Gle*_*enn 2 data-binding asp.net-mvc model model-binding modelbinders
我有一个Asp.net MVC应用程序,目前使用默认模型绑定器和具有复杂参数的URL,如下所示:
example.com/Controller/Action?a=hello&b=world&c=1&d=2&e=3 (注意问号)
不同的URL使用内置的模型绑定器自动映射到Action Method参数.我想继续使用标准模型绑定器,但我需要摆脱查询字符串.我们希望将这些网址放在CDN之后,该CDN不支持因查询字符串(Amazon Cloud front)而异的资源,因此我们需要从我们的网址中删除问号并执行类似这样的操作
example.com/Controller/Action/a=hello&b=world&c=1&d=2&e=3 (无问号)
这些网址只能通过AJAX使用,所以我对使用户或SEO友好不感兴趣.我想删除问号并保持我的所有代码完全相同.问题是,我不确定如何继续使用MVC模型绑定器并放弃它将是一项很多工作.
我不想使用复杂的路线来映射我的对象,就像这个问题一样,相反,我打算使用一条简单的路线,如下所示
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
);
Run Code Online (Sandbox Code Playgroud)
选项1(首选):OnActionExecuting 我计划在控制器动作使用我的控制器中的OnActionExecuting方法执行之前,使用上面路由中的catchall"query"值将旧的查询字符串注入默认模型绑定器.但是,我有点不确定我是否可以添加问号. 我可以这样做吗?你会如何建议修改网址?
选项2:自定义模型Binder 我也可以创建某种自定义模型绑定器,它只是告诉默认模型绑定器将"查询"值视为查询字符串. 你更喜欢这种方法吗?你能指点我一个相关的例子吗?
我有点担心这是一个边缘情况,并且在我开始尝试实现选项1或选项2并偶然发现不可预见的错误之前会喜欢一些输入.
您可以将自定义值提供程序与catchall路由一起使用:
routes.MapRoute(
"NoQueryString",
"NoQueryString/{controller}/{action}/{*catch-em-all}",
new { controller = "Home", action = "Index" }
);
Run Code Online (Sandbox Code Playgroud)
和价值提供者:
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
);
}
}
Run Code Online (Sandbox Code Playgroud)
你注册的是Application_Start:
ValueProviderFactories.Factories.Add(new MyCustomProvider());
Run Code Online (Sandbox Code Playgroud)
现在剩下的只是一个模型:
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; }
}
Run Code Online (Sandbox Code Playgroud)
和一个控制器:
public class HomeController : Controller
{
[ValidateInput(false)]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
Run Code Online (Sandbox Code Playgroud)
然后导航到:NoQueryString/Home/Index/a=hello&b=world&c=1&d=2&e=3.在Index被击中和模型绑定.
备注:注意ValidateInput(false)控制器上的操作.这可能是需要的,因为ASP.NET不允许您使用特殊字符,例如&URI的一部分.您可能还需要稍微调整一下web.config:
<httpRuntime requestValidationMode="2.0" requestPathInvalidCharacters=""/>
Run Code Online (Sandbox Code Playgroud)
有关这些调整的更多信息,请确保您已阅读Scott Hansleman的博客文章.
| 归档时间: |
|
| 查看次数: |
2479 次 |
| 最近记录: |