简体   繁体   中英

Error 400 on WCF Rest Service Get Request

I recently developed a WCF rest service where its sole purpose is to handle Get requests and return data.

I have (mostly) successfully done this however I run into an issue when I want to send more than about 200-300 characters in the request. Whenever I try this I end up getting an error 400 on the webpage. Initially I thought I was running into some sort of character limitation but after reading many webpages and other questions I'm stumped as to what is truly failing.

I have tried to change bindings like maxReceivedMessageSize, maxStringContentLength, maxBufferSize, and maxBufferPoolSize hoping one of those was the culprit but alas I was wrong. I also tried to add tracing to see if I could read any errors in the log but when I make a long request nothing gets added to the log. I'm unable to use a different browser than edge currently so I made an app that uses HttpClient to communicate with my server and I am still getting an error 400 when I make a "long" request.

An example of a request that works perfectly fine is http://IP:PORT/POINTINFO/DBNAME/{"User":"testuser","Pc":"testpc","Data":["Point01","Point02"]}

An example of a request that will get an error 400 is http://IP:PORT/POINTINFO/DBNAME/{"User":"testuser","Pc":"testpc","Data":["U1R0011AS","U1R0012AS","U1R0012BS","U1R0041AS","U1R0041BS","U1R0041CS","U1R0044AS","U1R0044BS","U1R0046AS","U1R0046BS","U1R0046CS","U1R0046DS","U1R11A-AV","U1R12A-AV","U1R12B-AV","U1R41A-AV","U1R41B-AV","U1R41C-AV","U1R44A-AV","U1R44B-AV","U1R46A-AV","U1R46B-AV","U1R46C-AV","U1R46D-AV","U1R46E-AV","U1RCSCOLDEST","U1RCSPRESS","U1RXPCNTBE"]}

As you can see, the request is long (at least to type) but it shouldn't be hitting any limitations. This is also perfectly valid JSON so that can't be why it's dying. I've also tried to put a breakpoint on my GetPointList function to see if there's something wrong with my code, but that never even gets called. This is my only exposure to WCF rest services so I'm sure there's a beginners mistake I'm making but I can't see what I'm doing wrong. Any help will be appreciated.

Here is my main:

static void Main(string[] args)
    {
        WebServiceHost hostWeb = new WebServiceHost(typeof(ConsoleApp1.Service));
        ServiceEndpoint ep = hostWeb.AddServiceEndpoint(typeof(ConsoleApp1.IService), new WebHttpBinding(), "");
        ServiceDebugBehavior stp = hostWeb.Description.Behaviors.Find<ServiceDebugBehavior>();
        stp.HttpHelpPageEnabled = false;
        hostWeb.Open();
        Console.WriteLine("Service Host started @ " + DateTime.Now.ToString());
        Console.Read();
    }

This is the interface I have:

    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        [WebInvoke(Method = "GET",
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "POINTINFO/{database}/{pointlist}")]
        [return: MessageParameter(Name = "Data")]
        List<PointData> GetPointList(string pointlist, string database);
    }

Here is my config that is scarred with prior attempts at fixing my issue:

<!--tracing for error detection-->
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel.MessageLogging" switchValue="Information, ActivityTracing">
        <listeners>
          <add name="log"
               type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="C:\Users\Administrator\Documents\messages.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

  <system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>

    <bindings>
      <!--<wsHttpBinding>-->
      <basicHttpBinding>
        <binding name="basicHttp" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="01:00:00" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
          <security mode="None">
            <!--<transport clientCredentialType="None" />-->
          </security>
          <readerQuotas maxStringContentLength="2147483647"/>
          <!--<reliableSession enabled="true" />-->
        </binding>
      </basicHttpBinding>
      <!--</wsHttpBinding>-->

      <webHttpBinding>
        <binding name="webHttp" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="01:00:00" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
          <security mode="None">
            <!--<transport clientCredentialType="None" />-->
          </security>
          <readerQuotas maxStringContentLength="2147483647"/>
        </binding>
      </webHttpBinding>
    </bindings>

    <services>

      <service name="ConsoleApp1.Service">
        <endpoint address="rest"  binding="webHttpBinding" bindingConfiguration="webHttp" contract="ConsoleApp1.IService" behaviorConfiguration="web"></endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:12345" />
          </baseAddresses>
        </host>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="mexBehaviour">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <!-- rest api-->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>

      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>

    <diagnostics>
      <messageLogging
           logEntireMessage="true"
           logMalformedMessages="true"
           logMessagesAtServiceLevel="true"
           logMessagesAtTransportLevel="true"
           maxMessagesToLog="300"
           maxSizeOfMessageToLog="20000"/>
    </diagnostics>
  </system.serviceModel>

I figured it out, thanks to this website: https://www.codeproject.com/Questions/847265/WCF-How-to-overcome-urllength-restriction

It turns out that the default character limit of each parameter in a REST url is 260. So you have to go in the registry and change the value of UrlSegmentMaxLength in HEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters to a REG_DWORD of whatever value you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM