界面:
namespace SQRT_WCF
{
[DataContract]
public class PlaceOrder
{
[DataMember]
public string claimID { get; set; }
[DataMember]
public string rederenceDate { get; set; }
}
}
调用的 C# 方法:
public SQ_jsonModel.Response placeOrder(PlaceOrder argPlaceOrderJSON)
{
...
}
我已将 Web 服务附加到工作进程,并通过代码进行跟踪。到目前为止,我尝试过的所有操作,变量 argPlaceOrderJSON 均为 null。
我尝试过至少三种变体:
变化#1
{
"claimID" : "value",
"rederenceDate" : "value"
}
变化#2:
{
"PlaceOrder" : {
"claimID" : "value",
"rederenceDate" : "value"
}
变化#3:
{
"ns0:PlaceOrder" : {
"@xmlns:ns0" : "SQRT_WCF",
"claimID" : "value",
"rederenceDate" : "value"
}
我编写了一个快速的 C# 控制台程序来构建和序列化一个对象,它与上面的变体 1 匹配。所以现在我认为问题不在于 JSON,而在于 SOAP-UI 和 Web 服务之间的握手。接下来我将编写一个 C# 测试客户端,看看会发生什么。
SQRT_WCF.PlaceOrder order = new SQRT_WCF.PlaceOrder();
order.ClaimID = "claim1";
string strJson = new JavaScriptSerializer().Serialize(order);
有人询问 webservice 中的属性,假设这就是他的意思:
公共接口 ISQRTREST
{
【运营合同】
无效 DoWork();
[OperationContract]
[WebInvoke(Method="GET",
ResponseFormat = WebMessageFormat.Json ,
BodyStyle = WebMessageBodyStyle.Wrapped ,
UriTemplate ="json/{id}"
)]
string JSONData(String id);
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "placeOrder/"
)]
SQ_jsonModel.Response placeOrder(PlaceOrder order);
}
网页配置
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="SQRT_WCF.SQRTREST" behaviorConfiguration="ServiceBehaviour">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="longTimeoutBinding" contract="SQRT_WCF.ISQRTREST" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="longTimeoutBinding"
receiveTimeout="00:10:00" sendTimeout="00:10:00">
<security mode="None"/>
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
更新:
似乎更改 BodyStyle = WebMessageBodyStyle.Bare 使其可以与变体 1 一起使用。
但现在的问题是我需要能够让它与 WebMessageBodyStyle.Wrapped 一起工作。
这是生产中的现有 Web 服务。编写该程序的人早已去世,现在 B2B/BizTalk 团队正在接管该项目。我们正在使用尚未具备 REST 的 BT2010,并且我们正在尝试为客户提供相同的界面,因此他们无需更改 URL 以外的任何内容。
RESTful Web 服务主体格式似乎解释得相当好,我即将尝试使用 C# 中的 .wrapped 选项的变体 2。
更新2:
尝试使用 BodyWrapped 的变体 2 仍然得到一个 null 对象:
我就是这样包裹的。采取了 Update1 中有效的方法
string strPostBodyWrapped = "{\"PlaceOrder\" : " + strPostBody + "}";
午餐后将进行更多调试。
更新3:
还是没有运气。根据上面的 StackOverflow 参考,看起来包装器应该是“实体”,我尝试了几种方法:
来自 SOAP-UI:
{
"entity" : {
"claimID" : "value",
}
我还尝试了“实体”而不是“实体”,请确定。
我的数据合同中的所有字段都是字符串,因此序列化日期或数字应该没有问题。
来自 C# 客户端测试程序:
strPostBody = replaceSingleWithDoubleQuotes("{'ClaimID':'testvalue'}");
string strPostBodyWrapped = replaceSingleWithDoubleQuotes("{'entity': ") + strPostBody + "}";
public static string replaceSingleWithDoubleQuotes(string argText)
{
return argText.Replace("'", "\"");
}
如果我在 SOAP_UI 中尝试一些不好的事情,就像这样:
{
"entity" : { xxx
"claimID" : "value",
}
然后我意识到实体不是关键字而是他的类的名称......哎呀。
所以我尝试了“Placeorder”和“placeorder”作为我的案例的包装。
我收到一个很好的错误,如下所示:
The server encountered an error processing the request. The exception message is 'The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message for operation 'placeOrderSQRT'. Encountered unexpected character 'x'.'...
所以我不明白为什么在这种情况下解析器会失败,但在其他情况下它不会失败,但它也不会设置任何字段值。
如果我尝试无效的字段名称,但语法正确,解析器似乎不会给出任何错误,例如“claimIDxxxxxxxx”:“值”