【发布时间】:2014-04-16 14:51:49
【问题描述】:
我正在尝试构建一个 WCF 服务,它接受并返回 json 格式的数据并在 ajax 调用中使用它。我遇到的问题是,当我尝试从 javascript 调用 WCF 服务时,我收到 405(不允许的方法)错误。似乎网页调用了服务器上的 options 方法(OPTIONS localhost:49572/Service1.svc/testmethod HTTP/1.1),服务器以 405 状态码对其进行响应。
下面是我的服务定义
namespace JsonAjaxService
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[System.ServiceModel.Web.WebInvoke(
Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "testmethod")]
CompositeType GetDataUsingDataContract(CompositeType composite);
}
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
}
这里是 Web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1"/>
</system.web>
<system.serviceModel>
<services>
<service name="JsonAjaxService.Service1" behaviorConfiguration="ServiceBehaviour">
<endpoint address ="" binding="webHttpBinding" contract="JsonAjaxService.IService1" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
最后是我用来调用此服务的代码
function test() {
var json = '{"StringValue":"test","BoolValue":"false"}';
$.ajax(
{
type: "POST",
processData: false,
contentType: "application/json",
url: "http://localhost:49572/Service1.svc/testmethod",
data: json,
dataType: "json",
success: function (data) { alert(data); },
error: function (data) { alert('error')); }
});
【问题讨论】:
-
使用提琴手发出请求,检查它是否有效并从响应中发布标头。链接:telerik.com/download/fiddler
-
似乎网页调用了服务器上的options方法(OPTIONS localhost:49572/Service1.svc/testmethod HTTP/1.1),服务器以405状态码响应。
-
很合理,因为你没有这种方法。如果是跨域调用(但好像不是),听说需要使用dataType:"jsonp"。但是如果你捕捉到一个 Option 调用,那肯定是 JSON 有问题。
-
使用 JSONP 作为数据类型解决了这个问题,但提出了另一个问题。网页使用 get 执行查询,当 wcf 仅在有 compostitetype 作为服务方法参数时才接受 POST。
-
是的,真的很奇怪,您的要求似乎是正确的。不幸的是,我无法解决这个问题,因为我对 JSON 没有太多经验。
标签: c# javascript json wcf