Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
422 views
in Technique[技术] by (71.8m points)

jquery - Passing complex objects into a WCF Rest Service

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:

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?

Thank You

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

See Denny's post for 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.


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:

[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:

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 $1');
  },
  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. Denny provides 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...