【问题标题】:Error 400 on WCF Rest Service Get RequestWCF 休息服务获取请求上的错误 400
【发布时间】:2021-10-20 12:08:36
【问题描述】:

我最近开发了一个 WCF 休息服务,其唯一目的是处理 Get 请求和返回数据。

我已经(大部分)成功地完成了这项工作,但是当我想在请求中发送超过 200-300 个字符时遇到了问题。每当我尝试这样做时,我最终都会在网页上收到错误 400。最初我以为我遇到了某种字符限制,但在阅读了许多网页和其他问题后,我对真正失败的地方感到困惑。

我曾尝试更改 maxReceivedMessageSize、maxStringContentLength、maxBufferSize 和 maxBufferPoolSize 等绑定,希望其中一个是罪魁祸首,但可惜我错了。我还尝试添加跟踪以查看是否可以读取日志中的任何错误,但是当我提出长请求时,没有任何内容被添加到日志中。我目前无法使用与 edge 不同的浏览器,因此我制作了一个使用 HttpClient 与我的服务器通信的应用程序,当我发出“长”请求时仍然收到错误 400。

一个完美运行的请求示例是http://IP:PORT/POINTINFO/DBNAME/{"User":"testuser","Pc":"testpc","Data":["Point01","Point02"]}

将得到错误 400 的请求示例是 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"]}

如您所见,请求很长(至少要输入),但不应受到任何限制。这也是完全有效的 JSON,所以这不是它死亡的原因。我还尝试在我的 GetPointList 函数上放置一个断点,以查看我的代码是否有问题,但它甚至从未被调用。这是我唯一接触 WCF 休息服务的机会,所以我确信我犯了一个初学者错误,但我看不出我做错了什么。任何帮助将不胜感激。

这是我的主要内容:

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

这是我的界面:

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

这是我之前尝试解决我的问题的配置:

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

【问题讨论】:

  • 您可以查看客户端的 request.contentType 并尝试使用 application/json。

标签: c# rest wcf


【解决方案1】:

我想通了,感谢这个网站:https://www.codeproject.com/Questions/847265/WCF-How-to-overcome-urllength-restriction

原来REST url中每个参数的默认字符限制是260。所以你必须进入注册表并更改值 将 HEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters 中的 UrlSegmentMaxLength 设置为您需要的任何值的 REG_DWORD。

【讨论】:

  • 你到底为什么要在 URL 中传递 JSON?
猜你喜欢
  • 1970-01-01
  • 2012-04-27
  • 2015-11-24
  • 1970-01-01
  • 2011-09-29
  • 2014-01-11
  • 2013-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多