4

URL 示例 http_//host/url/unlimited/index?first=value1&second=value2...&anyvalidname=somevalue

我想采取一项行动,预先接受未知数量的未知名称的参数。像这样的东西:

public class UnlimitedController : Controller
{
    public ActionResult Index(object queryParams)
    {

    }

    //or even better
    public ActionResult Index(Dictionary<string, object> queryParams)
    {

    }
}
4

6 回答 6

4

您可以创建一个自定义模型绑定器,将查询字符串转换为字典。

自定义模型绑定器

  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);
    }
  }

行动

public ActionResult Index([ModelBinder(typeof(CustomModelBinder))]
   Dictionary<string, string> queryParams)
{

}
于 2012-07-10T04:09:44.377 回答
1

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();
}

Test.cshtml

<h2>Test</h2>
@Html.Raw(ViewBag.Data)

网页, http://localhost:35268/Home/Test?var1=1&var2=2, 显示:

var1: 1
var2: 2
于 2012-07-10T00:45:53.683 回答
0

为什么不将所需的所有内容保存在单个查询字符串参数中并将其作为字符串在服务器端获取,
然后自行解析字符串并获取您想要的
东西,
http://example.com?a=someVar&b=var1_value1__var2_value2__var3_value3
然后在服务器端拆分字符串并获取变量和所有如果你不想要这个值

,那么你可以做的就是
通过 url 调用控制器并手动进入Request.QueryString[]集合,你将获得所有变量和那里的值

于 2012-07-09T22:55:55.703 回答
0

您的控制器代码可能像

  public ActionResult MultipleParam(int a, int b, int c)
            {
                ViewData["Output"] = a + b + c;
                return View();
            }

全球.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 */) { }
于 2012-07-09T22:59:44.157 回答
0

另一种可能的解决方案是创建自定义路线

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)
    {
    }
}

网址:

http://localhost/ParamsEnabled/Home/Test/parameteres?param1=value1&param2=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
}
于 2012-07-10T14:48:19.110 回答
0

只需使用HttpContext来收集您的查询字符串。

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.

于 2016-03-03T06:19:25.843 回答