我有一个当前为 HTTP GET 请求设置的 WCF 4.0 服务。我正在尝试修改它以使其使用 POST,但保持与现有 GET URI 的向后兼容性。使用 jQuery 和 JSON 数据调用 Web 服务。因此,我的要求如下:
- 匹配现有的 GET URI,大概是使用 WebInvoke 属性的 UriTemplate 参数。
- 从 POST 正文中的 JSON 数据中获取现有参数,大概是通过使用带有 WebInvoke 属性的 WebMessageBodyStyle.Wrapped 和 WebMessageFormat.Json。
- 最好有办法从 POST 正文中提取大块数据,可能也包含在 JSON 对象中。
好吧,不碍事,这就是我到目前为止所得到的。我的小测试服务称为 AjaxService,它有一种方法称为 ToUpper。首先,我的 web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="WebApplication2.AjaxServiceAspNetAjaxBehavior">
<!--<enableWebScript />-->
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<remove scheme="http" />
<add scheme="http" binding="webHttpBinding" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="WebApplication2.AjaxService">
<endpoint address=""
behaviorConfiguration="WebApplication2.AjaxServiceAspNetAjaxBehavior"
binding="webHttpBinding"
contract="WebApplication2.AjaxService" />
</service>
</services>
</system.serviceModel>
</configuration>
我的 ToUpper 函数的以下版本允许我在 URI 中传递它的参数,就像 HTTP GET 一样。
[OperationContract]
[WebInvoke( UriTemplate="ToUpper?str={str}",
Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json)]
public string ToUpper(string str)
{
return str.ToUpper();
}
它在 Javascript 中的使用如下所示,并正确返回“这是来自 URI”。
$(document).ready(function () {
$.ajax({
type: "POST",
url: "AjaxService.svc/ToUpper?str=this%20is%20from%20the%20uri",
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log("result: " + JSON.stringify(data));
},
error: function (jqXHR, textStatus, errorThrown) {
console.log("error", jqXHR, textStatus, errorThrown);
}
});
});
UriTemplate="ToUpper?str={str}"
我可以通过从 WebInvoke 参数中删除并改用此 javascript 来将参数放入 POST 数据而不是 URI 。它正确返回“这是来自帖子”。
$(document).ready(function () {
$.ajax({
type: "POST",
url: "AjaxService.svc/ToUpper",
data: JSON.stringify({str:"This is from the POST"}),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log("result: " + JSON.stringify(data));
},
error: function (jqXHR, textStatus, errorThrown) {
console.log("error", jqXHR, textStatus, errorThrown);
}
});
});
我希望如果我离开UriTemplate="ToUpper?str={str}"
原地并使用上面的 javascript,将 str 参数从 POST 数据而不是 URI 中提取出来就足够聪明了。不幸的是,它只是给了我一个错误 400。有没有办法让它工作?
我尝试的另一件事是使用可选的 Stream 参数来获取 POST 数据的原始内容。但正如这篇博文指出的那样,只有将内容类型设置为纯文本而不是 JSON,才能获取该流。我可以这样做并手动解析流,但我认为我还需要手动检查 URL 以确定我是否获得了真实值或默认值。呸。
如果无法使用系统绑定/设置进行此操作,我正在考虑尝试编写一个自定义绑定,该绑定可以智能地从 POST 和 URI 中提取参数,并且即使在你“重新使用 JSON。我花了几个小时试图弄清楚如何做到这一点,但我很难过!
有没有其他人解决过这个问题或对如何使其工作有任何想法?我无法想象我是第一个尝试这样做的人,但经过大量搜索后我空手而归。