Reputation: 7012
I have the following url:
http://localhost:58124/Tag/GetData?filter(Tag)=contains(112)&filter(Process)=contains(112)&page=0&pageSize=30
If I declare my action result like this
public ActionResult GetData(int page, int pageSize)
I get the values of page and pageSize populated from the parameters. How can I get the filter(Tag) and filter(Process) values from the parameters?
EDIT: The string could have n number of these filter(name) parameters. Is there a way to gather them all or do I need to get them individually?
Upvotes: 1
Views: 506
Reputation: 1039398
Seems like a good candidate for a custom model binder:
public class FilterViewModel
{
public string Key { get; set; }
public string Value { get; set; }
}
public class FilterViewModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var filterParamRegex = new Regex(bindingContext.ModelName + @"\((?<key>.+)\)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
return
(from key in controllerContext.HttpContext.Request.Params.AllKeys
let match = filterParamRegex.Match(key)
where match.Success
select new FilterViewModel
{
Key = match.Groups["key"].Value,
Value = controllerContext.HttpContext.Request[key]
}).ToArray();
}
}
which will be registered in Application_Start
:
ModelBinders.Binders.Add(typeof(FilterViewModel[]), new FilterViewModelBinder());
and then:
public ActionResult GetData(FilterViewModel[] filter, int page, int pageSize)
{
...
}
The benefit of the custom model binder is that it does exactly what it name suggests: custom model binding since your query string parameters do not follow standard conventions used by the default model binder. In addition to that your controller action is clean and simple and it doesn't need to rely on some ugly plumbing code which obviously is not the responsibility of controller actions.
Upvotes: 0
Reputation: 4589
One way of doing it is filtering out the parameters starting with "filter" and iterate on the result. In the foreach-loop you can put them in a list or something, depending on how you plan to use them. I'm useing System.Linq for convenience:
using System.Diagnostics;
using System.Web.Mvc;
using System.Linq;
namespace ImgGen.Controllers
{
public class TagController : Controller
{
public ActionResult GetData(int page, int pageSize)
{
var filters = Request.QueryString.AllKeys.ToList().Where(key => key.StartsWith("filter"));
foreach (var filter in filters)
{
var value = Request.QueryString.GetValues(filter)[0];
Debug.Print(filter + " = " + value);
}
return View();
}
}
}
Hope this helps.
Upvotes: 0
Reputation: 32447
You can access the QueryString property of HttpRequestBase class through Request property.
public ActionResult GetData(int page, int pageSize)
{
var queryString = Request.QueryString;
var filter = queryString["filter(Tag)"];
///
}
Upvotes: 1