WCF REST 服务 400 错误请求

Posted

技术标签:

【中文标题】WCF REST 服务 400 错误请求【英文标题】:WCF REST service 400 Bad Request 【发布时间】:2011-09-29 18:31:58 【问题描述】:

我有 WCF RESTful 服务和 android 客户端。

当我提出更大的请求时,服务器回复 400。看来我有 65k 限制问题,例如 在here 或其他百万个关于相同问题的帖子中。

但是,我似乎无法修复它。这是我的 web.config 的外观

    <system.serviceModel>
    <diagnostics>
      <messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true"
        logMessagesAtTransportLevel="true" />
    </diagnostics>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint name="myEndpoint" helpEnabled="true" automaticFormatSelectionEnabled="true" maxReceivedMessageSize="1000000" />
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

这是服务功能的代码示例:

[WebInvoke(UriTemplate = "/trips/TripId/inspection", Method = "POST")]
        [Description("Used on mobile devices to submit inspections to server")]
        public void PostTripInspection(string tripId, Inspection inspection)
        
            return;
        

这是托管 WCF (Global.asax.cs) 的 Web 项目中的代码

private static void RegisterRoutes()
        
            // Setup URL's for each customer
            using (var cmc = new CoreModelContext())
            
                foreach (var account in cmc.Accounts.Where(aa => aa.IsActive).ToList())
                
                    RouteTable.Routes.Add(
                        new ServiceRoute(
                            account.AccountId + "/mobile", new WebServiceHostFactory(), typeof(MobileService)));
                
            
        

据我了解,Java HttpClient 没有施加任何限制,因此它在 WCF 方面。有关如何解决此问题或如何在 WCF 中拦截消息的任何指示?

编辑 2: 这就是跟踪显示的内容。当我修改标准端点时,它没有帮助......

【问题讨论】:

【参考方案1】:

如果您看到此链接 (Similar *** Question),请原谅我:

默认情况下,WCF 传输是 仅限于以 65K 发送消息。如果 你想发送更大的,你需要 启用流传输模式和 你需要增加 MaxReceivedMessageSize,在那里 就像一个守卫来阻止某人 通过上传一个来杀死你的服务器 海量文件。

所以,你可以使用绑定来做到这一点 配置,或者你可以在 代码。这是一种方法 代码:

var endpoint = ((HttpEndpoint)host.Description.Endpoints[0]); //Assuming one endpoint
endpoint.TransferMode = TransferMode.Streamed;
endpoint.MaxReceivedMessageSize = 1024 * 1024 * 10;  // Allow files up to 10MB

【讨论】:

编程设置见social.technet.microsoft.com/wiki/contents/articles/…。或者,通过 web.config,尝试将 transferMode="Streamed" 添加到绑定元素。 此链接未显示端点获取的配置位置。但无论如何,我认为这不是正确的方向。我的 Android 客户端执行简单的 POST,不涉及流式传输。它只是 POST 大 json 字符串.. 端点的绑定是在该链接的 Test() 方法中配置的。 我明白了。但它显示了 SERVER 如何将数据流式传输回客户端。就像我提到的那样,在我的情况下,服务器不会用数据回复客户端。客户端将大 json 发布到服务器。所以,我需要配置服务器以便它监听并且不拒绝 @katit 该代码仅与使用来自wcf.codeplex.com的新 ​​WCF Web API 库的人相关【参考方案2】:

在这种情况下,您不需要使用流式传输 - 您需要做的就是增加标准 webHttpEndpoint 上的 maxReceivedMessageSize 配额:

<standardEndpoints>
  <webHttpEndpoint>
    <!-- 
        Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
        via the attributes on the <standardEndpoint> element below
    -->
    <standardEndpoint name=""
                      helpEnabled="true"
                      automaticFormatSelectionEnabled="true"
                      maxReceivedMessageSize="1000000"/>
  </webHttpEndpoint>
</standardEndpoints>

更新:如果配置更改不起作用(我不知道为什么),您可以尝试在代码中增加它。通过使用自定义服务主机工厂,您可以获得对端点对象的引用,并且可以在那里增加配额。下面的代码显示了这样一个工厂(您需要更新RegisterRoute 代码才能使用这个新工厂):

public class MyWebServiceHostFactory : ServiceHostFactory

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    
        return base.CreateServiceHost(serviceType, baseAddresses);
    

    class MyWebServiceHost : WebServiceHost
    
        public MyWebServiceHost(Type serviceType, Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        
        
        protected override void OnOpening()
        
            base.OnOpening();
            foreach (ServiceEndpoint endpoint in this.Description.Endpoints)
            
                if (!endpoint.IsSystemEndpoint)
                
                    Binding binding = endpoint.Binding;
                    if (binding is WebHttpBinding)
                    
                        ((WebHttpBinding)binding).MaxReceivedMessageSize = 1000000;
                    
                    else
                    
                        CustomBinding custom = binding as CustomBinding;
                        if (custom == null)
                        
                            custom = new CustomBinding(binding);
                        

                        custom.Elements.Find<HttpTransportBindingElement>().MaxReceivedMessageSize = 1000000;
                    
                
            
        
    

【讨论】:

看起来就是这样,对吧?对我来说很有意义,但不起作用:(请参阅更新的主帖。我运行了跟踪,是的,这个属性似乎是问题所在。我想知道我需要修改什么绑定.. 应该可以,但如果不行,你可以试试我添加到答案中的更新解决方案。 我会将您的帖子标记为答案,因为您将我指向我应该查看的位置。你猜怎么了?!从端点删除“name =”“”后它开始工作。 Microsoft 服务配置编辑器对此进行了投诉,但代码不会使用任何名称注册此配置。标签必须出...

以上是关于WCF REST 服务 400 错误请求的主要内容,如果未能解决你的问题,请参考以下文章

WCF REST的POST时候报400错误是怎么回事

WCF - 远程服务器返回意外响应:(400)错误请求

WCF 服务 400 错误请求

wcf 服务错误请求 400 流式传输

使用 GET 访问 WCF 休息服务时出现 400 http 错误请求错误

WCF:自托管服务上的 HTTP 400 错误请求