问题
I'm passed a list of parameters. Such as "Name", "Id", "Type". There will be an many of these in url, like so:
"Name=blah1,Id=231,Type=blah1;Name=blah2,Id=2221,Type=blah1;Name=blah3,Id=45411,Type=blah3;"
I wonder if there is a way to map these query parameters to a List of objects. So, I can create an object:
MyTestObject {Name;Id;Type} and can say in my controller
Index(IList<MyTestObject> params)
params will be filled in with data from query string.
Something that is similar to http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
回答1:
Yes, ASP.NET MVC could automatically bind collections to action params, but you need to pass your params as a from values, moreover, it is looks like to many params you going pass in query string. Have look at this one http://weblogs.asp.net/nmarun/archive/2010/03/13/asp-net-mvc-2-model-binding-for-a-collection.aspx
Basically what you need to do:
1) Create your class which would contain your params
public class MyParam
{
public int Id {get; set;}
public string Name {get; set;}
//do all the rest
}
2) Create model which you would pass to your view
public class MyViewModel
{
IList<MyParam> MyParams {get; set;}
}
3) Create your collection in your [HttpGet]
action and pass that to your view:
[HttpGet]
public virtual ActionResult Index()
{
MyViewModel model = new MyViewModel();
model.MyParams = CreateMyParamsCollection();
return View(model);
}
4) Iterate your collection in the view
@model MyViewModel
@{int index = 0;}
@foreach (MyParam detail in Model.MyParams)
{
@Html.TextBox("MyParams[" + index.ToString() + "].Id", detail.Id)
@Html.TextBox("MyParams[" + index.ToString() + "].Name", detail.Name)
index++;
}
5) Than on your [HttpPost]
action you may catch your params in collection
[HttpPost]
public virtual ActionResult Index(MyViewModel model)
or
[HttpPost]
public virtual ActionResult Index(IList<MyParam> model)
P.S
Moreover, if you want to get all your form params in controller you may simple go like that:
[HttpPost]
public virtual ActionResult Index(FormCollection form)
回答2:
You can you a values provider, and it will populate values from the querystring into a single object. This is what you would do if you're not going to create a View Model.
Transform the QueryString into a FormCollection via:
var GetCollection = new FormCollection( Request.QueryString );
回答3:
You could create a custom model binder, that works off the Request.QueryString
collection, rather than the regular FormCollection
.
E.g:
public class MyTestObjectModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var qs = controllerContext.HttpContext.Request.QueryString;
return new MyTestObject
{
Name = qs["Name"],
Id = qs["Id"],
// etc, etc
};
}
}
Then setup your [HttpGet]
action accordingly:
[HttpGet]
public ActionResult Index([ModelBinder(typeof(MyTestObjectModelBinder))]MyTestObject m) {
}
You could also register it globally if you like, e.g on Application_Start()
:
ModelBinders.Binders.Add(typeof(MyTestObject), new MyTestObjectModelBinder());
Then you just need the model on your action:
[HttpGet]
public ActionResult Index(MyTestObject m) {
}
Having said all of this, if you've got this many parameters, one must ask where do these parameters come from? Most likely a form on another page.
In which case, this should be a [HttpPost]
action, with the parameters in the form collection, then the regular MVC model binding will take care of the above code for you.
回答4:
I actually followed advice in the article by Mr. Haack I created a class with all of the parameters as public properties. Then I had a view take a list of objects of that type. If the query parameter names follow a certain pattern (prepended by index) then I get a list of my object automatically populated and I don't have to do any manual parsing at all. This is the simplest solution for me.
Example:
query param object:
public class QueryParams
{
public string Id,
public string Name,
public string Type
}
in controller method:
public ActionResult Index(IList<QueryParams> queryData)
then I make sure that query string is formated in the following way(prepended by index):
http://localhost/myapp/?[0].id=123&[0].Name=blah&[0].Type=Person&[1].Id=345&[1].Name=example&[1].Type=Stuff
In my controller, queryData list parameter will contain two objects populated with correct data.
回答5:
On a related note, I was looking for a way to enumerate through the QueryString name-value collection, and this is what I came up with:
var qry =HttpContext.Request.QueryString;
if (qry.HasKeys())
{
foreach (var key in qry)
{
if(key != null)
var str= String.Format("Key:{0}, value:{1} ", key, qry.Get(key.ToString()));
}
}
This code will give you all the names and their values in the QueryString.
来源:https://stackoverflow.com/questions/6739211/asp-net-mvc-get-list-of-objects-from-query-string