简体   繁体   English

如何将DataContract对象作为WCF RESTFUL Web服务的参数发送?

[英]How can I send a DataContract object as parameter for a WCF RESTFUL webservice?

I am developing a WCF resful service which will be basically consumed from some mobile applications. 我正在开发一个WCF resful服务,它将基本上从一些移动应用程序中消耗。 Over the POST I am trying to send a DataContract object [actually I have to send a List of object] and another single id as string. 在POST上我试图发送一个DataContract对象[实际上我必须发送一个对象列表]和另一个单独的id作为字符串。 My question is if it is possibly to define my function to accept DataContract object and the single string ? 我的问题是,是否可能定义我的函数来接受DataContract对象和单个字符串?

Following is my code : Interface declaration: 以下是我的代码:接口声明:

[ServiceContract]
    public interface IService1
    {

        [OperationContract]
        [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetDataUsingDataContract/{id}")]
        CompositeType GetDataUsingDataContract(string id, CompositeType composite );


    }

    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }

Actual definition of the function: 功能的实际定义:

public CompositeType GetDataUsingDataContract(string id, CompositeType composite )
        {

            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite .BoolValue)
            {
                composite .StringValue += "- Suffix and the id is"+id;
            }
            return report;
        }

and the json object I am trying to send from Fiddler is 我试图从Fiddler发送的json对象是

{"BoolValue":true,"StringValue":"sdfsdfsf"}

Fiddler在发送请求时捕捉提琴手快速输出 Above are the snaps from the fiddler I am testing the service from. 以上是我正在测试服务的小提琴手的快照。 After couple of googling I have got the following link where the client actually uses webservice reference to get the DataContract type and serializes to json before sending as request body. 经过几次谷歌搜索后,我得到了以下链接,其中客户端实际使用webservice引用获取DataContract类型并序列化为json,然后作为请求体发送。 But why then my test from Fiddler doesn't succeed ?! 但是为什么我对Fiddler的测试没有成功? http://dotnetmentors.com/wcf/wcf-rest-service-to-get-or-post-json-data-and-retrieve-json-data-with-datacontract.aspx http://dotnetmentors.com/wcf/wcf-rest-service-to-get-or-post-json-data-and-retrieve-json-data-with-datacontract.aspx

Can anybody please suggest anything ? 任何人都可以建议吗?

The web.config is as bellow: web.config如下:

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="JSONWebService.Service1" behaviorConfiguration="JSONWebService.Service1Behavior">
        <endpoint address="../Service1.svc"
            binding="webHttpBinding"
            contract="JSONWebService.IService1"
            behaviorConfiguration="webBehaviour" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="JSONWebService.Service1Behavior">

          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webBehaviour">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

There's a couple of things you need to do to get this scenario to work. 要使此方案起作用,您需要做几件事。

First, in the service contract, you need to mark the method that has multiple parameters with the BodyStyle parameter of the WebInvoke attribute set to Wrapped as shown in this example (adapted from the sample you linked to at http://dotnetmentors.com/wcf/wcf-rest-service-to-get-or-post-json-data-and-retrieve-json-data-with-datacontract.aspx ): 首先,在服务合同中,您需要将具有多个参数的方法标记为WebInvoke属性的BodyStyle参数设置为Wrapped ,如此示例所示(根据您在http://dotnetmentors.com/链接的示例改编) wcf / wcf-rest-service-to-get-or-post-json-data-and-retrieve-json-data-with-datacontract.aspx ):

[OperationContract]
[WebInvoke(UriTemplate = "/PlaceOrder",
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json, Method = "POST",
    BodyStyle = WebMessageBodyStyle.Wrapped)]
bool PlaceOrder(string id, OrderContract order);

With this attribute parameter in place you have to wrap the multiple web method parameters into a single string in your client. 使用此属性参数,您必须将多个Web方法参数包装到客户端中的单个字符串中。 The following example shows a way of doing this in C#: 以下示例显示了在C#中执行此操作的方法:

  var requestdata = new
  {
    id = order.OrderID,
    order = order
  };
  string data2 = JsonConvert.SerializeObject(requestdata);

Note that the field names in the anonymous method match the parameter names in your web method. 请注意,匿名方法中的字段名称与Web方法中的参数名称匹配。

For reference, the JSON that this produces looks like this where you can see the id and order objects in the JSON string: 作为参考,它生成的JSON看起来像这样你可以在JSON字符串中看到idorder对象:

{"id":"10560","order":{"OrderID":"10560","OrderDate":"06/09/2013 12:29:04","ShippedDate":"16/09/2013 12:29:04","ShipCountry":"Uganda","OrderTotal":"781"}}

You should be able to test out JSON in this format in Fiddler with your example. 您应该能够使用您的示例在Fiddler中以此格式测试JSON。


Extending the answer to deal with other datatypes 扩展答案以处理其他数据类型

Using a DataContract that includes a bool and a DateTime property: 使用包含boolDateTime属性的DataContract

[DataContract]
public class OrderContract
{
  [DataMember]
  public string OrderID { get; set; }

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

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

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

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

  [DataMember]
  public bool Shipped { get; set; }

  [DataMember]
  public DateTime DeliveredDate { get; set; }
}

The issue here is dealing with the DateTime and making sure that the JSON is in a format that the WCF RESTful service can deserialize. 这里的问题是处理DateTime并确保JSON采用WCF RESTful服务可以反序列化的格式。 To get this to work I used this code on the client: 为了实现这一点,我在客户端上使用了这段代码:

OrderContract order = new OrderContract
{
  OrderID = "10560",
  OrderDate = DateTime.Now.ToString(),
  ShippedDate = DateTime.Now.AddDays(10).ToString(),
  ShipCountry = "India",
  OrderTotal = "781",
  Shipped = true,
  DeliveredDate = DateTime.Now
};

DataContractJsonSerializer ser =
        new DataContractJsonSerializer(typeof(OrderContract));
MemoryStream mem = new MemoryStream();
ser.WriteObject(mem, order);
string data =
    Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);

var requestdata = new
{
  id = order.OrderID,
  order = order
};
JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings
{
  DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
string data2 = JsonConvert.SerializeObject(requestdata, microsoftDateFormatSettings);
WebClient webClient = new WebClient();
webClient.Headers["Content-type"] = "application/json";
webClient.Encoding = Encoding.UTF8;
webClient.UploadString("http://localhost:61966/OrderService.svc/PlaceOrder", "POST", data2);

Note the JSON Serializer settings - this produces the following JSON: 请注意JSON Serializer设置 - 这会生成以下JSON:

{"id":"10560","order":{"OrderID":"10560","OrderDate":"10/09/2013 16:15:30","ShippedDate":"20/09/2013 16:15:30","ShipCountry":"India","OrderTotal":"781","Shipped":true,"DeliveredDate":"\/Date(1378826130655+0100)\/"}}

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

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