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

mar*_*man 2 rest wcf json wcf-rest

我正在开发一个WCF resful服务,它将基本上从一些移动应用程序中消耗.在POST上我试图发送一个DataContract对象[实际上我必须发送一个对象列表]和另一个单独的id作为字符串.我的问题是,是否可能定义我的函数来接受DataContract对象和单个字符串?

以下是我的代码:接口声明:

[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; }
        }
    }
Run Code Online (Sandbox Code Playgroud)

功能的实际定义:

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;
        }
Run Code Online (Sandbox Code Playgroud)

我试图从Fiddler发送的json对象是

{"BoolValue":true,"StringValue":"sdfsdfsf"}
Run Code Online (Sandbox Code Playgroud)

Fiddler在发送请求时捕捉 提琴手快速输出 以上是我正在测试服务的小提琴手的快照.经过几次谷歌搜索后,我得到了以下链接,其中客户端实际使用webservice引用获取DataContract类型并序列化为json,然后作为请求体发送.但是为什么我对Fiddler的测试没有成功? http://dotnetmentors.com/wcf/wcf-rest-service-to-get-or-post-json-data-and-retrieve-json-data-with-datacontract.aspx

任何人都可以建议吗?

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>
Run Code Online (Sandbox Code Playgroud)

Dom*_*tts 12

要使此方案起作用,您需要做几件事.

首先,在服务合同中,您需要将具有多个参数的方法标记为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);
Run Code Online (Sandbox Code Playgroud)

使用此属性参数,您必须将多个Web方法参数包装到客户端中的单个字符串中.以下示例显示了在C#中执行此操作的方法:

  var requestdata = new
  {
    id = order.OrderID,
    order = order
  };
  string data2 = JsonConvert.SerializeObject(requestdata);
Run Code Online (Sandbox Code Playgroud)

请注意,匿名方法中的字段名称与Web方法中的参数名称匹配.

作为参考,它生成的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"}}

您应该能够使用您的示例在Fiddler中以此格式测试JSON.


扩展答案以处理其他数据类型

使用包含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; }
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是处理DateTime并确保JSON采用WCF RESTful服务可以反序列化的格式.为了实现这一点,我在客户端上使用了这段代码:

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);
Run Code Online (Sandbox Code Playgroud)

请注意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)\/"}}
Run Code Online (Sandbox Code Playgroud)