【问题标题】:Error 415 when posting JSON data to WCF Service将 JSON 数据发布到 WCF 服务时出现错误 415
【发布时间】:2023-03-21 13:09:01
【问题描述】:

我正在尝试将一些 JSON 数据发送到我在 c# 和 wcf 中创建的服务。在 Fiddler 中,我的 POST 请求如下

提琴手:

Request Header
User-Agent: Fiddler
Host: localhost
Content-Length: 29
Content-Type: application/json; charset=utf-8

Request Body
{sn:"2705", modelCode:1702 } 

下面是服务接口。它使用 WebInvoke 属性来管理 POST 请求

[ServiceContract]
public interface IProjectorService
{
    [WebInvoke(Method="POST", UriTemplate="projectors", RequestFormat=WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json )]
    [OperationContract]
    void RecordBreakdown(Record record);
}

服务接口的实现采用传入参数的变量,并使用 ado 将此数据发送到 SQL db。

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public partial class ProjectorService : IProjectorService
{

    public void RecordBreakdown(Record record)
    {
        //ado code to send data to db (ie do record.SerialNumber...
    }        
}

POCO 对象来表示多个参数

[DataContract]
public class Record
{      
    [DataMember]
    public string SerialNumber { get; set; }
    [DataMember]
    public int ModelCode { get; set; }
}

.svc 文件

<%@ ServiceHost Language="C#" Debug="true" Service="ProjectorService" CodeBehind="~/App_Code/ProjectorService.cs" %>

Web.config:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5"/>
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https"/>
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>

在 fiddler 中,当我单击“执行”时,收到错误 415“不支持的媒体类型”。我目前的想法是,在我的投影仪服务类中,也许我应该创建一个响应对象并将 200 代码发回?!

【问题讨论】:

    标签: c# json wcf rest


    【解决方案1】:

    要让 WCF 端点识别 [WebInvoke](或 [WebGet])注释,它需要定义为 WebHTTP 端点(又名 REST 端点)——这意味着使用 webHttpBindingwebHttp 端点行为.由于您没有在 web.config 中定义任何端点,因此它使用该方案的默认绑定,即 BasicHttpBinding。具有该绑定的端点仅响应 XML (SOAP) 请求,这就是您在发送 JSON 请求时收到该错误的原因。

    尝试替换 web.config 中的 &lt;system.serviceModel&gt; 部分,这应该可以根据需要定义端点:

      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
          </serviceBehaviors>
          <endpointBehaviors>
            <behavior name="Web">
              <webHttp/>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <services>
          <service name="ProjectorService">
            <endpoint address=""
                      behaviorConfiguration="Web"
                      binding="webHttpBinding"
                      contract="IProjectorService" />
          </service>
        </services>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
      </system.serviceModel>
    

    【讨论】:

    • 那行得通。我认为 Web 绑定是使用 svc 文件中的工厂方法自动生成的(无论如何我都没有包含)。除了这些更改之外,我还需要将 BodyStyle = WebMessageBodyStyle.Bare 添加到服务方法中,因为 JSON 数据没有包装在另一个对象中。
    【解决方案2】:

    问题很可能是您的服务方法需要 2 个参数。默认只能存在 1 个 body 参数。

    您可以通过 2 种方式解决此问题。 第一种方式: 将 BodyStyle = WebMessageBodyStyle.Wrapped 添加到您的 WebInvoke 属性中,如下所示:

    [WebInvoke(Method = "POST", UriTemplate = "projectors", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
    void RecordBreakdown(string sn, int modelCode);
    

    第二种方式:为 POST 数据创建一个类。例如,您可以为要作为 JSON 发布到服务的所有变量创建一个类。要从 JSON 创建类,您可以使用Json2CSharp(或在 VS2012 Update 2 中将 JSON 粘贴为类)。 以下 JSON

    {"sn":2705, "modelCode":1702 } 
    

    将产生以下类:

    public class Record
    {
        public string sn { get; set; }
        public int modelCode { get; set; }
    }
    

    之后你必须改变你的方法来接受这个类:

    void RecordBreakdown(string sn, int modelCode);
    

    到:

    void RecordBreakdown(Record record);
    

    之后,您现在应该可以将 JSON 发布到服务了。

    希望这会有所帮助!

    编辑: 从下面加入我的答案。

    再次查看您的配置文件后,它看起来也像是绑定错误配置。 WCF 的默认绑定是基本使用 SOAP 1.1 的“bassicHttpBinding”。

    由于您想使用 JSON 和 RESTFul 服务,您必须使用“webHttpBinding”。 Here is a link 是我们一直用于 RESTFul 服务的基本配置。当需要安全传输(例如:https)时,您可以将安全模式设置为传输。

    <security mode="Transport"></security>
    

    【讨论】:

    • 我已经尝试添加 BodyStyle = WebMessageBodyStyle.Wrapped 但它没有奏效。仍然收到 415 错误。我还删除了多个参数并根据您的建议创建了一个新类,我认为我更喜欢这种方式,所以我更新了问题以显示这些更改,但这也不起作用,我仍然看到错误 415。
    • 再次查看您的配置文件后,它看起来也像是绑定错误配置。 WCF 的默认绑定是基本使用 SOAP 1.1 的“bassicHttpBinding”。由于您想使用 JSON 和 RESTFul 服务,您将不得不使用“webHttpBinding”。我已经包含了一个基本配置的链接,我们一直在使用我们的 RESTFul 服务。 :) 信息:link
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-13
    • 2016-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多