Jquery 将JQGrid与wcfweb服务结合使用
我试图从运行于ASP.NET 2.0 WebForms应用程序中的WCF Web服务中获取JQGrid的数据。问题在于WCFWeb服务希望将数据格式化为JSON字符串,而JQGrid正在执行HTTP Post并将其作为内容类型传递:application/x-www-form-urlencoded 尽管对于返回到JQGrid的数据格式(它接受JSON、XML和其他格式)似乎有几个选项,但似乎没有办法改变它向web服务传递输入的方式 因此,我试图找出如何调整WCF服务,使其能够接受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
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扩展的链接
[OperationContract]
[WebContentType("application/json; charset=utf-8")]
public string DoWork(string FirstName, string LastName)
{
return "Your name is " + LastName + ", " + FirstName;
}