Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将JSON数据发布到WCF服务时出现错误415_C#_Json_Wcf_Rest - Fatal编程技术网

C# 将JSON数据发布到WCF服务时出现错误415

C# 将JSON数据发布到WCF服务时出现错误415,c#,json,wcf,rest,C#,Json,Wcf,Rest,我正在尝试向我在c#和wcf中创建的服务发送一些JSON数据。在Fiddler中,我的职位要求如下 小提琴手: 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请求的 [S

我正在尝试向我在c#和wcf中创建的服务发送一些JSON数据。在Fiddler中,我的职位要求如下

小提琴手:

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代码发送回去

问题很可能是您的服务方法需要两个参数。默认情况下,只能存在一个主体参数

您可以通过两种方式解决此问题。 第一种方式: 添加BodyStyle=WebMessageBodyStyle。包装到WebInvoke属性,如下所示:

[WebInvoke(Method = "POST", UriTemplate = "projectors", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
void RecordBreakdown(string sn, int modelCode);
第二种方法:为POST数据创建一个类。例如,您可以为要作为JSON发布到服务的所有变量创建一个类。要从JSON创建类,可以使用(或将JSON粘贴为VS2012更新2中的类)。 下面是JSON

{"sn":2705, "modelCode":1702 } 
将生成以下类:

public class Record
{
    public string sn { get; set; }
    public int modelCode { get; set; }
}
之后,您必须更改方法以接受此类,如下所示:

void RecordBreakdown(string sn, int modelCode);
致:

之后,您现在应该能够将JSON发布到服务中

希望这有帮助

编辑: 把我下面的答案和这个联系起来


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

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

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

对于要识别
[WebInvoke]
(或
[WebGet]
)注释的WCF端点,需要将其定义为WebHTTP端点(又称REST端点)-这意味着使用
webHttpBinding
WebHTTP
端点行为。由于您没有在web.config中定义任何端点,因此它正在使用方案的默认绑定,即
BasicHttpBinding
。具有该绑定的端点只响应XML(SOAP)请求,这就是为什么在发送JSON请求时会出现该错误

尝试替换web.config中的
部分,这将根据需要定义端点:

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


我尝试添加BodyStyle=WebMessageBodyStyle.Wrapped,但没有成功。仍然有415个错误。我还删除了多个参数并根据您的建议创建了一个新类,我更喜欢这种方式,我想我已经更新了问题以显示这些更改,但这也不起作用,我仍然看到错误415。再次查看配置文件后,它看起来也像是绑定错误配置。WCF的默认绑定是“bassicHttpBinding”,它基本上使用SOAP 1.1。因为您想要使用JSON和RESTFul服务,所以必须使用“webHttpBinding”。我提供了一个链接,指向我们在RESTFul服务中始终使用的基本配置。:)信息:成功了。我认为web绑定是使用svc文件中的工厂方法自动生成的(我还没有包括它)。除了这些更改,我还需要将
BodyStyle=WebMessageBodyStyle.Bare
添加到服务方法中,因为JSON数据没有包装在另一个对象中。
  <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>