Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.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
Jquery 将JQGrid与wcfweb服务结合使用_Jquery_Wcf_Jqgrid - Fatal编程技术网

Jquery 将JQGrid与wcfweb服务结合使用

Jquery 将JQGrid与wcfweb服务结合使用,jquery,wcf,jqgrid,Jquery,Wcf,Jqgrid,我试图从运行于ASP.NET 2.0 WebForms应用程序中的WCF Web服务中获取JQGrid的数据。问题在于WCFWeb服务希望将数据格式化为JSON字符串,而JQGrid正在执行HTTP Post并将其作为内容类型传递:application/x-www-form-urlencoded 尽管对于返回到JQGrid的数据格式(它接受JSON、XML和其他格式)似乎有几个选项,但似乎没有办法改变它向web服务传递输入的方式 因此,我试图找出如何调整WCF服务,使其能够接受 Content

我试图从运行于ASP.NET 2.0 WebForms应用程序中的WCF Web服务中获取JQGrid的数据。问题在于WCFWeb服务希望将数据格式化为JSON字符串,而JQGrid正在执行HTTP Post并将其作为内容类型传递:application/x-www-form-urlencoded

尽管对于返回到JQGrid的数据格式(它接受JSON、XML和其他格式)似乎有几个选项,但似乎没有办法改变它向web服务传递输入的方式

因此,我试图找出如何调整WCF服务,使其能够接受

Content-Type: application/x-www-form-urlencoded
而不是

Content-Type:"application/json; charset=utf-8"
当我使用JQuery测试使用url编码发送Ajax请求时(如下所示):

电话失败了。使用Fiddler检查流量,我发现服务器返回的错误:

{"ExceptionDetail":{"HelpLink":null,"InnerException":null,"Message":
"The incoming message has an unexpected message format 'Raw'. The expected
message formats for the operation are 'Xml', 'Json'. This can be because 
a WebContentTypeMapper has not been configured on the binding. 
See the documentation of WebContentTypeMapper for more details."...
请注意,由于编码不同,此代码确实有效

$.ajax({
    type: "POST",
    url: "../Services/DocLookups.svc/DoWork",
    data: '{"FirstName":"Howard", "LastName":"Pinsley"}',
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(msg) {
        alert(msg.d);
    }
});
在服务器上,服务看起来像:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class DocLookups {
    // Add [WebGet] attribute to use HTTP GET

    [OperationContract]
    public string DoWork(string FirstName, string LastName) {
        return "Your name is " + LastName + ", " + FirstName;
    }
}
我的web.config包含:

<system.serviceModel>
  <behaviors>
   <endpointBehaviors>
    <behavior name="DocLookupsAspNetAjaxBehavior">
     <enableWebScript />
    </behavior>
   </endpointBehaviors>
  </behaviors>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  <services>
   <service name="DocLookups">
    <endpoint address="" behaviorConfiguration="DocLookupsAspNetAjaxBehavior"
     binding="webHttpBinding" contract="DocLookups" />
   </service>
  </services>
</system.serviceModel>


谢谢你的帮助

如果您无法控制ajax调用,我建议您创建和侦听器来覆盖内容类型头

public class ContentTypeOverrideInterceptor : RequestInterceptor
{
    public string ContentTypeOverride { get; set; }

    public ContentTypeOverrideInterceptor(string contentTypeOverride) : base(true)
    {
        this.ContentTypeOverride = contentTypeOverride;
    }

    public override void ProcessRequest(ref RequestContext requestContext)
    {
        if (requestContext == null || requestContext.RequestMessage == null)
        {
            return;
        }
        Message message = requestContext.RequestMessage;
        HttpRequestMessageProperty reqProp = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
        reqProp.Headers["Content-Type"] = ContentTypeOverride;
    }
}
然后,如果查看.svc文件,您将看到AppServiceHostFactory类将其更改为包含拦截器

class AppServiceHostFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        var host = new WebServiceHost2(serviceType, true, baseAddresses);
        host.Interceptors.Add(new ContentTypeOverrideInterceptor("application/json; charset=utf-8"));
        return host;
    }
}
那应该对你有用

更新 如评论中所述,上述方法适用于WCF REST初学者工具包。如果只使用常规WCF服务,则必须创建IOperationBehavior并将其附加到服务。下面是行为属性的代码

public class WebContentTypeAttribute : Attribute, IOperationBehavior, IDispatchMessageFormatter
{
    private IDispatchMessageFormatter innerFormatter;
    public string ContentTypeOverride { get; set; }

    public WebContentTypeAttribute(string contentTypeOverride)
    {
        this.ContentTypeOverride = contentTypeOverride;
    }


    // IOperationBehavior
    public void Validate(OperationDescription operationDescription)
    {

    }

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        innerFormatter = dispatchOperation.Formatter;
        dispatchOperation.Formatter = this;
    }

    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
    {

    }

    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
    {

    }

    // IDispatchMessageFormatter
    public void DeserializeRequest(Message message, object[] parameters)
    {
        if (message == null)
            return;

        if (string.IsNullOrEmpty(ContentTypeOverride))
            return;

        var httpRequest = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
        httpRequest.Headers["Content-Type"] = ContentTypeOverride;
    }

    public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
    {
        return innerFormatter.SerializeReply(messageVersion, parameters, result);
    }
}
您必须修改您的服务合同,使其看起来像这样

[OperationContract]
[WebContentType("application/json; charset=utf-8")]
public string DoWork(string FirstName, string LastName)
{
    return "Your name is " + LastName + ", " + FirstName;
}
链接 根据您的要求,这里有一些描述这些WCF扩展的链接


顺便说一句。这个拦截器可能更好,它松散地基于WCF REST Starter Kit示例中的XHttpMethodOverrideInterceptor。我在.svc文件中没有看到任何代码,后面的代码也没有提到工厂类。另外,我不清楚——您是否正在动态更改传入请求的内容类型(例如,从url编码更改为JSon?),如果是,什么是将传递的参数从一种格式转换为另一种格式。您是使用WCF REST Starter工具包还是仅使用WCF服务?这里要做的是在消息到达编码器之前拦截消息并覆盖其中的内容类型。感谢所有帮助。不,我没有使用WCF REST初学者工具包。也许我应该研究一下,因为我不熟悉它及其功能。我也会调查你的答案。你能告诉我在哪里更全面地讨论这项技术吗?再次感谢!您正在使用剩余的初学者工具包吗?如果是这样,我可能不得不将我的答案从RequestInterceptor修改为MessageInterceptor。我用WCF版本更新了我的答案。
[OperationContract]
[WebContentType("application/json; charset=utf-8")]
public string DoWork(string FirstName, string LastName)
{
    return "Your name is " + LastName + ", " + FirstName;
}