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
182 views
in Technique[技术] by (71.8m points)

c# - Passing complex type containing array of complex types to Web API

Extending on from this question, I'm trying to pass a complex object containing a collection of complex objects to an ASP.NET Web API controller action method, but I'm having trouble finding the correct format to use for my input object in the request. Continuing the example from Christopher Johnson's question (and removing some fields for simplicty), if I change his PhoneRequest object to contain a collection of phone numbers...

public class PhoneRequest
{
    public string[] PhoneNumbers { get; set; }
    public string State { get; set; }
}

...and I either pass the parameter as a URL encoded query string:

/api/phonenumber?id[0][State]=UT&id[0][PhoneNumbers][0]=555-1234567

...or POST it as a html form encoded (Content-Type: application/x-www-form-urlencoded) request body:

[0][State]=UT&[0][PhoneNumbers][0]=555-1234567

...then everything works great. But If I change PhoneNumbers from a collection of strings to a collection of a new PhoneNumber type...

public class PhoneRequest
{
    public PhoneNumber[] PhoneNumbers { get; set; }
    public string State { get; set; }
}
public class PhoneNumber
{
    string AreaCode { get; set; }
    string Number { get; set; }
}

...and I pass the object in what appears to me to be the logical way, given the previous result...

id[0][State]=UT&id[0][PhoneNumbers][0][AreaCode]=555&id[0][PhoneNumbers][0][Number]=1234567

...or again as a html form post body...

[0][State]=UT&[0][PhoneNumbers][0][AreaCode]=555&[0][PhoneNumbers][0][Number]=1234567

...then it still makes an attempt to bind it, and gets into my action method, but the model only contains State, and the phone number is this weird ComplexUriAndFormObject thing. Here's a copy-paste from my debugger Watch:

phoneRequest    {ComplexUriAndFormObject.Models.PhoneRequest[1]}
    [0] {ComplexUriAndFormObject.Models.PhoneRequest}
        PhoneNumbers    {ComplexUriAndFormObject.Models.PhoneNumber[1]}
        [0] {ComplexUriAndFormObject.Models.PhoneNumber}
            AreaCode    null
            Number  null
        State   "UT"

Is there some way to specify this object correctly using this format? Or have I exceeded the limit of what ASP.NET Web API's built in model binders are able to do?

Note: Please don't say "just use POST" or "just use JSON/XML/Whatever as your Content-Type"... If I was able to do that, I would.

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

Until now, no built-in Web API model binders including derived FromUri and FromBody attributes support passing a complex object that contains any property of non-primitive class types (excluding the System.String) with query strings. I had the similar issues and have created a unique and advanced custom model binder, the FieldValueModelBinder class, to work on a target object hierarchy having generic list or array collections. I can use the pure query string type of source data without imbedding any JSON or XML structure into it. The model binder can be used as easy as the FromUri and FromBody attributes. It also works effectively for transferring query string data in both URI and request body.

Please read my article and download source code I have just posted using this link. You can also run the test app from the download source for your input string, model, and results. I hope that this is the right solution you need.


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

...