gpt4 book ai didi

jquery - 将 JQGrid 与 WCF Web 服务结合使用

转载 作者:行者123 更新时间:2023-12-01 00:13:01 27 4
gpt4 key购买 nike

我正在尝试从我的 ASP.NET 2.0 WebForms 应用程序中运行的 WCF Web 服务获取 JQGrid 的数据。问题在于 WCF Web 服务期望数据格式化为 JSON 字符串,而 JQGrid 正在执行 HTTP Post 并将其作为 Content-Type: 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 请求时(如下所示):

$.ajax({
type: "POST",
url: "../Services/DocLookups.svc/DoWork",
data: 'FirstName=Howard&LastName=Pinsley',
contentType: "Content-Type: application/x-www-form-urlencoded",
dataType: "json",
success: function(msg) {
alert(msg.d);
}
});

调用失败。使用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 调用,我建议您创建拦截器来覆盖 Content-Type header 。

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

您必须修改您的服务契约(Contract),使其看起来像这样

[OperationContract]
[WebContentType("application/json; charset=utf-8")]
public string DoWork(string FirstName, string LastName)
{
return "Your name is " + LastName + ", " + FirstName;
}

链接

根据您的要求,这里有一些描述这些 WCF 扩展的链接

关于jquery - 将 JQGrid 与 WCF Web 服务结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/538891/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com