【问题标题】:WCF POST method get error 400 Bad RequestWCF POST 方法获取错误 400 错误请求
【发布时间】:2016-10-23 04:44:44
【问题描述】:

我正在使用 WCF POST 方法,一旦我将参数 POST 添加到服务,它会返回错误 400 Bad Request,如果我将参数留空,它可以访问我的服务。

这是我的界面:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
using System.IO;
namespace SampleArticle
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IRestService" in both code and config file together.
    [ServiceContract(Namespace="IRestService/JSONData")]
    public interface IRestService
    {

        [OperationContract]
        [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,UriTemplate = "authorize")]
        Stream authorize(Stream streamdata);

    }
}

这是我的 Web.config

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

  <appSettings>

    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />

  </system.web>

  <system.serviceModel>


    <services>
      <service name="SampleArticle.RestService" behaviorConfiguration="serviceBehavior">
        <endpoint address="" binding="webHttpBinding" contract="SampleArticle.IRestService" behaviorConfiguration="web"></endpoint>        
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>

        <behavior name="serviceBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>

      </serviceBehaviors>

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

    </behaviors>

    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>


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


 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
   <directoryBrowse enabled="true" />

  </system.webServer>

</configuration>

我正在使用 Msxml2.ServerXMLHTTP 进行 POST

Dim objXmlHttpMain , URL

URL="http://localhost/SampleArticle/RestService.svc/authorize" 

strJSONToSend = "{""acctId"": ""Test10001"","
strJSONToSend = strJSONToSend & """language"": 200,"
strJSONToSend = strJSONToSend & """Code"": ""Test"","
strJSONToSend = strJSONToSend & """token"": ""abcd123412341234"","
strJSONToSend = strJSONToSend & """serialNo"": ""20161020160455982841""}"

// if i set the parameter to empty i can access to the service
'strJSONToSend  = ""
Set objXmlHttpMain = CreateObject("Msxml2.ServerXMLHTTP") 
'on error resume next 
objXmlHttpMain.open "POST",URL, False 

// if i change the  "application/json" to "application/x-www-form-urlencoded" it works 
'objXmlHttpMain.setRequestHeader "Content-Type", "application/json"
objXmlHttpMain.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"

objXmlHttpMain.send strJSONToSend 


//check for output
S = objXmlHttpMain.responseText
response.write S

set objJSONDoc = nothing 
set objResult = nothing

服务器日志消息

“授权”操作(带有命名空间“IRestService/JSONData”的合同“IRestService”)的传入消息包含无法识别的 http 正文格式值“Json”。预期的正文格式值为“原始”。这可能是因为尚未在绑定上配置 WebContentTypeMapper。详情请参阅 WebContentTypeMapper 的文档。

如果我将内容类型“application/json”更改为“application/x-www-form-urlencoded” 它有效,但我需要 JSON 格式的数据。 有什么我缺少的设置吗?请指教。

【问题讨论】:

  • 您可能提出了错误的要求 :) - 您真的应该展示您如何调用服务。有关发布代码的指导,请参阅 minimal reproducible example
  • 你确定strJSONToSend的JSON格式正确吗?
  • 我猜是...有什么建议吗?
  • 是的,您的 JSON 是正确的,并且是:{"acctId": "Test10001","language": 200, "Code": "Test", "token": "abcd123412341234","serialNo": "20161020160455982841" }?
  • 更改authorize的返回类型,再次测试,只是为了测试。

标签: c# wcf


【解决方案1】:

我已经解决了添加自定义 WebContentTypeMapper 的问题。 这是我的示例编码:

创建新类以允许接收 RAW 类型的数据

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace SampleArticle
{
    public class MyWebContentTypeMapper : WebContentTypeMapper
    {
        public override WebContentFormat GetMessageFormatForContentType(string contentType)
        {

            return WebContentFormat.Raw;
        }
    }
}

Web.Config 为服务添加自定义绑定

<system.serviceModel>
    <services>
        <service name="SampleArticle.RestService" behaviorConfiguration="serviceBehavior">
            <endpoint address="" binding="customBinding" bindingConfiguration="RawReceiveCapable" contract="SampleArticle.IRestService" behaviorConfiguration="web"></endpoint>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="serviceBehavior">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
            <behavior name="">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="web">
                <webHttp/>
            </behavior>
        </endpointBehaviors>
    </behaviors>


    <bindings>
        <customBinding>
            <binding name="RawReceiveCapable">
                <webMessageEncoding webContentTypeMapperType="SampleArticle.MyWebContentTypeMapper, SampleArticle, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
                <httpTransport manualAddressing="true" maxReceivedMessageSize="524288000" transferMode="Streamed"/>
            </binding>
        </customBinding>
    </bindings>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>

这解决了我的问题,希望对其他人也有帮助。感谢帮助

【讨论】:

  • 干得好,正如你所看到的,我在我的一个 cmets 中说过,应该始终强制返回 Raw,因此必须实现自定义 WebContentTypeMapper
猜你喜欢
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 2018-05-09
相关资源
最近更新 更多