wcf 3.5 REST服务使用XML而不是JSON响应格式

时间:2010-08-17 16:07:34

标签: c# .net wcf json

我有一份服务合同,其中定义了多个运营合同。我添加了一个新的端点,将我的操作公开为一个宁静的Web服务。此外,我已经更新了操作定义,以便可以以RESTful方式调用它们

    [OperationContract]
    [WebInvoke(
    Method = "GET",
    ResponseFormat = WebMessageFormat.Xml,
    BodyStyle = WebMessageBodyStyle.Bare,
    UriTemplate = "product/getall")]   
    Product[] GetAll()

一切正常我的产品以XML格式返回......但我想改用JSON。如果我将代码更改为

[OperationContract]
[WebInvoke(
Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "product/getall")]   
Product[] GetAll()

对product / getall调用的响应为空。没有异常被抛出,但我感觉WCF JSON实现无法应对序列化。谁有类似的问题?有什么建议?是否可以使用JSON.NET来序列化/反序列化我的对象?

2 个答案:

答案 0 :(得分:2)

我能够让它发挥作用 - 这就是我所做的。首先,我的环境是VS2010,我使用的是VS Web服务器(Cassini)。

我没有更改您的方法签名或您的WebInvoke属性。 GetAll()方法的主体是:

[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "product/getall")]
Product[] GetAll()
{
    Product[] prods = new Product[3] {
        new Product() { Name="Foo", Desc="Bar"},
        new Product() {Name="Ha", Desc="Ho"},
        new Product() {Name="Who", Desc="What"}
    };

    return prods;
}

web.config看起来像这样:

<system.serviceModel>
    <behaviors>
        <endpointBehaviors>
            <behavior name="WebApplication2.ProdServiceAspNetAjaxBehavior">
              <webHttp />
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
        multipleSiteBindingsEnabled="true" />
    <services>
        <service name="WebApplication2.ProdService">
            <endpoint address="" behaviorConfiguration="WebApplication2.ProdServiceAspNetAjaxBehavior"
                binding="webHttpBinding" contract="WebApplication2.ProdService" />
        </service>
    </services>
</system.serviceModel>

老实说,大部分都是默认的开箱即用功能。我唯一更改的是将endpointBehavior更改为使用webHttp而不是默认enableWebScript。除此之外,它运作良好。

编辑(忘记了产品类):这是Product类 - 我用DataContractDataMember属性修饰了它:

[DataContract]
public class Product
{
    [DataMember()]
    public String Name { get; set; }
    [DataMember()]
    public String Desc { get; set; }
}

这是我的输出:

[{"Desc":"Bar","Name":"Foo"},{"Desc":"Ho","Name":"Ha"},{"Desc":"What","Name":"Who"}]

我的猜测是你在web.config中使用enableWebScript。将其更改为webHttp,看看会发生什么。 enableWebScript设置用于更多ASMX类型的兼容性(我相信)。如果您正在返回JSON(我的许多GET服务方法都会这样做),请使用webHttp(这是我以前习惯使用的)。

让我知道你得到了什么,我会相应地更新我的答案。

答案 1 :(得分:1)

打开WCF跟踪并查看跟踪日志。这应该确定问题所在。您可以使用以下设置配置web.config以启用跟踪。

<system.serviceModel>
  <diagnostics>
      <messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" />
  </diagnostics>
</system.serviceModel>

<system.diagnostics>
  <sources>
    <source name="System.ServiceModel" switchValue="Warning, ActivityTracing"
      propagateActivity="true">
      <listeners>
        <add type="System.Diagnostics.DefaultTraceListener" name="Default">
          <filter type="" />
        </add>
        <add name="ServiceModelTraceListener">
          <filter type="" />
        </add>
      </listeners>
    </source>
    <source name="System.ServiceModel.MessageLogging" switchValue="Warning, ActivityTracing">
      <listeners>
        <add type="System.Diagnostics.DefaultTraceListener" name="Default">
          <filter type="" />
        </add>
        <add name="ServiceModelMessageLoggingListener">
          <filter type="" />
        </add>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add initializeData="C:\Web_tracelog.svclog"
      type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
      name="ServiceModelTraceListener" traceOutputOptions="Timestamp">
      <filter type="" />
    </add>
    <add initializeData="C:\Web_messages.svclog"
      type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
      name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
      <filter type="" />
    </add>
  </sharedListeners>
</system.diagnostics>