我在将复杂 JSON 用作 WCF 服务中的参数时遇到问题。
在 Visual Studio 2008 SP1 中使用 Microsoft.Net 3.5 SP1
有以下契约(Contract):
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(UriTemplate="GetDataUsingDataContract?composite={composite}",
BodyStyle=WebMessageBodyStyle.Wrapped,
RequestFormat=WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
CompositeType GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
}
// Use a data contract as illustrated in the sample below to add composite types to service operations
[DataContract]
public class CompositeType
{
string boolValue = "true";
string stringValue = "Hello ";
[DataMember]
public string BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
使用以下网址:
http://localhost:1122/Service1.svc/GetDataUsingDataContract?composite={"BoolValue":"True","StringValue":"Hello"}
使用端点配置:
<system.serviceModel>
<services>
<service name="WebHTTPBindingExample.Service1" behaviorConfiguration="WebHTTPBindingExample.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/Design_Time_Addresses/WebHTTPBindingExample/Service1/"/>
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<!--<endpoint address="" binding="wsHttpBinding" contract="WebHTTPBindingExample.IService1">
--><!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
--><!--
<identity>
<dns value="localhost"/>
</identity>
</endpoint>-->
<endpoint address="Web" behaviorConfiguration="ChatAspNetAjaxBehavior" binding="webHttpBinding" name="ajaxEndpoint" contract="WebHTTPBindingExample.IService1"/>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WebHTTPBindingExample.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="False"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="ChatAspNetAjaxBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
我收到以下错误:
Operation 'GetDataUsingDataContract' in contract 'IService1' has a query variable named 'composite' of type 'WebHTTPBindingExample.CompositeType', but type 'WebHTTPBindingExample.CompositeType' is not convertible by 'QueryStringConverter'. Variables for UriTemplate query values must have types that can be converted by 'QueryStringConverter'.
最佳答案
我不相信您可以通过这种方式使用 WCF 在查询字符串上传递复杂类型。见 this response来自 ASP.NET 论坛中的 Microsoft 技术 - 这与您的情况类似。
根据您如何删除服务方法,似乎更合适的动词是 POST 或 PUT,您可以输入 CompositeType
请求正文中的有效负载。但我猜你的意图。
通过将查询字符串类型从 CompositeType
更改,我能够使您的代码正常工作并仍然使用 GET至 String
然后将 JSON 字符串反序列化为 CompositeType
通过使用 ASP.NET JavaScriptSerializer
类。 (你可以在这里使用你最喜欢的 JSON 帮助类——我偏爱 JSON.NET ,但我也听说 FlexJson 也很好。)
我没有接触你的 web.config(除了让它在我的本地测试应用程序中工作)。我唯一的变化是服务方法签名和服务方法的实现。
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(UriTemplate = "GetDataUsingDataContract?composite={composite}",
BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
CompositeType GetDataUsingDataContract(String composite);
// TODO: Add your service operations here
}
public class Service1 : IService1
{
public CompositeType GetDataUsingDataContract(String composite)
{
//use the JavaScriptSerializer to convert the string to a CompositeType instance
JavaScriptSerializer jscript = new JavaScriptSerializer();
CompositeType newComp = jscript.Deserialize<CompositeType>(composite);
newComp.StringValue += " NEW!";
return newComp;
}
}
我希望这会有所帮助。如果您对此有其他疑问,请告诉我。
关于WCF 复杂 JSON INPUT 错误(QueryStringConverter 不可转换),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5241661/