我需要传递一个连接的字符串作为web api Url

问题描述:

我正在开发Xamarin中的PCL项目。我需要在Web api Url中动态地传递设备的IP地址。 我的代码是如下:我需要传递一个连接的字符串作为web api Url

在后面的代码:

string IpAdd = txtIP.Text; 

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

MainViewModel.FinalIPAddress = IPAddress; 

在我MainViewModel

public static string FinalIPAddress { get; set; } 

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

但我无法通过这个来获得。下面的异常被抛出。

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. 

该怎么办?任何帮助将不胜感激。

+0

什么具体的行抛出异常,以及什么具体的参数,你传递一个原因呢?你为什么使用URLEncoding IP地址? – Jason

+0

public static readonly string WebServiceUrl = System.Net.WebUtility.UrlEncode(FinalIPAddress); - 这正是抛出这个异常的线。我将后面的代码中的变量“FinalIPAddress”传递给我的视图模型。“FinalIPAddress”是包含用户输入的IPAddress的共享字符串。 – user1508599

+0

当这个类被实例化时,WebServiceUrl将会为null。为什么不在FinalIPAddress属性中设置值? –

我在想你的模型实现中的WebServiceUrl看起来很奇怪。模型应该很薄。在您试图使用WebServiceUrl并将其从模型中完全移除的时候,为什么不在模型的FinalIPAddress上调用UrlEncode?

无论如何,当创建模型时,它可能没有FinalIPAddress的值,除非你指定它,所以它是空白的,你会得到我在想的异常。如果你想这样做,为什么不把它变成一个静态字符串函数而不是一个返回UrlEncode(FinalIPAddress)结果的变量。然后,当你调用它时,可能在你填充了FinalIPAddress之后,它会被实时创建,并且你有相同的结果。

此外,传统上在api中,您应该本地访问客户端的IP地址,该请求来自请求本身和用户代理。这可能是一个更精简的方法来考虑。

编辑:按照要求,最小的代码改变,这将做到这一点会被去除

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

,并用静态方法代替你可以调用

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

然后使用类似的方法调用你可以使用任何模型变量MainViewModel.WebServiceUrl(),并将它视为一个字符串。

有许多方法可以完成你想要做的事情,有些可以说是更好的做法。值得一读,但现在这个小小的改变会让你的代码发挥作用。

+0

你可以在代码中告诉我如何去与你的建议@Nard狗? – user1508599

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

也求这里

private void MakeRequest(string url) 
{ 

} 

输出

在这里你可以看到,一旦你设定的Model.BaseAddress你将有正确的 “FinalIPAdress” 你要找的。

Example running program url after setting baseaddress from input

公共静态只读字符串WebServiceUrl

去掉 '只读',这应该在你的情况下工作。

+0

当您尝试访问它时,WebServiceUrl不会为null吗? WebServiceUrl是一个实例变量,因此它不会根据模型更新值。 –