Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC - get list of objects from query string

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

like image 480
dev.e.loper Avatar asked Jul 18 '11 20:07

dev.e.loper


4 Answers

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.

like image 80
dev.e.loper Avatar answered Nov 20 '22 20:11

dev.e.loper


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 );
like image 32
Lucent Fox Avatar answered Nov 20 '22 19:11

Lucent Fox


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.

like image 3
RPM1984 Avatar answered Nov 20 '22 19:11

RPM1984


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)
like image 1
angularrocks.com Avatar answered Nov 20 '22 18:11

angularrocks.com