fal*_*uan 7 asp.net-mvc guid asp.net-mvc-routing
使用ASP.NET MVC(3或4DP)中的开箱即用方法定位器,有没有办法让MVC框架区分字符串和Guid而无需解析控制器操作中的参数?
用法示例适用于URL
执行
public ActionResult Details(Guid guid)
Run Code Online (Sandbox Code Playgroud)
方法,和
执行
public ActionResult Details(string id)
Run Code Online (Sandbox Code Playgroud)
方法.
没有任何变化,显然这些方法含糊不清,如下:
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);
}
Run Code Online (Sandbox Code Playgroud)
导致错误:
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
Run Code Online (Sandbox Code Playgroud)
我尝试使用自定义约束(基于如何创建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 }
);
Run Code Online (Sandbox Code Playgroud)
并将动作签名切换为:
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);
}
Run Code Online (Sandbox Code Playgroud)
约束执行并传递,因此参数被发送到动作,但看起来仍然是一个字符串,因此对两个方法签名不明确.我希望动作方法的位置会导致模糊,因此可以通过插入自定义模块来定位方法来覆盖.
通过解析出字符串参数可以获得相同的结果,但为了简洁起见,在行动中避免使用该逻辑(更不用说希望有一天后再使用),这样做非常好.
cou*_*ben 11
首先,您必须通过给出两个不同的名称来消除歧义.
public ActionResult DetailsGuid(Guid guid)
{
var model = Context.GetData(guid);
return View(model);
}
public ActionResult DetailsString(string id)
{
var model = Context.GetData(id);
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
接下来,您需要一个自定义路由处理程序来检查请求,并相应地更改方法名称:
using System.Web.Mvc;
using System.Web.Routing;
public class MyRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var routeData = requestContext.RouteData;
var stringValue = routeData.Values["id"].ToString();
Guid guidValue;
var action = routeData.Values["action"];
if (Guid.TryParse(stringValue, out guidValue) && (guidValue != Guid.Empty);
routeData.Values["action"] = action + "Guid";
else
routeData.Values["action"] = action + "String";
var handler = new MvcHandler(requestContext);
return handler;
}
}
Run Code Online (Sandbox Code Playgroud)
最后,在Details路线顶部添加路线,如下所示:
routes.Add("Details",
new Route("{controller}/Details/{id}",
new RouteValueDictionary(
new { controller = "Home", action = "Details" }),
new MyRouteHandler()
)
);
);
Run Code Online (Sandbox Code Playgroud)
当请求进入详细信息时,Details路由将使用您的自定义路由处理程序来检查id令牌.路由处理程序根据id标记的形式添加到操作名称,以便将请求定向到相应的操作.
我的观点是使用动作方法选择器更有用,编码更少.
public class GuidMethodSelectorAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
var idStr = controllerContext.RouteData.Values["id"];
if (idStr == null)
return false;
Guid a;
var result = Guid.TryParse(idStr.ToString(), out a);
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
此选择器检查ID参数的请求.如果是guid,则返回true.所以,使用它:
public class HomeController : Controller
{
[GuidMethodSelector]
public ActionResult Index(Guid id)
{
return View();
}
public ActionResult Index(string id)
{
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
如果你仍然以这种方式注册路由,那么GuidRouteConstraint()类被添加到更新版本的MVC中,应该用来代替自定义实现:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Guid",
"{controller}/{action}/{guid}",
new { controller = "Home", action = "Index" },
new { guid = new GuidRouteConstraint() }
);
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以简单地创建您的操作结果:
public class HomeController : Controller {
public ActionResult Index(Guid guid) {
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11923 次 |
| 最近记录: |