【问题标题】:REST WCF service returns XML response but not JSON responseREST WCF 服务返回 XML 响应但不返回 JSON 响应
【发布时间】:2012-06-13 13:46:24
【问题描述】:

我是 WCF 的新手,所以我认为这是非常基本的。我有一个简单的方法,它返回一个“订单”对象。使用默认 XML 时它工作得很好,但是,当我应用

ResponseFormat = WebMessageFormat.Json

属性,无法返回JSON。代码成功执行并命中返回行,但随后立即再次调用该方法,最后第三次调用,然后浏览器返回错误说明与本地主机的连接已中断

当我删除ResponseFormat = WebMessageFormat.Json 时,调用该方法并返回XML 就好了。不确定我是否缺少 JSON。

IProductSales.cs

namespace ProductsSalesService
{
    [ServiceContract(Name = "ProductsSales")]
    public interface IProductsSales
    {

        [OperationContract]
        [WebGet(UriTemplate = "Orders/{orderID}", ResponseFormat = WebMessageFormat.Json)]
        [Description("Returns the details of an order")]
        SalesOrderHeader GetOrder(string orderID);

    }
}

产品销售

public SalesOrderHeader GetOrder(string orderID)
{
    SalesOrderHeader header = null;

    try
    {
        int id = Convert.ToInt32(orderID);
        AdventureWorksEntities database = new AdventureWorksEntities();

            header = (from order in database.SalesOrderHeaders
                      where order.SalesOrderID == id
                      select order).FirstOrDefault();

    }
    catch
    {
        throw new WebFaultException(HttpStatusCode.BadRequest);
    }

    return header;
}

我正在研究 WCF 书中的一个示例,因此他们让我构建了一个小型控制台应用程序作为主机,所以这是我为主机客户端准备的 app.config 文件。

<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <add name="AdventureWorksEntities" connectionString="metadata=res://*/ProductsSalesModel.csdl|res://*/ProductsSalesModel.ssdl|res://*/ProductsSalesModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=BINGBONG;Initial Catalog=AdventureWorks;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup><system.serviceModel>
    <services>
      <service name="ProductsSalesService.ProductsSales">
        <endpoint address="http://localhost:8000/Sales" binding="webHttpBinding"
          bindingConfiguration="" name="ProductsSalesService.ProductsSales"
          contract="ProductsSalesService.IProductsSales" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

最后,这只是主机客户端代码。

public class Program
    {
        static void Main(string[] args)
        {
            WebServiceHost host = new WebServiceHost(typeof(ProductsSalesService.ProductsSales));
            host.Open();
            Console.WriteLine("Service running");
            Console.WriteLine("Press ENTER to stop the service");
            Console.ReadLine();
            host.Close();
        }
    }

所以当我去http://localhost:8000/Sales/Orders/43659 提取我的订单时,它点击了三下,页面在 Chrome 中取消并出现以下错误:

此网页不可用 与 localhost 的连接是 打断了。以下是一些建议: 稍后重新加载此网页。 检查您的互联网连接。重新启动任何路由器、调制解调器或其他 您可能正在使用的网络设备。将 Google Chrome 添加为允许 防火墙或防病毒软件设置中的程序。如果是 已经是允许的程序,请尝试将其从列表中删除 允许的程序并再次添加。如果您使用代理服务器, 检查您的代理设置或联系您的网络管理员以 确保代理服务器正常工作。如果你不相信你应该 使用代理服务器,调整您的代理设置:转到扳手 菜单 > 设置 > 显示高级设置... > 更改代理设置...

LAN 设置并取消选中“为 LAN 使用代理服务器”复选框。错误 101 (net::ERR_CONNECTION_RESET):连接是 重置。

如果我删除 WebMessageFormat.Json 一切正常!

感谢您的帮助!

【问题讨论】:

    标签: wcf


    【解决方案1】:

    对于初学者,请尝试 WCF 跟踪/日志记录,看看它是否能说明问题。

    把它放在你服务器的配置文件中(在&lt;configuration&gt;元素的某个地方):-

    <system.diagnostics>
     <sources>
      <source name="System.ServiceModel" switchValue="Error" propagateActivity="true">
        <listeners>
          <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Temp\server.svclog"/>
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add name="messages"
          type="System.Diagnostics.XmlWriterTraceListener"
          initializeData="C:\Temp\server_messages.svclog" />
        </listeners>
      </source>
     </sources>
    </system.diagnostics>
    

    并将其放在&lt;system.serviceModel&gt; 元素中:-

    <diagnostics>
      <messageLogging
           logEntireMessage="true"
           logMalformedMessages="false"
           logMessagesAtServiceLevel="true"
           logMessagesAtTransportLevel="false"
           maxMessagesToLog="3000"
           maxSizeOfMessageToLog="2000"/>
    </diagnostics>
    

    再次尝试访问您的服务并检查此(希望)生成的 .svclog 文件以寻找线索。这些文件将在“服务跟踪查看器”工具中打开 - 如果没有,可以从 MS 下载(我认为是 Win SDK 的一部分)。

    【讨论】:

    • 诊断结果揭示了我真正的问题,这是我收到的一个异常:“类型 'xxx' 无法序列化为 JSON,因为它的 IsReference 设置为 'True'。JSON 格式不支持引用,因为没有用于表示引用的标准化格式。要启用序列化,请禁用类型或类型的适当父类上的 IsReference 设置,这意味着 WCF 的本机 DataContractJsonSerializer 无法序列化实体框架对象。
    【解决方案2】:

    虽然我的错误实际上是无关的,但这是我在调查我的问题时发现的第一篇文章,即我的服务失败并且我看到一个错误连接已中断

    我的错是因为我从WebGet 方法输出的类具有具有DataContract 属性的属性,但我没有为每个属性添加Set 访问器(因为我认为它们仅输出我没有看到这一点)。

    将跟踪添加到我的配置文件中很快发现错误是没有Set 访问器,因此我将private set 访问器添加到每个DataContract 属性,现在一切都按预期工作。

    我已在此处添加此内容,以防其他人遵循相同的搜索路径并遇到相同的问题

    【讨论】:

      【解决方案3】:

      这行代码将在不考虑配置的情况下构建服务主机,因此您将拥有服务,但它会侦听不同的 URL。

      WebServiceHost host = new WebServiceHost(typeof(ProductsSalesService.ProductsSales));
      

      在下面添加基地址new WebServiceHost加代码:

          WebChannelFactory<ProductsSalesService.IProductsSales> cf = 
          new WebChannelFactory<ProductsSalesService.IProductsSales>("ProductsSalesService.ProductsSales");
      ProductsSalesService.IProductsSales channel = cf.CreateChannel();
      

      在此处查看完整代码 - http://msdn.microsoft.com/en-us/library/bb919583

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-16
        • 2017-08-10
        • 1970-01-01
        • 2018-05-23
        • 2013-08-23
        • 2021-09-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多