asp.net-mvc - ASP.net MVC - 使用没有查询字符串值或花哨路由的模型绑定(bind)器

标签 asp.net-mvc data-binding model modelbinders model-binding

我有一个 Asp.net MVC 应用,目前使用默认模型绑定(bind)器和具有复杂参数的 url 运行良好,如下所示:

example.com/Controller/Action?a=hello&b=world&c=1&d=2&e=3(注意问号)

使用内置的模型绑定(bind)器,不同的 url 会自动映射到 Action Method 参数。我想继续使用标准模型 Binder ,但我需要摆脱查询字符串。我们想把这些 url 放在 CDN that does not support resources that vary by query strings (Amazon Cloud front) 后面所以我们需要从我们的网址中删除问号并做一些像这样的傻事

example.com/Controller/Action/a=hello&b=world&c=1&d=2&e=3(无问号)

这些 url 仅通过 AJAX 使用,因此我对让它们对用户或 SEO 友好不感兴趣。我只想去掉问号并保持所有代码完全相同。问题是,我不确定如何继续使用 MVC 模型绑定(bind)器并放弃它会做很多工作。

我不想使用复杂的路线来映射我的对象 like this question did相反,我打算使用如下所示的单一简单路线

   routes.MapRoute(
        "NoQueryString",                    // Route name
        "NoQueryString/{action}/{query}", // 'query' = querystring without the ?
        new {
            controller = "NoQueryString",
            action = "Index",
            query = "" }  // want to parse with model binder - By NOT ROUTE
    );

选项 1(首选):OnActionExecuting 我计划在 Controller 操作使用我的 Controller 中的 OnActionExecuting 方法执行之前,在上面的路由中使用 catchall“query”值将旧查询字符串注入(inject)默认模型绑定(bind)器。但是,我不确定是否可以加回问号。 我可以这样做吗?您建议如何修改网址?

选项 2:自定义模型绑定(bind)器 我还可以制作某种自定义模型绑定(bind)器,它只告诉默认模型绑定(bind)器将“查询”值视为查询字符串。 您更喜欢这种方法吗?你能给我指出一个相关的例子吗?

我有点担心这是一个边缘案例,在我开始尝试实现选项 1 或选项 2 并偶然发现无法预料的错误之前,我会喜欢一些输入。

最佳答案

您可以使用带有 catchall 路由的自定义值提供程序:

routes.MapRoute(
    "NoQueryString",
    "NoQueryString/{controller}/{action}/{*catch-em-all}",
    new { controller = "Home", action = "Index" }
);

和值(value)提供者:

public class MyCustomProvider : ValueProviderFactory
{
    public override IValueProvider GetValueProvider(ControllerContext controllerContext)
    {
        var value = controllerContext.RouteData.Values["catch-em-all"] as string;
        var backingStore = new Dictionary<string, object>();
        if (!string.IsNullOrEmpty(value))
        {
            var nvc = HttpUtility.ParseQueryString(value);
            foreach (string key in nvc)
            {
                backingStore.Add(key, nvc[key]);
            }
        }
        return new DictionaryValueProvider<object>(
            backingStore, 
            CultureInfo.CurrentCulture
        );
    }
}

Application_Start 中注册:

ValueProviderFactories.Factories.Add(new MyCustomProvider());

现在剩下的就是模型了:

public class MyViewModel
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
    public string D { get; set; }
    public string E { get; set; }
}

和一个 Controller :

public class HomeController : Controller
{
    [ValidateInput(false)]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

然后导航到:NoQueryString/Home/Index/a=hello&b=world&c=1&d=2&e=3Index 被命中,模型被绑定(bind)。

备注:注意 Controller 操作上的ValidateInput(false)。这可能是需要的,因为 ASP.NET 不允许您使用特殊字符,例如 & 作为 URI 的一部分。您可能还需要稍微调整一下 web.config:

<httpRuntime requestValidationMode="2.0" requestPathInvalidCharacters=""/>

有关这些调整的更多信息,请确保您已阅读 Scott Hansleman 的 blog post .

关于asp.net-mvc - ASP.net MVC - 使用没有查询字符串值或花哨路由的模型绑定(bind)器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4800881/

相关文章:

WPF ComboBox-选择值时显示不同的内容

ios - 核心数据轻量级迁移与 NSManagedObject 子类和关系

mysql - 将 MySql 与 ASP.Net MVC 结合使用时 Entity Framework IndexAttribute 错误

javascript - Asp.Net MVC 4 从表单发布中的对象数组自动绑定(bind)模型

c# - 如何将文件写入内存流,压缩其中三个内存流,然后将其放入另一个内存流中?

c# - 绑定(bind)到不带参数的成员函数?

mysql - IEnumerable 从 mySQL 连接打印出单个实体

WPF用户控件: can I bind properties from an internal and an external datacontext?

validation - yii2 表单文件小部件在每次更新时都会给出验证错误

ruby-on-rails - rails : Validating min and max length of a string but allowing it to be blank