2017-04-11 2 views
0

Ich entwickle ein PCL-Projekt in Xamarin .Ich muss die IP-Adresse des Geräts dynamisch in der Web-API Url übergeben. My-Code ist wie folgt:Ich muss eine verkettete Zeichenfolge als Web-API übergeben Url

Im Code hinter:

string IpAdd = txtIP.Text; 

IPAddress = "http://" + IpAdd + ":8124/api/Items/"; 

MainViewModel.FinalIPAddress = IPAddress; 

In meinem MainViewModel

public static string FinalIPAddress { get; set; } 

public static readonly string WebServiceUrl = System.Net.WebUtility.UrlEncode(FinalIPAddress); 

Aber ich bin nicht in der Lage, durch diese zu erhalten. Die folgende Ausnahme wird ausgelöst.

Exception thrown: 'System.InvalidOperationException' in System.Net.Http.Phone.ni.DLL 
Additional information: An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set. 

Wie geht man damit um? Jede Hilfe wird geschätzt.

+0

Welche spezifische Zeile wirft die Ausnahme, und welches spezifische Argument übergeben Sie, dass es verursacht? Warum URLEncoding eine IP-Adresse? – Jason

+0

public static readonly Zeichenfolge WebServiceUrl = System.Net.WebUtility.UrlEncode (FinalIPAddress); - Dies ist die Zeile, die genau diese Ausnahme auslöst. Und ich übergebe die Variable "FinalIPAddress" aus dem Code dahinter an mein View-Modell. "FinalIPAddress" ist die conacatenated-Zeichenfolge, die die IPAddress enthält, die der Benutzer eingibt. – user1508599

+0

WebServiceUrl wird null sein, wenn diese Klasse instanziiert wird. Warum nicht den Wert in der FinalIPAddress-Eigenschaft festlegen? –

Antwort

0

Ich denke, Ihre WebServiceUrl in der Modellimplementierung sieht seltsam aus. Modelle sollten dünn sein. Warum rufen Sie nicht den UrlEncode auf der FinalIPAddress des Modells zu dem Zeitpunkt auf, an dem Sie versuchen, die WebServiceUrl zu verwenden und diese vollständig aus dem Modell zu entfernen?

Unabhängig davon, wenn das Modell erstellt wird, hat es wahrscheinlich keinen Wert für FinalIPAddress, bis Sie es zuweisen, also ist es leer und Sie erhalten die Ausnahme, die ich denke. Wenn Sie diesen Ansatz ausführen möchten, warum nicht eine statische String-Funktion anstelle einer Variablen, die das Ergebnis von UrlEncode (FinalIPAddress) zurückgibt. Dann, wenn Sie es aufrufen, wird wahrscheinlich, nachdem Sie FinalIPAddress ausgefüllt haben, in Echtzeit erstellt und Sie haben das gleiche Ergebnis.

Auch traditionell in einer API sollten Sie nativen Zugriff auf die IP-Adresse des Clients haben, der die Anfrage von der Anfrage selbst und dem Benutzer-Agent durchführt. Das mag ein schlankerer Ansatz sein, den es zu berücksichtigen gilt.

Edit: Wie gewünscht, die kleinste Codeänderung, die dies die mit einer statischen Methode würde erreichen würde das Entfernen

public static readonly string WebServiceUrl = System.Net.WebUtility.UrlEncode(FinalIPAddress); 

und ersetzen Sie

public static string WebServiceUrl() 
{ 
    return System.Net.WebUtility.UrlEncode(FinalIPAddress); 
} 

Dann nutzen Sie den Methodenaufruf nennen könnte, wie Sie würden jede Modellvariable, MainViewModel.WebServiceUrl(), und behandeln Sie es einfach wie eine Zeichenfolge.

Es gibt viele Möglichkeiten zu erreichen, was Sie versuchen zu tun, und einige sind wohl viel bessere Praxis. Es lohnt sich, darüber zu lesen, aber vorerst würde diese kleine Änderung Ihren Code funktionsfähig machen.

+0

können Sie mir im Code zeigen, wie Sie mit Ihrem Vorschlag @Nard Dog? – user1508599

+0

Ich habe mit einem einfachen Code-Snippet bearbeitet. –

0

Der folgende Code löst Ihr Problem. Normalerweise würden Sie die Basisadresse nicht ändern, wenn Sie nur auf Ihre API zeigen, aber ich bin mir nicht sicher, was das Endziel hier ist.

Modell

Da Sie hart auf die Codierung der Regelung und der Pfad müssen Sie nur einstellen, die Basisadresse von dem Benutzer Eingang planen.

public class Model 
{ 
    public string BaseAddress { get; set; } 
    public string Scheme { get { return "http://"; } } 
    public string Path { get { return ":8124/api/Items"; } } 

    public string WebServiceURL { 
     get { 
      return Scheme + BaseAddress + Path; 
     } 
    } 
} 

Implementierung

habe ich einen Test Eintrag mit einer hier Absenden-Button.

private Entry _urlEntry = new Entry { Placeholder = "url" }; 
private Button _submit = new Button { Text = "Submit" }; 
private Model _model; 

public BackPage() 
{ 
    Content = new StackLayout 
    { 
     Children = { _urlEntry, _submit } 
    }; 
     _submit.Clicked += Submit_Clicked; 
} 

Knopf Ereignis

Du musst ich es nicht tatsächlich instanziiert Ihr Modell hier einfach nicht für irgendetwas anderes im Beispiel benötigen.

private void Submit_Clicked(object sender, System.EventArgs e) 
{ 
    var text = _urlEntry?.Text; 

    if(text.Length > 0) 
    { 
     _model = new Model { BaseAddress = text }; 
     MakeRequest(_model.WebServiceURL); 
    } 
    else 
    { 
     DisplayAlert("Error", "Entry field is empty", "ok"); 
    } 
    } 

Make Anfrage Hier

private void MakeRequest(string url) 
{ 

} 

Ausgabe

Hier können Sie sehen, wenn Sie die Model.BaseAddress eingestellt werden Sie die richtige "FinalIPAdress" haben Sie suchen .

Example running program url after setting baseaddress from input

0

public static schreibgeschützte String WebServiceURL

entfernen Sie den 'Read-only', die in Ihrem Fall funktionieren sollte.

+0

Wäre WebServiceUrl nicht null, wenn Sie versuchen und darauf zugreifen? WebServiceUrl ist eine Instanzvariable, daher wird der Wert nicht basierend auf dem Modell aktualisiert. –

Verwandte Themen