客户端配置以消费WCF JSON Web服务

12

我已按照此博客描述的方式配置了Web服务以使用Json:http://www.west-wind.com/weblog/posts/164419.aspx以及其他不同的博客,但是我无法创建一个消费此服务的客户端。我尝试了各种方法,但总是得到无意义的异常。什么是实现(我应该补充WCF)客户端的正确方法?


1
服务是否在与客户端相同的域中运行?我遇到了一个问题,我的服务运行在与我的客户端不同的域上,无法让它们进行通信。后来我意识到,AJAX本身不允许跨域通信。 - DDiVita
2个回答

45

似乎缺乏关于如何编写WCF客户端以访问JSON REST服务的示例。大家似乎都使用WCF实施服务,但几乎从不用于编写客户端。因此,下面提供了一个相当完整的示例,包括服务(实现GET和POST请求)和客户端代码。

服务

服务接口

[ServiceContract]
public interface IService1
{
    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare,
        UriTemplate = "/getcar/{id}")]
    Car GetCar(string id);

    [OperationContract]
    [WebInvoke(RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare,
        UriTemplate = "/updatecar/{id}")]
    Car UpdateCar(string id, Car car);
}

服务数据结构

[DataContract]
public class Car
{
    [DataMember]
    public int ID { get; set; }

    [DataMember]
    public string Make { get; set; }
}

服务实现

public class Service1 : IService1
{
    public Car GetCar(string id)
    {
        return new Car { ID = int.Parse(id), Make = "Porsche" };
    }

    public Car UpdateCar(string f, Car car)
    {
        return car;
    }
}

服务标记

<%@ ServiceHost Language="C#" Service="JSONService.Service1"
    CodeBehind="Service1.svc.cs"
    Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

Web.config

:这是ASP.NET网站的配置文件,其中包含应用程序级别和服务器级别的设置。它允许您配置诸如数据库连接字符串、错误处理、安全性、会话状态等方面的设置。

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>   
</configuration>

客户端

现在是客户端的部分。它重用了接口IService1和类Car。除此之外,还需要以下代码和配置。

App.config

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webby">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <client>
      <endpoint address="http://localhost:57211/Service1.svc" name="Service1" binding="webHttpBinding" contract="JSONService.IService1" behaviorConfiguration="webby"/>
    </client>
  </system.serviceModel>
</configuration>

程序.cs

public class Service1Client : ClientBase<IService1>, IService1
{
    public Car GetCar(string id)
    {
        return base.Channel.GetCar(id);
    }


    public Car UpdateCar(string id, Car car)
    {
        return base.Channel.UpdateCar(id, car);
    }
}


class Program
{
    static void Main(string[] args)
    {
        Service1Client client = new Service1Client();
        Car car = client.GetCar("1");
        car.Make = "Ferrari";
        car = client.UpdateCar("1", car);
    }
}

玩得愉快。


1
客户端实现示例在互联网上非常罕见,这是非常真实的。它帮助我解决了我的问题。 - Hemant
我已经提出了另一个关于在WCF客户端中访问HTTP状态代码的问题。请您能否查看并给予一些指导?http://stackoverflow.com/q/4677052/23671 - Hemant
1
我很好奇。将REST服务隐藏在基于RPC的客户端代理后面的意义何在?为什么不直接使用SOAP?通过像这样在客户端上使用WCF,我认为您已经失去了REST可能带来的所有好处。 - Darrel Miller
1
这个例子只是我在编写一个使用主要基于JSON(用Java实现)的WFC客户端来访问一个已存在的REST服务时的一些实验的副产品。那个服务看起来非常不同,几乎完全只读。而且它已经证明非常适合它的目的:以所选择的详细程度、紧凑格式和单次请求提供数据。客户端是带有有限带宽并且往返时间长的移动电话。幸运的是,该服务不是SOAP(过于复杂,太啰嗦)。而且RPC风格的代理只是容易使用... - Codo
4
你是否意识到这并不是REST呢?虽然在HTTP上进行RPC可能会很有价值,但它不会实现REST架构所带来的好处。 - Darrel Miller
@DarrelMiller 也许是这样,但你所说的模型并不总是有用;在很多情况下,RPC-HTTP 更可取。 - Mr. TA

-1

什么是异常?它们对你来说可能毫无意义,但在这里的某个人可能会发现它们有助于诊断你的问题。我使用jQuery向WCF服务发出ajax请求,设置通常如下:

     $(document).ready(function() {

        $.ajaxSetup({
            type: "POST",
            processData: true,
            contentType: "application/json",
            timeout: 5000,
            dataType: "json"
        });
        var data = { "value": 5 };

        AjaxPost("GetData", data, OnEndGetData, OnError);
    });

    function OnEndGetData(result) {
        alert(result.GetDataResult);
    }

    function OnError(msg) {
        alert(msg);
    }

function AjaxPost(method, data, callback, error) {
    var stringData = JSON.stringify(data);
    var url = "Service1.svc/" + method;

    $.ajax({
        url: url,
        data: stringData,
        success: function(msg) {
            callback(msg);
        },
        error: error
    });
}

JSON.stringify() 可在 json.org 脚本中找到:http://www.json.org/js.html,而我的 GetData 方法的签名如下:

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat =   WebMessageFormat.Json)]
string GetData(int value);

1
嗨,也许我没有表达清楚,但我真的在尝试在C#的Winform应用程序中实现一个WCF客户端,而不是Web客户端。 - Grzenio
同时,我在 $.ajax({ 这一行遇到了一个错误:$ 未定义。 - Grzenio
1
我不确定你能否在不使用普通的WebClient或HttpRequest/Response设置的情况下实现JSON客户端。$是jQuery的一部分。 - Mike_G
这个答案与创建/配置WCF客户端有什么关系? - bytedev
@nashwan 这个问题没有指定是哪种类型的WCF客户端。我使用jQuery和JS创建了一个客户端。 - Mike_G
@Mike_G,你描述的是JavaScript AJAX客户端而不是WCF客户端。(WCF不是服务器端的名称...服务器端有WCF服务和客户端有WCF客户端。你也可以使用其他类型的客户端消费WCF服务,但这不是问题所在)。 - bytedev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接