向使用json的RESTful WCF发送Post请求

7

我尝试过各种组合来使用jQuery发送POST请求到RESTful WCF。希望有人能够模拟并让它正常工作。代码在这里:http://pastebin.com/Ua97919C

我已经使用WCF工作了2年,但每次发送POST请求都让我很苦恼。

我已经努力让它正常工作了4天,看了至少35-40篇文章。

最终,这个请求将从iPhone发送到WCF。

当我用Fiddler检查时,错误大多是:“服务器遇到处理请求过程中的错误。异常消息是'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.'。请参阅服务器日志以获取更多详细信息。异常堆栈跟踪为:

System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
2个回答

4
在您的解决方案中添加一个名为Global.ascx的文件,并将代码替换为以下内容。
protected void Application_BeginRequest(object sender, EventArgs e)
{
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    }
}

还有一件事,改变dataType:'text'

$.ajax({
    type: "POST",
    url: "http://localhost:4638/Edulink.svc/SaveUserData",                        
    dataType: "text",
    contentType: "application/json",
    data:'{"EmailID":"praveen", "LevelID": 1}',         
    success:function(data, status) {             
        console.log(data); //gives 1                
    },
    error:function(request, status, error) {
        alert("o0ops");           
    }
});

不行,它会在jQuery.min.js处抛出错误。我之前也试过了。 - iMatoria
@iMatoria 如果你想要样例项目,请告诉我,我会上传它。 - Rafay
我尝试在Web和Service项目中添加Global文件。在Web项目中,它发送成功响应,但由于HttpContext.Current.Response.End()而不进入Service。在Service项目中,它没有任何影响。请上传示例项目到filefactory.com。 - iMatoria
是的,我确实收到了方法返回的 1,全局文件只需添加到 WCFPost.Service 项目中,在这里是我使用的带有服务的 ajax 调用 http://pastebin.com/2veXcN8Z - Rafay
我已将您的回答标记为答案,因为您让我发现这取决于您从哪里发起对WCF的请求。当我从jQuery发起请求时,由于某些安全原因,它选择为OPTIONS而不是POST。但当我从iPhone发起它时,它非常好用,这正是我想要的。感谢你。 - iMatoria
显示剩余6条评论

2

问题在于操作的 body 样式。你将其声明为

[WebInvoke(
        Method = "POST",
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        UriTemplate = "/SaveUserData")]
string SaveUserData(UserInfo userInfo);

这意味着请求必须用一个对象进行“包装”,并带有对象名称的成员。如果您发送以下请求,它应该可以工作。

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: url,
    data: '{"userInfo":{"EmailID":"praveen", "LevelID": 1}}',
    dataType: "json",
    processData: false,
    success: function (data, textStatus, jqXHR) {
        debugger;
    },
    error: function (jqXHR, textStatus, errorThrown) {
        debugger;
    }
});

另一个选择是更改操作的BodyStyle属性为Bare,这种情况下您原始的请求是正确的。

不管怎样都不行。你能下载这个示例并让它工作吗:http://www.filefactory.com/file/c0dd2ac/n/WCFPost.zip - iMatoria
你可以查看我在Pastebin上的示例,该示例类似于你的场景,并使你自己的功能正常工作。SVC文件:SVC:http://pastebin.com/aG7FNDb0。SVC.cs文件:SVC.CS:http://pastebin.com/vhqeBSV3。HTML文件:http://pastebin.com/fDiYzR3Q。Web.config文件:http://pastebin.com/j4yw1axb - carlosfigueira
感谢您的努力。但是,它仍然无法正常工作。我已经按照您所说的每一行代码都写了。 - iMatoria

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接