json - 如何发送 DataContract 对象作为 WCF RESTFUL web 服务的参数?

标签 json wcf rest wcf-rest

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

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

[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; }
        }
    }

函数的实际定义:

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

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

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

Fiddler snap when sending the request Fiddler snap of the output 以上是我正在测试服务的 fiddler 的快照。 经过几次谷歌搜索后,我得到了以下链接,其中客户端实际使用 web 服务引用来获取 DataContract 类型并在作为请求正文发送之前序列化为 json。但是为什么我的 Fiddler 测试没有成功?! https://geeksarray.com/blog/wcf-rest-service-to-get-or-post-json-data-and-retrieve-json-data-with-datacontract

任何人都可以提出任何建议吗?

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>

最佳答案

要让这个场景发挥作用,您需要做几件事。

首先,在服务契约中,需要将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);

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

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

请注意,匿名方法中的字段名称与您的网络方法中的参数名称匹配。

作为引用,这生成的 JSON 看起来像这样,您可以在 JSON 字符串中看到 idorder 对象:

{"id":"10560","order":{"OrderID":"10560","OrderDate":"06/09/2013 12:29:04","ShippedDate":"16/09/2013 12:29:04","ShipCountry":"乌干达","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; }
}

此处的问题是处理 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);

注意 JSON 序列化程序设置 - 这会生成以下 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)\/"}}

关于json - 如何发送 DataContract 对象作为 WCF RESTFUL web 服务的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18651878/

相关文章:

c# - WCF N 层应用程序中的异常处理和日志记录

java - 使用 POST 方法的 RESTful Java 客户端

spring - Spring 启动。在一个应用程序中为@Ccontroller和@RestController处理不同的错误

c# - HighCharts (highstock) - 数据不会显示

php - 使用 json 发送邮件

wcf - 是否建议将 self 跟踪实体与 WCF 服务一起使用?

node.js - NodeJS 路由器负载太大

json - 下拉列表无法从对象中提取数字值(Angular 4)

java - 文本中的特殊字符

.net - 尝试将 Web 引用添加到 WCF 服务时出现 HTTP 400 错误请求错误