2017-04-11 3 views
0

私はXamarinでPCLプロジェクトを開発しています。ウェブAPIのURLにデバイスのIPアドレスを動的に渡す必要があります。私MainViewModelWeb api URLとして連結された文字列を渡す必要があります

public static string FinalIPAddress { get; set; } 

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

string IpAdd = txtIP.Text; 

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

MainViewModel.FinalIPAddress = IPAddress; 

しかし、私はこれを介して取得することができません:背後にあるコードで

: マイコードは以下の通りです。以下の例外がスローされます。

どのようにこれを行えばよいですか?どんな助けもありがとう。

+0

どの特定の行が例外をスローしていますか、それを引き起こす特定の引数は何ですか?なぜあなたはIPアドレスをURLエンコードしていますか? – Jason

+0

public static readonly string WebServiceUrl = System.Net.WebUtility.UrlEncode(最終IPアドレス);これは、この例外をスローする行です。変数 "FinalIPAddress"をコードの背後にあるビューモデルに渡しています。 "FinalIPAddress"は、ユーザーが入力したIPAddressを含むconacatenated文字列です。 – user1508599

+0

このクラスがインスタンス化されると、WebServiceUrlはnullになります。なぜFinalIPAddressプロパティの値を設定しないのですか? –

答えて

0

モデルの実装であなたのWebServiceUrlが奇妙に思えます。モデルは薄いはずです。 WebServiceUrlを使用しようとしている時点で、モデルのFinalIPAddressでUrlEncodeを呼び出してモデルから完全に削除するのはなぜですか?

モデルが作成されても、割り当てられるまでFinalIPAddressの値がない可能性があります。そのため、空白で、私が考えている例外が発生します。このアプローチをしたいのであれば、UrlEncode(FinalIPAddress)の結果を返す変数ではなく、静的な文字列関数にしてみてください。 FinalIPAddressを実装した後に呼び出すと、リアルタイムで作成され、同じ結果が得られます。

また、伝統的にAPIでは、要求自体とユーザーエージェントから要求を出しているクライアントのIPアドレスにネイティブにアクセスする必要があります。これは考慮すべき、より希薄なアプローチかもしれません。

編集:要求されたとして、これを実現するだろう最小のコードの変更は、その後のようなメソッド呼び出しを使用し

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

を呼び出すことができます

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

を削除し、静的メソッドに置き換えられます任意のモデル変数MainViewModel.WebServiceUrl()を呼び出すだけで、文字列のように扱うことができます。

あなたがしようとしていることを達成する方法はたくさんありますが、間違いなくもっと良い方法があります。上に読む価値はありますが、今のところこの小さな変更がコードを機能させるでしょう。

+0

私はあなたに@ナードッグの提案と一緒に行く方法をコードで私に示すことができますか? – user1508599

+0

私は単純なコードスニペットで編集しました。 –

0

次のコードは、あなたの問題を解決します。通常、APIを指しているだけでは基本アドレスの変更はありませんが、最終目標が何であるか分かりません。

モデル

あなたはハードだけのユーザー入力からのベースアドレスを設定する必要がありスキームとパスをコーディングに計画しているので。

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; 
     } 
    } 
} 

実装

私はここで、送信ボタンを使用してテスト項目を作成しました。

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; 
} 

ボタンイベント

あなたが実際にここにあなたのモデルをインスタンス化する必要はありません。私はただの例では、何のためにそれを必要としません。

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"); 
    } 
    } 

あなたがModel.BaseAddressを設定したら、あなたが探している正しい "FinalIPAdress" を持つことになります見ることができるここで要求

private void MakeRequest(string url) 
{ 

} 

出力ここ

ください。

Example running program url after setting baseaddress from input

0

パブリック静的読み取り専用の文字列WebServiceUrl

あなたのケースで動作するはずである、 '読み取り専用' を削除します。

+0

アクセスしようとするとWebServiceUrlがnullにならないでしょうか? WebServiceUrlはインスタンス変数なので、モデルに基づいて値を更新することはありません。 –

関連する問題