WCF服务返回HTTP 400,但仅当Content-Type设置为“text / xml”或“text / json”时

时间:2009-11-20 20:45:04

标签: c# wcf iis

我真的很难过。我已经尝试了所有可以想象的工具,检查了我能够的每一种资源,但仍然无法理解这一点。

我有一个WCF服务,旨在以专有的XML格式处理普通的旧XML请求(这是一个旧的ASMX转换)。我使用WCF 3.5设置服务以接受普通的HTTP POST请求,只要请求标头中的Content-Type未设置为“text / xml”(或任何其他XML或JSON类型,它就能很好地工作,例如“text / json”或“application / json”)。

换句话说,如果我将请求的内容类型设置为“text”或“text / plain”甚至“what”,则服务按预期工作。但是,当我将内容类型设置为“text / xml”时,服务因HTTP 400 Bad Request而失败。

我找不到调试失败的方法来获取更多信息。永远不会调用实际的服务方法,并且实现IErrorHandler也没有捕获错误。我怀疑我的WCF配置或我的IIS 7设置有问题,但我对于发生的事情一无所知。

这是我的服务合同:

using System.ServiceModel;
using System.ServiceModel.Web;
using System.IO;

namespace App.api.v_1_1
{
    [ServiceContract]
    public interface IPlainXmlWebServiceViaHttpPost
 {
        [WebInvoke(UriTemplate = "", BodyStyle = WebMessageBodyStyle.Bare, Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
        [OperationContract]
  Stream Process(Stream xml);
 }
}

这是我的服务实施:

using System.IO;
using System.ServiceModel.Activation;
using App.api.v_1_0;
using System.ServiceModel;

namespace App.api.v_1_1
{
    [ServiceBehavior(Namespace = Constants.WebServiceNamespace)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class PlainXmlWebServiceViaHttpPost : IPlainXmlWebServiceViaHttpPost
 {
        public Stream Process(Stream request)
        {
            return request.ProcessTextStreamWith(PoxProcessor.Process);
        }
 }
}

基本上它只是将传入的Stream转换为字符串,使用该字符串执行某些操作,并返回转换回Stream的字符串响应。我们的想法是能够将任意XML传递给服务并返回任意XML。

最后,这是web.config的相关部分:

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <bindings>
        <webHttpBinding>
            <binding name="poxBinding" maxReceivedMessageSize="655360">
                <readerQuotas maxArrayLength="655360" />
                <security mode="None">
                    <transport clientCredentialType="None" />
                </security>
            </binding>
        </webHttpBinding>
    </bindings>
    <behaviors>
        <endpointBehaviors>
            <behavior name="REST">
                <webHttp />
            </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior name="poxBehavior">
                <serviceDebug httpHelpPageEnabled="false" includeExceptionDetailInFaults="true" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
        <service behaviorConfiguration="poxBehavior" name="App.api.v_1_1.PlainXmlWebServiceViaHttpPost">
            <endpoint address="" behaviorConfiguration="REST" binding="webHttpBinding"
                bindingConfiguration="poxBinding" contract="App.api.v_1_1.IPlainXmlWebServiceViaHttpPost" />
        </service>
    </services>
</system.serviceModel>

我一直在尝试各种解决方法让WCF / IIS与我合作,但都失败了。有谁知道什么会导致请求预期的内容类型返回HTTP 400,但所有其他内容类型都按预期处理?

2 个答案:

答案 0 :(得分:7)

您是否在.svc文件中使用了WebServiceHostFactory

<%@ ServiceHost 
    Factory="System.ServiceModel.Activation.WebServiceHostFactory"   
    Service="App.api.v_1_1.PlainXmlWebServiceViaHttpPost" 
%>

答案 1 :(得分:2)

对你有几点想法。您可以查看rest starter kit。他们创造了许多额外的东西,以帮助建立宁静的服务,并有很多很好的例子。

在解决wcf服务问题时要尝试的另一件事是打开邮件日志记录。您可以在配置文件中执行此操作:

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

可以使用SvcTraceViewer.exe(我位于此处:C:\ Program Files \ Microsoft SDKs \ Windows \ v6.0A \ bin)读取日志文件。我相信这个工具附带Windows SDK。在同一位置找到的配置编辑器(SvcConfigEditor.exe)可用于帮助编辑web.config。如果在将配置文件加载到编辑器后单击“诊断”文件夹,还有其他选项可供记录。