Xamarin Forms 的 Rest + WCF 集成
Rest + WCF Integration for Xamarin Forms
我正在做一个需要连接到 WCF 服务的 Xamarin Forms 项目。我必须使用 Rest 来访问它,所以我选择使用兼容 PCL 的 RestSharp 版本。我已经完成了许多基于 SOAP 的 Web 服务,但这是我第一次深入研究 Rest,我觉得我缺少一些非常基本的东西。我已确认我的 Web 服务在我进行 SOAP 调用时正常运行,因此我认为我的设置有误。
这是我的网络服务的示例代码:
Imports System.IO
Imports System.Net
Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports System.ServiceModel.Web
<ServiceContract()>
Public Interface Iapi
<WebInvoke(Method:="PUT",
UriTemplate:="Login/Email/{Email}/Password/{Password}",
RequestFormat:=WebMessageFormat.Json,
ResponseFormat:=WebMessageFormat.Json)>
<OperationContract(AsyncPattern:=True)>
Function Login(email As String, password As String) As String
End Interface
这是我尝试调用该服务的示例代码:
public void Login(string email, string password)
{
RestClient client = new RestClient("http://www.example.com/service.svc/");
RestRequest request = new RestRequest
{
Method = Method.PUT,
Resource = "Login/Email/{Email}/Password/{Password}",
RequestFormat = DataFormat.Json
};
request.AddParameter("Email", email, ParameterType.UrlSegment);
request.AddParameter("Password", password,ParameterType.UrlSegment);
client.ExecuteAsync(request, response => {
session = response.Content;
ActionCompleted(this, new System.EventArgs());
});
}
当我进行上述调用时,没有出现任何异常,只有一个空字符串 return 值。同样的事情发生在浏览器中。我怀疑我的服务定义。我有几个问题可能有点基础,但我希望将来也能帮助其他 WCF/Rest 初学者。
1. 我的服务定义中的 UriTemplate 有什么问题(如果有的话)?一个合适的 UriTemplate 应该是什么样的?
2.这种服务调用应该使用PUT方法,还是GET或POST更合适?
3. 我的 Web 服务定义中是否明显遗漏了其他任何内容?
4. 我将完整的服务 uri (http://www.example.com/service.svc/) 传递给 Rest 客户端是否正确?
5. 对 Rest 初学者还有什么建议,特别是与 WCF-Rest 组合有关的建议吗?
- 如果您使用的是 GET,则正确的 URI 模板可能如下所示:
C#
[OperationContract]
[WebGet(UriTemplate = "Book/{id}")]
Book GetBookById(string id);
VB:
<OperationContract()> _
<WebGet(UriTemplate:="Book/{id}")> _
Function GetBookById(ByVal id As String) As Book
然后您可以使用 http://example.com/Book/1 调用 ID==1 的书。
- 在微软世界中,PUT 通常用于创建或更新数据,例如新任务、订单等。但是,即使我个人认为 POST 或 GET,您也可以使用它进行登录将是更准确的方法。但这只是我的意见。
查看此问题了解更多信息:
PUT vs POST in REST
您的声明中似乎没有遗漏任何内容。
如果您无法使用浏览器访问它,可能不是 RestSharp 的使用有问题。但是,这里有一些注意事项。使用异步方法时,您通常会想尝试使用 .NET 的 async/await-pattern。然后请求不锁定主线程。
示例:
http://www.dosomethinghere.com/2014/08/23/vb-net-simpler-async-await-example/
这是我在 Xamarin 项目中用于调用服务的一小段代码:
protected static async Task<T> ExecuteRequestAsync<T>(string resource,
HttpMethod method,
object body = null,
IEnumerable<Parameter> parameters = null) where T : new()
{
var client = new RestClient("http://example.com/rest/service.svc/");
var req = new RestRequest(resource, method);
AddRequestKeys(req);
if (body != null)
req.AddBody(body);
if (parameters != null)
{
foreach (var p in parameters)
{
req.AddParameter(p);
}
}
Func<Task<T>> result = async () =>
{
var response = await client.Execute<T>(req);
if (response.StatusCode == HttpStatusCode.Unauthorized)
throw new Exception(response.Data.ToString());
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception("Error");
return response.Data;
};
return await result();
}
是的,没错。
您如何托管 WCF?如果使用 IIS,您的 web.config 是什么样的?这是一个例子:
附带说明一下,我注意到您提到您需要访问 WCF 服务。您是否考虑过改用 .NET Web API?它提供了一种更直接的方法来创建 RESTful 端点,无需配置。它的实现和使用更简单,但是它不提供与 WCF 服务相同的灵活性。
为了调试 WCF 服务,我强烈推荐 "WCF Test client":
https://msdn.microsoft.com/en-us/library/bb552364(v=vs.110).aspx
Where can I find WcfTestClient.exe (part of Visual Studio)
在 web.config 中启用元数据后,您将能够看到所有可用的方法。下面的示例配置:
<configuration>
<system.serviceModel>
<services>
<service name="Metadata.Example.SimpleService">
<endpoint address=""
binding="basicHttpBinding"
contract="Metadata.Example.ISimpleService" />
</service>
</services>
<behaviors>
</behaviors>
</system.serviceModel>
</configuration>
来源:
https://msdn.microsoft.com/en-us/library/ms734765(v=vs.110).aspx
如果没有帮助,您能否提供您的 web.config 和您的服务实施情况?
我正在做一个需要连接到 WCF 服务的 Xamarin Forms 项目。我必须使用 Rest 来访问它,所以我选择使用兼容 PCL 的 RestSharp 版本。我已经完成了许多基于 SOAP 的 Web 服务,但这是我第一次深入研究 Rest,我觉得我缺少一些非常基本的东西。我已确认我的 Web 服务在我进行 SOAP 调用时正常运行,因此我认为我的设置有误。
这是我的网络服务的示例代码:
Imports System.IO
Imports System.Net
Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports System.ServiceModel.Web
<ServiceContract()>
Public Interface Iapi
<WebInvoke(Method:="PUT",
UriTemplate:="Login/Email/{Email}/Password/{Password}",
RequestFormat:=WebMessageFormat.Json,
ResponseFormat:=WebMessageFormat.Json)>
<OperationContract(AsyncPattern:=True)>
Function Login(email As String, password As String) As String
End Interface
这是我尝试调用该服务的示例代码:
public void Login(string email, string password)
{
RestClient client = new RestClient("http://www.example.com/service.svc/");
RestRequest request = new RestRequest
{
Method = Method.PUT,
Resource = "Login/Email/{Email}/Password/{Password}",
RequestFormat = DataFormat.Json
};
request.AddParameter("Email", email, ParameterType.UrlSegment);
request.AddParameter("Password", password,ParameterType.UrlSegment);
client.ExecuteAsync(request, response => {
session = response.Content;
ActionCompleted(this, new System.EventArgs());
});
}
当我进行上述调用时,没有出现任何异常,只有一个空字符串 return 值。同样的事情发生在浏览器中。我怀疑我的服务定义。我有几个问题可能有点基础,但我希望将来也能帮助其他 WCF/Rest 初学者。
1. 我的服务定义中的 UriTemplate 有什么问题(如果有的话)?一个合适的 UriTemplate 应该是什么样的?
2.这种服务调用应该使用PUT方法,还是GET或POST更合适?
3. 我的 Web 服务定义中是否明显遗漏了其他任何内容?
4. 我将完整的服务 uri (http://www.example.com/service.svc/) 传递给 Rest 客户端是否正确?
5. 对 Rest 初学者还有什么建议,特别是与 WCF-Rest 组合有关的建议吗?
- 如果您使用的是 GET,则正确的 URI 模板可能如下所示:
C#
[OperationContract]
[WebGet(UriTemplate = "Book/{id}")]
Book GetBookById(string id);
VB:
<OperationContract()> _
<WebGet(UriTemplate:="Book/{id}")> _
Function GetBookById(ByVal id As String) As Book
然后您可以使用 http://example.com/Book/1 调用 ID==1 的书。
- 在微软世界中,PUT 通常用于创建或更新数据,例如新任务、订单等。但是,即使我个人认为 POST 或 GET,您也可以使用它进行登录将是更准确的方法。但这只是我的意见。
查看此问题了解更多信息: PUT vs POST in REST
您的声明中似乎没有遗漏任何内容。
如果您无法使用浏览器访问它,可能不是 RestSharp 的使用有问题。但是,这里有一些注意事项。使用异步方法时,您通常会想尝试使用 .NET 的 async/await-pattern。然后请求不锁定主线程。
示例: http://www.dosomethinghere.com/2014/08/23/vb-net-simpler-async-await-example/
这是我在 Xamarin 项目中用于调用服务的一小段代码:
protected static async Task<T> ExecuteRequestAsync<T>(string resource,
HttpMethod method,
object body = null,
IEnumerable<Parameter> parameters = null) where T : new()
{
var client = new RestClient("http://example.com/rest/service.svc/");
var req = new RestRequest(resource, method);
AddRequestKeys(req);
if (body != null)
req.AddBody(body);
if (parameters != null)
{
foreach (var p in parameters)
{
req.AddParameter(p);
}
}
Func<Task<T>> result = async () =>
{
var response = await client.Execute<T>(req);
if (response.StatusCode == HttpStatusCode.Unauthorized)
throw new Exception(response.Data.ToString());
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception("Error");
return response.Data;
};
return await result();
}
是的,没错。
您如何托管 WCF?如果使用 IIS,您的 web.config 是什么样的?这是一个例子:
附带说明一下,我注意到您提到您需要访问 WCF 服务。您是否考虑过改用 .NET Web API?它提供了一种更直接的方法来创建 RESTful 端点,无需配置。它的实现和使用更简单,但是它不提供与 WCF 服务相同的灵活性。
为了调试 WCF 服务,我强烈推荐 "WCF Test client": https://msdn.microsoft.com/en-us/library/bb552364(v=vs.110).aspx
Where can I find WcfTestClient.exe (part of Visual Studio)
在 web.config 中启用元数据后,您将能够看到所有可用的方法。下面的示例配置:
<configuration>
<system.serviceModel>
<services>
<service name="Metadata.Example.SimpleService">
<endpoint address=""
binding="basicHttpBinding"
contract="Metadata.Example.ISimpleService" />
</service>
</services>
<behaviors>
</behaviors>
</system.serviceModel>
</configuration>
来源: https://msdn.microsoft.com/en-us/library/ms734765(v=vs.110).aspx
如果没有帮助,您能否提供您的 web.config 和您的服务实施情况?