用于 Xamarin 表单的 Rest + WCF 集成

Posted

技术标签:

【中文标题】用于 Xamarin 表单的 Rest + WCF 集成【英文标题】:Rest + WCF Integration for Xamarin Forms 【发布时间】:2015-11-28 17:31:20 【问题描述】:

我正在做一个需要连接到 WCF 服务的 Xamarin Forms 项目。我必须使用 Rest 来访问它,所以我选择使用与 PCL 兼容的 RestSharp 构建。我已经完成了许多基于 SOAP 的 Web 服务,但这是我第一次深入研究 Rest,我觉得我缺少一些非常基本的东西。当我进行 SOAP 调用时,我已经确认我的 Web 服务正常运行,所以我认为我的设置有误。

这是我的网络服务的示例代码:

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());
        );            
    

当我进行上面的调用时,我没有得到任何异常,只是一个空字符串返回值。同样的事情发生在浏览器中。我怀疑我的服务定义。我有几个问题可能有点基础,但我希望将来也能帮助其他 WCF/Rest 初学者。

1. 我的服务定义中的 UriTemplate 有什么问题(如果有的话)?合适的 UriTemplate 应该是什么样的?

2.对于这种服务调用,我应该使用 PUT 方法,还是 GET 或 POST 更合适?

3.我的网络服务定义中是否还有其他明显缺失的内容?

4.我将完整的服务 uri (http://www.example.com/service.svc/) 传递给 Rest 客户端是否正确?

5. 对 Rest 初学者有何其他建议,特别是与 WCF-Rest 组合有关的建议?

【问题讨论】:

【参考方案1】:
    如果您使用 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 的图书。

    在 Microsoft 世界中,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 测试客户端”: 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 和服务实现?

【讨论】:

这非常有帮助,也是迄今为止我看到的关于这个主题的最佳解释。非常感谢!我也会研究 WebAPI。我从事桌面和服务器软件已有十多年了,但 Web/Mobile 对我来说是一个新世界。你在这里的回答给了我那些我错过的东西! 很高兴为您提供帮助。您遇到的问题/解决方案是什么? 我实际上切换到了纯 JSON 方法,即 ServiceStack 只是因为这个项目的时间限制 - 我必须在你的答案到来之前拨打电话。基本问题是我对 WCF 和 Rest 的理解不够好,无法做出合理的实现。 @smoksnes,我正在尝试通过 wcf 休息一下,但我没有。该服务是 POST 并由其他公司开发。我需要发送两个参数 json("iduser:1","idindicador:2"),然后我收到这样的 json 响应("real:235.00","projetado:250.00")。如何将 json 文件作为参数发送?

以上是关于用于 Xamarin 表单的 Rest + WCF 集成的主要内容,如果未能解决你的问题,请参考以下文章

wcf rest 服务用于安卓和ISO调用1

ASP.Net Web API 与 WCF - Web API 能否用于向单例 WCF 服务提供基于 REST 的通信?

wcf rest 服务用于安卓和ISO调用5-------验证

wcf rest 服务用于安卓和ISO调用2-------文件上传

尝试发布到 wcf rest 4 服务时出现错误请求

Xamarin 表单:用于静态内容的 CarouselView