区分 MVC 3 中的 Guid 和字符串参数
使用 ASP.NET MVC(3 或 4DP)中的开箱即用方法定位器,是否有办法让 MVC 框架区分字符串和 Guid,而无需解析控制器操作中的参数?
用法示例是 URL
http://[域]/customer/details/F325A917-04F4-4562-B104-AF193C41FA78
执行
public ActionResult Details(Guid guid)
方法,以及
执行
public ActionResult Details(string id)
方法。
如果没有任何更改,显然这些方法是不明确的,如下所示:
public ActionResult Details(Guid id)
{
var model = Context.GetData(id);
return View(model);
}
public ActionResult Details(string id)
{
var model = Context.GetData(id);
return View(model);
}
导致错误:
The current request for action 'Details' on controller type 'DataController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Details(System.Guid) on type Example.Web.Controllers.DataController
System.Web.Mvc.ActionResult Details(System.String) on type Example.Web.Controllers.DataController
我尝试使用自定义约束(基于 如何创建 System.Guid 类型的路由约束?)尝试通过路由推送它:
routes.MapRoute(
"Guid",
"{controller}/{action}/{guid}",
new { controller = "Home", action = "Index" },
new { guid = new GuidConstraint() }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
并切换操作签名to:
public ActionResult Details(Guid guid)
{
var model = Context.GetData(guid);
return View(model);
}
public ActionResult Details(string id)
{
var model = Context.GetData(id);
return View(model);
}
约束执行并通过,因此参数被发送到一个操作,但看起来仍然是一个字符串,因此对两个方法签名来说是不明确的。我预计操作方法的定位方式会导致歧义,因此可以通过插入自定义模块来定位方法来覆盖。
通过解析字符串参数可以实现相同的结果,但为了简洁起见,避免操作中的逻辑(更不用说希望有一天重用)会非常好。
Using the out-of-the-box method locators in ASP.NET MVC (3 or 4DP), is there a way to have the MVC framework differentiate between a string and Guid without needing to parse the parameter in the controller action?
Usage examples would be for the URL
http://[domain]/customer/details/F325A917-04F4-4562-B104-AF193C41FA78
to execute the
public ActionResult Details(Guid guid)
method, and
to execute the
public ActionResult Details(string id)
method.
With no changes, obviously the methods are ambiguous, as follows:
public ActionResult Details(Guid id)
{
var model = Context.GetData(id);
return View(model);
}
public ActionResult Details(string id)
{
var model = Context.GetData(id);
return View(model);
}
resulting in the error:
The current request for action 'Details' on controller type 'DataController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Details(System.Guid) on type Example.Web.Controllers.DataController
System.Web.Mvc.ActionResult Details(System.String) on type Example.Web.Controllers.DataController
I attempted to use a custom constraint (based on How can I create a route constraint of type System.Guid?) to try and push it through via routing:
routes.MapRoute(
"Guid",
"{controller}/{action}/{guid}",
new { controller = "Home", action = "Index" },
new { guid = new GuidConstraint() }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
And switched the action signatures to:
public ActionResult Details(Guid guid)
{
var model = Context.GetData(guid);
return View(model);
}
public ActionResult Details(string id)
{
var model = Context.GetData(id);
return View(model);
}
The constraint executes and passes, thus the argument is sent to an action, but seemingly still as a string, and thus ambiguous to the two method signatures. I expect that there's something in how the action methods are located that causes the ambiguity, and thus could be overridden by plugging in a custom module to locate methods.
The same result could be achieved by parsing out the string parameter, but would be really nice for brevity to avoid that logic in the action (not to mention to hopefully reuse someday later).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,您必须通过给方法指定两个不同的名称来消除歧义:
接下来,您需要一个自定义路由处理程序来检查请求,并相应地更改方法名称:
最后,在顶部添加一个
Details
路由您的路由,如下所示:当收到详细信息请求时,
Details
路由将使用您的自定义路由处理程序来检查id
令牌。路由处理程序根据 id 令牌的形式添加到操作名称,以便将请求定向到适当的操作。First, you must disambigute your methods by giving them two different names:
Next, you need a custom route handler to inspect the request, and change the method name accordingly:
Finally, add a
Details
route at the top of your routes, as follows:When a request comes in for details, the
Details
route will use your custom route handler to inspect theid
token. The route handler adds to the action name based on the form of the id token, so that the request will be directed to the appropriate action.我的观点是,使用操作方法选择器更有用并且编码更少。
该选择器检查 ID 参数的请求。如果是 guid,则返回 true。因此,要使用它:
My opinion is that using action method selector is more usable and less coding.
This selector inspects request for ID parameter. If it's guid, it returns true. So, to use it:
如果您仍然以这种方式注册路由,则 GuidRouteConstraint() 类已添加到较新版本的 MVC 中,并且应该使用它而不是自定义实现:
然后您可以简单地创建操作结果,如下所示:
If you're still registering routes in this way then the GuidRouteConstraint() class was added in a newer version of MVC and should be used instead of a custom implementation:
Then you can simply create your action result as: