使用UriTemplate和POST数据从Javascript调用WCF服务

时间:2012-08-02 16:35:44

标签: json wcf jquery wcf-binding

我有一个当前为HTTP GET请求设置的WCF 4.0服务。我正在尝试修改它以便它使用POST,但保持向后兼容现有的GET URI。使用jQuery和JSON数据调用Web服务。因此,我的要求如下:

  • 匹配现有的GET URI,大概是使用WebInvoke属性的UriTemplate参数。
  • 从POST主体中的JSON数据中获取现有参数,可能是使用WebMessageBodyStyle.Wrapped和WebMessageFormat.Json以及WebInvoke属性。
  • 最好有办法从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函数允许我像在HTTP GET中一样在URI中传递它的参数。

  [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);
        }
    });
});

我可以通过从WebInvoke参数中删除UriTemplate="ToUpper?str={str}"并使用此javascript来将参数放在POST数据而不是URI中。它正确地返回“这是从POST”。

$(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数据的原始内容。但正如this blog post指出的那样,如果将内容类型设置为纯文本而不是JSON,则只能获取该流。我可以这样做并手动解析流,但我想我还需要手动检查URL以确定我是否有实际值或默认值。呸。

如果没有办法使用系统绑定/设置工作,我正在考虑尝试编写一个自定义绑定,它可以很好地从POST和URI中提取参数,并且还可以为您提供原始流当你使用JSON时。我花了几个小时试图弄清楚如何做到这一点,但我很难过!

有没有其他人解决过这个问题或有任何关于如何使其发挥作用的想法?我无法想象我是第一个尝试这样做的人,但是经过大量的搜索后我空手而归。

0 个答案:

没有答案