开发者

WCF REST service 400 Bad Request

I have WCF RESTful service and Android client.

Server replies with 400 when I do bigger request. It seems that I have 65k limit issue like in here or in other million posts on same problem.

However, I can't seem to be able to fix it. Here is how my web.config looks

    <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>

Here is code example of service function:

[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;
        }

Here is code inside my Web project which hosts WCF (Global.asax.cs)

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)));
                }
            }
        }

From what I understand Java HttpClient doesn't impose any limits so it's on WCF side. Any pointers on how to solve this issue or how to intercept message in WCF?

EDIT 2: This is what trace shows. And when I modigy standardEndpoint it doesn't help...

WCF REST service 400 Bad Request


Forgive me if you've seen this link (Similar StackOverflow Question):

By default the WCF Transport is limited to sending messages at 65K. If you want to send larger you need to enable Streaming Transfer Mode and you need to increase the size of MaxReceivedMessageSize, which is there just as a guard to prevent someone killing your server by uploading a massive file.

So, you can do this using binding configuration or you can do it in code. Here is one way to do it in code:

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


You don't need to use streaming in this case - all you need to do is to increase the maxReceivedMessageSize quota on the standard webHttpEndpoint:

<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>

Update: if the config change didn't work (I don't know why), you can try increasing it in code. By using a custom service host factory, you get a reference to the endpoint object and you can increase the quota there. The code below shows one such a factory (you'll need to update the RegisterRoute code to use this new factory):

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;
                    }
                }
            }
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜