简体   繁体   English

Xamarin表单的Rest + WCF集成

[英]Rest + WCF Integration for Xamarin Forms

I am doing a Xamarin Forms project that requires connection to a WCF service. 我正在做一个Xamarin Forms项目,该项目需要连接到WCF服务。 I must use Rest to access it, so I opted to use a PCL-compatible build of RestSharp. 我必须使用Rest来访问它,因此我选择使用PCL兼容的RestSharp版本。 I have done many SOAP based web services, but this is my first dive into Rest, and I feel like I am missing something very basic. 我已经完成了许多基于SOAP的Web服务,但这是我第一次深入研究Rest,感觉好像缺少了一些非常基本的东西。 I have confirmed that my web service functions correctly when I make SOAP calls, so I believe I have set something up incorrectly. 我已经确认在进行SOAP调用时我的Web服务可以正常运行,因此我认为我设置不正确。

Here is sample code for my web service: 这是我的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

Here is sample code for my attempt to call the service: 这是我尝试调用该服务的示例代码:

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

When I make the call above, I get no exceptions, just an empty string return value. 当我在上面进行调用时,没有异常,只有空字符串返回值。 The same thing happens in the browser. 在浏览器中也会发生同样的事情。 I suspect my service definition. 我怀疑我的服务定义。 I have several questions that are probably a bit basic, but I hope will also help other WCF/Rest beginners in the future. 我有一些可能有点基本的问题,但希望将来对其他WCF / Rest初学者有所帮助。

1. What, if anything, is wrong with my UriTemplate in the definition of my service? 1.服务定义中的UriTemplate有什么问题(如果有的话)? What would a proper UriTemplate look like? 适当的UriTemplate会是什么样?

2. Should I be using the PUT method for this kind of service call, or is GET or POST more appropriate? 2.我应该对这种服务调用使用PUT方法,还是更合适使用GET或POST?

3. Is anything else obviously missing from my web service definition? 3.我的Web服务定义中显然还有其他地方吗?

4. Am I correct in passing the full service uri ( http://www.example.com/service.svc/ ) to the Rest client? 4.将完整服务uri( http://www.example.com/service.svc/ )传递给Rest客户端是否正确?

5. Any additional suggestions for a Rest beginner, specifically in relation to the WCF-Rest combination? 5.对于Rest初学者,还有关于WCF-Rest组合的其他建议吗?

  1. A proper URI-template could look something like this if you're using a GET: 如果您使用的是GET,则正确的URI模板可能看起来像这样:

C# C#

[OperationContract]
[WebGet(UriTemplate  = "Book/{id}")]
Book GetBookById(string id);

VB: VB:

<OperationContract()> _ 
<WebGet(UriTemplate:="Book/{id}")> _ 
Function GetBookById(ByVal id As String) As Book

Then you can call it using http://example.com/Book/1 for the book with ID==1. 然后,您可以使用http://example.com/Book/1为ID == 1的图书进行调用。

  1. In the Microsoft-world PUT is often used for creating or updating data, such as a new task, order etc. However, you CAN use it for login even if I personally think a POST or GET would be the more accurate approach. 在Microsoft世界中,PUT通常用于创建或更新数据,例如新任务,订单等。但是,即使我个人认为POST或GET是更准确的方法,也可以将其用于登录。 But that's just my oppinion. 但这只是我的观点。

See this question for more information: PUT vs POST in REST 有关更多信息,请参见此问题: REST中的PUT与POST

  1. There's nothing that seems to be missing in you declaration. 您的声明中似乎没有什么缺失。

  2. If you cannot reach it with a browser, it's probably not the usage of RestSharp that's wrong. 如果您无法通过浏览器访问它,那可能不是RestSharp的用法错误。 However, here's some notes. 但是,这里有一些注意事项。 When using async methods you will often want to try using .NET's async/await-pattern. 使用异步方法时,您通常会想尝试使用.NET的async / await-pattern。 Then the request doesn't lock the main thread. 然后,该请求不会锁定主线程。

Example: http://www.dosomethinghere.com/2014/08/23/vb-net-simpler-async-await-example/ 范例: http//www.dosomethinghere.com/2014/08/23/vb-net-simpler-async-await-example/

Here's a little piece of code that I use in my Xamarin-projects for invoking services: 这是我在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();
}
  1. Yes, that's correct. 对,那是正确的。

  2. How do you host your WCF? 您如何托管WCF? If using IIS, what does your web.config look like? 如果使用IIS,您的web.config是什么样的? Here's an example: 这是一个例子:

As a side note, I noticed you mentioned that you require access to a WCF-service. 作为附带说明,我注意到您提到您需要访问WCF服务。 Have you considered using .NET Web API instead? 您是否考虑过改用.NET Web API? It provides a more straight-forward approach for creating RESTful endpoints, without the need for configs. 它为创建RESTful端点提供了更简单的方法,而无需进行配置。 It's more simple to implement and to use, however it does not provide the same flexibility as a WCF-service does. 它的实现和使用更简单,但是它没有提供与WCF服务相同的灵活性。

For debugging a WCF-service I strongly recommend "WCF Test client": https://msdn.microsoft.com/en-us/library/bb552364(v=vs.110).aspx 为了调试WCF服务,我强烈建议您使用“ WCF测试客户端”: https : //msdn.microsoft.com/zh-cn/library/bb552364(v=vs.110).aspx

Where can I find WcfTestClient.exe (part of Visual Studio) 在哪里可以找到WcfTestClient.exe(Visual Studio的一部分)

With metadata-enabled in your web.config, you will be able to see all available methods. 在web.config中启用了元数据后,您将能够看到所有可用的方法。 Example-configuration below: 示例配置如下:

<configuration>
  <system.serviceModel>
    <services>
      <service name="Metadata.Example.SimpleService">
        <endpoint address=""
                  binding="basicHttpBinding"
                  contract="Metadata.Example.ISimpleService" />
      </service>
    </services>
    <behaviors>

    </behaviors>
  </system.serviceModel>
</configuration>

Source: https://msdn.microsoft.com/en-us/library/ms734765(v=vs.110).aspx 来源: https : //msdn.microsoft.com/en-us/library/ms734765(v=vs.110).aspx

If it doesn't help, could you provide your web.config and implementation of your service as well? 如果没有帮助,您是否还可以提供web.config和服务实现?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM