Asp.net mvc 如何创建ASP.NET MVC控制器,从查询字符串接受无限量的参数
URL示例 http//host/url/unlimited/index?first=value1&second=value2…&anyvalidname=somevalue 我希望有一个操作预先接受未知数量的具有未知名称的参数。大概是这样的:Asp.net mvc 如何创建ASP.NET MVC控制器,从查询字符串接受无限量的参数,asp.net-mvc,Asp.net Mvc,URL示例 http//host/url/unlimited/index?first=value1&second=value2…&anyvalidname=somevalue 我希望有一个操作预先接受未知数量的具有未知名称的参数。大概是这样的: public class UnlimitedController : Controller { public ActionResult Index(object queryParams) { } //or even b
public class UnlimitedController : Controller
{
public ActionResult Index(object queryParams)
{
}
//or even better
public ActionResult Index(Dictionary<string, object> queryParams)
{
}
}
public类UnlimitedController:Controller
{
公共操作结果索引(对象查询参数)
{
}
//甚至更好
公共操作结果索引(字典查询参数)
{
}
}
为什么不将所需的所有内容保存在一个查询字符串参数中,并在服务器端作为字符串获取然后自己解析字符串,得到想要的内容
类似这样的东西
http://example.com?a=someVar&b=var1_value1__var2_value2__var3_value3
然后在服务器端,只需拆分字符串并获取变量和所有值
如果你不想要这个,那么你能做的就是
只需通过url调用控制器并手动进入
请求.QueryString[]
集合,您将获得所有变量和值您的控制器代码可能如下
public ActionResult MultipleParam(int a, int b, int c)
{
ViewData["Output"] = a + b + c;
return View();
}
Global.asax.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Parameter",
"{controller}/{action}/{a}/{b}/{c}",
new { controller = "Home", action = "MultipleParam", a = 0, b = 0, c = 0 }
);
}
如果路由为{controller}/{action}/{id}/{page},则/Home/MultipleParam/101/1?showComments=true,则检索机制为:
public ActionResult MultipleParam(string id /* = "101" */, int page /* = 1 */, bool showComments /* = true */) { }
在HomeController.cs中
public ActionResult Test()
{
Dictionary<string, string> data = new Dictionary<string, string>();
foreach (string index in Request.QueryString.AllKeys)
{
data.Add(index, Request.QueryString[index]);
}
StringBuilder sb = new StringBuilder();
foreach (var element in data)
{
sb.Append(element.Key + ": " + element.Value + "<br />");
}
ViewBag.Data = sb.ToString();
return View();
}
您可以创建一个自定义模型绑定器,将查询字符串转换为字典 自定义模型活页夹
public class CustomModelBinder: IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var querystrings = controllerContext.HttpContext.Request.QueryString;
return querystrings.Cast<string>()
.Select(s => new { Key = s, Value = querystrings[s] })
.ToDictionary(p => p.Key, p => p.Value);
}
}
公共类CustomModelBinder:IModelBinder
{
公共对象绑定模型(ControllerContext ControllerContext,ModelBindingContext bindingContext)
{
var QueryString=controllerContext.HttpContext.Request.QueryString;
返回querystrings.Cast()
.Select(s=>new{Key=s,Value=querystring[s]})
.ToDictionary(p=>p.Key,p=>p.Value);
}
}
行动
public ActionResult Index([ModelBinder(typeof(CustomModelBinder))]
Dictionary<string, string> queryParams)
{
}
public ActionResult索引([ModelBinder(typeof(CustomModelBinder))]
字典查询参数)
{
}
另一种可能的解决方案是创建自定义路线
public class ParamsEnabledRoute : RouteBase
{
private Route route;
public ParamsEnabledRoute(string url)
{
route = new Route(url, new MvcRouteHandler());
}
public override RouteData GetRouteData(HttpContextBase context)
{
var data = route.GetRouteData(context);
if (data != null)
{
var paramName = (string)data.Values["paramname"] ?? "parameters";
var parameters = context.Request.QueryString.AllKeys.ToDictionary(key => key, key => context.Request.QueryString[key]);
data.Values.Add(paramName, parameters);
return data;
}
return null;
}
public override VirtualPathData GetVirtualPath(RequestContext context, RouteValueDictionary rvd)
{
return route.GetVirtualPath(context, rvd);
}
}
用法:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(new ParamsEnabledRoute("ParamsEnabled/{controller}/{action}/{paramname}"));
}
控制器:
public class HomeController : Controller
{
public ActionResult Test(Dictionary<string, string> parameters)
{
}
}
路由属性:
public class RouteDataValueAttribute : ActionMethodSelectorAttribute
{
private readonly RouteDataValueAttributeEnum type;
public RouteDataValueAttribute(string valueName)
: this(valueName, RouteDataValueAttributeEnum.Required)
{
}
public RouteDataValueAttribute(string valueName, RouteDataValueAttributeEnum type)
{
this.type = type;
ValueName = valueName;
}
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
if (type == RouteDataValueAttributeEnum.Forbidden)
{
return controllerContext.RouteData.Values[ValueName] == null;
}
if (type == RouteDataValueAttributeEnum.Required)
{
return controllerContext.RouteData.Values[ValueName] != null;
}
return false;
}
public string ValueName { get; private set; }
}
public enum RouteDataValueAttributeEnum
{
Required,
Forbidden
}
只需使用收集您的查询字符串
using System.Web;
public class UnlimitedController : Controller
{
public ActionResult Index(object queryParams)
{
}
//or even better
public ActionResult Index()
{
NameValueCollection queryString = HttpContext.Request.QueryString;
// Access queryString in the same manner you would any Collection, including a Dictionary.
}
}
问题是“如何创建ASP.NET MVC控制器,从查询字符串接受无限量的参数”?任何控制器都会接受无限数量的参数作为
NamedValueCollection
我想遵循传统的查询字符串标准,而不是发明自己的。这可能是一种解决方法。但是我正在寻找更好的解决方案,我需要获得名称和值。我提出了另一个基于自定义路由的实现。但对我来说,这似乎是一个有效的解决方案,所以我会接受它。虽然我从来没有测试过,你为什么还要走这么远HttpContext.Request.QueryString
已经是一个NameValueCollection
,这意味着它可以像字典一样操作。可能不需要额外铸造。
http://localhost/ParamsEnabled/Home/Test/parameteres?param1=value1¶m2=value2
public class RouteDataValueAttribute : ActionMethodSelectorAttribute
{
private readonly RouteDataValueAttributeEnum type;
public RouteDataValueAttribute(string valueName)
: this(valueName, RouteDataValueAttributeEnum.Required)
{
}
public RouteDataValueAttribute(string valueName, RouteDataValueAttributeEnum type)
{
this.type = type;
ValueName = valueName;
}
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
if (type == RouteDataValueAttributeEnum.Forbidden)
{
return controllerContext.RouteData.Values[ValueName] == null;
}
if (type == RouteDataValueAttributeEnum.Required)
{
return controllerContext.RouteData.Values[ValueName] != null;
}
return false;
}
public string ValueName { get; private set; }
}
public enum RouteDataValueAttributeEnum
{
Required,
Forbidden
}
using System.Web;
public class UnlimitedController : Controller
{
public ActionResult Index(object queryParams)
{
}
//or even better
public ActionResult Index()
{
NameValueCollection queryString = HttpContext.Request.QueryString;
// Access queryString in the same manner you would any Collection, including a Dictionary.
}
}