jQuery 将复杂对象传递到 WCF 休息服务中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2062053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing complex objects into a WCF Rest Service
提问by Brandon Michael Hunter
I have an Operation Contract that accepts a complex object and I'm calling the operation through jQuery. How do I pass in a complex type object like that using jQuery. Below is the operation signature:
我有一个接受复杂对象的操作合同,我正在通过 jQuery 调用该操作。如何使用 jQuery 传递像这样的复杂类型对象。下面是操作签名:
public Resolution CreateNewResolution(Resolution NewResolution);
I need to pass in a Resolution object on the client, but I don't know how to do something like using jQuery. Any help?
我需要在客户端传递一个 Resolution 对象,但我不知道如何使用 jQuery 之类的东西。有什么帮助吗?
Thank You
谢谢你
回答by Cheeso
See Denny's postfor a start, although I don't agree with his use of GET, and passing JSON in the querystring for complex params. That seems really wrong.
请参阅Denny 的帖子作为开始,尽管我不同意他使用 GET,并在查询字符串中为复杂参数传递 JSON。这似乎真的错了。
The param you use for data
is the json representation of whatever your Resolution type is. For example, suppose the type and operation is defined like this on the server side:
您使用的参数data
是您的分辨率类型的 json 表示。例如,假设类型和操作在服务器端是这样定义的:
[DataContract( Namespace = "urn:brandon.michael.hunter/ws/2010/01",
Name = "Resolution" )]
public class Resolution
{
[DataMember( IsRequired = true, Name = "Name" )]
public string Name { get; set; }
[DataMember( IsRequired = true, Name = "Rank" )]
public int Rank { get; set; }
[DataMember( IsRequired = true, Name = "SerialNumber" )]
public int SerialNumber { get; set; }
[DataMember( IsRequired = false, Name = "Id" )]
public int Id { get; set; }
}
[OperationContract]
[WebInvoke(Method = "PUT",
RequestFormat=WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "new")]
public Resolution CreateNewResolution(Resolution r)
{
// your logic here
r.Id = System.Guid.NewGuid();
return r;
}
Then, in Javascript, the code you use might look like this:
然后,在 Javascript 中,您使用的代码可能如下所示:
var resolution = {r: { Name : "Fred", Rank : 2, SerialNumber : 17268 }};
// convert object to JSON string (See http://jollytoad.googlepages.com/json.js)
var objectAsJson = $.toJSON(resolution);
// result is a string: '{"Name":"Fred","Rank":"2","SerialNumber":"17268"}'
$.ajax({
type : "PUT", // must match Method in WebInvoke
contentType : "application/json",
url : "Service.svc/new", // must match UriTemplate in WebInvoke
data : objectAsJson,
dataFilter : function (data, type) {
// convert from "\/Date(nnnn)\/" to "new Date(nnnn)"
return data.replace(/"\\/(Date\([0-9-]+\))\\/"/gi, 'new ');
},
processData : false, // do not convert outbound data to string (already done)
success : function(msg){ ... },
error : function(xhr, textStatus, errorThrown){ ... }
});
Notes:
笔记:
- You need to have the name of the variable (r) to be the first object in the JSON that is being passed, at least with WCF 4. When I used the previous example, it did not work until I put in the name of the variable at the beginning.
- For passing complex objects in JSON, use PUT or POST as the type (HTTP Method) of the request
- you need to convert the complex object to a JSON string. There's a nice, tiny jquery plugin to do this. Dennyprovides his own implementation.
- I found that if I use
processData=true
, then the resulting string sent to the service is in querystring format, not in JSON. Not what I want for passing complex objects. So I set it to false. Using true would be fine for simpler non-JSON requests where you're doing WebGet, and all the params are in the query string. - the dataFilter allows for correct deserialization of DateTime objects
- the
msg
param passed to the success callback contains the returned json. - You may want to use a URL rewriter to hide that .svc tag in the request URL
- in this case, the WCF service uses the webHttp behavior, not enableWebScript. The latter dynamically generates Javascript proxies to invoke the service, but the way you asked the question, makes it seem like you don't want that.
- 您需要将变量 (r) 的名称作为正在传递的 JSON 中的第一个对象,至少在 WCF 4 中是这样。当我使用前面的示例时,直到我输入开头的变量。
- 对于在 JSON 中传递复杂对象,请使用 PUT 或 POST 作为请求的类型(HTTP 方法)
- 您需要将复杂对象转换为 JSON 字符串。有一个不错的小型 jquery 插件可以做到这一点。 Denny提供了他自己的实现。
- 我发现如果我使用
processData=true
,那么发送到服务的结果字符串是查询字符串格式,而不是 JSON。不是我想要传递复杂对象的东西。所以我把它设置为false。对于正在执行 WebGet 且所有参数都在查询字符串中的更简单的非 JSON 请求,使用 true 会很好。 - dataFilter 允许正确反序列化 DateTime 对象
msg
传递给成功回调的参数包含返回的 json。- 您可能希望使用 URL 重写器来隐藏请求 URL 中的 .svc 标记
- 在这种情况下,WCF 服务使用 webHttp 行为,而不是 enableWebScript。后者动态生成 Javascript 代理来调用服务,但是您提出问题的方式使您似乎不想要那样。
回答by goodguys_activate
Check out Gil Fink's blog regarding Combining WCF Data Services, JSONP and jQuery
查看 Gil Fink 的关于结合 WCF 数据服务、JSONP 和 jQuery 的博客
During Mike Flasko's sessionat MIX11, he showed how to create a JSONP aware WCF Data Service with a JSONPSupportBehavior attribute that is available for downloadfrom MSDN code gallery (and is supposed to be a part of Microsoft.Data.Services.Extensions namespace). In this post I'll show a simple example that uses the attribute and jQuery in order to make a JSONP cross domain call for a WCF Data Service.
在 Mike Flasko 在 MIX11的会议期间,他展示了如何创建具有 JSONPSupportBehavior 属性的 JSONP 感知 WCF 数据服务,该属性可从 MSDN 代码库下载(并且应该是 Microsoft.Data.Services.Extensions 命名空间的一部分)。在这篇文章中,我将展示一个简单的示例,该示例使用属性和 jQuery 来为 WCF 数据服务进行 JSONP 跨域调用。
Setting up the Environment
设置环境
First I started by creating two different ASP.NET web applications. The first application includes the calling page and the second includes the WCF Data Service. Then, I created in the second web application an Entity Framework model and the WCF Data Service from that model. I also added the JSONPSupportBehavior.cs class that exists in the linkI supplied earlier. The class includes the implementation of JSONPSupportBehavior which implements the WCF IDispatchMessageInspector interface. Also it includes the JSONPSupportBehaviorAttribute which I use in my code. The code is simple and looks like:
首先,我创建了两个不同的 ASP.NET Web 应用程序。第一个应用程序包括调用页面,第二个应用程序包括 WCF 数据服务。然后,我在第二个 Web 应用程序中创建了一个实体框架模型和来自该模型的 WCF 数据服务。我还添加了存在于我之前提供的链接中的 JSONPSupportBehavior.cs 类。该类包括实现 WCF IDispatchMessageInspector 接口的 JSONPSupportBehavior 的实现。它还包括我在代码中使用的 JSONPSupportBehaviorAttribute。代码很简单,看起来像:
[JSONPSupportBehavior]
public class SchoolDataService : DataService<SchoolEntities>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
Making the JSONP Call
进行 JSONP 调用
In the second web application I've created a web form that will hold the JSONP call example. Here is the code that makes the call:
在第二个 Web 应用程序中,我创建了一个 Web 表单,用于保存 JSONP 调用示例。这是进行调用的代码:
<!DOCTYPE html>
<html>
<head runat="server">
<title>JSONP Call</title>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.js" type="text/javascript"></script>
</head>
<body>
<form id="form1" runat="server">
<output id="result">
</output>
</form>
<script type="text/javascript">
$.getJSON('http://localhost:23330/SchoolDataService.svc/Courses?$format=json&$callback=?',
function (response) {
$.each(response.d, function (index, value) {
var div = document.createElement('div');
div.innerHTML = value.Title;
$('#result').append(div);
})
});
</script>
</body>
</html>
Lets explore the web form code: At first I use Microsoft CDN in order to retrieve the jQuery library. Then, I've created a HTML5 output element in order to append to it the output of the call. In the main script I use jQuery's getJSON function which is calling the WCF Data Service. Pay attention that in order to get a JSON response from the WCF Data Service you need to use the $format=json query string parameter. After I retrieve the data I iterate and create a div element for each course title that was retrieved. This is done in the success function that I wired in the getJSON function call. Here is the output of running the code:
让我们探索 Web 表单代码: 首先,我使用 Microsoft CDN 来检索 jQuery 库。然后,我创建了一个 HTML5 输出元素,以便将调用的输出附加到它。在主脚本中,我使用调用 WCF 数据服务的 jQuery 的 getJSON 函数。请注意,为了从 WCF 数据服务获得 JSON 响应,您需要使用 $format=json 查询字符串参数。检索数据后,我迭代并为检索到的每个课程标题创建一个 div 元素。这是在我在 getJSON 函数调用中连接的成功函数中完成的。这是运行代码的输出:
Summary
概括
In the post I supplied a simple example of making a JSONP call to a WCF Data Service using jQuery. This sort of solution can help you to consume WCF Data Services that exists in other domains from your client side. In a follow up post I'll show the same example using the new datajslibrary
在帖子中,我提供了一个使用 jQuery 对 WCF 数据服务进行 JSONP 调用的简单示例。这种解决方案可以帮助您从客户端使用其他域中存在的 WCF 数据服务。在后续文章中,我将使用新的datajs库展示相同的示例