MVC 创建自定义路由

4 浏览
0 Comments

MVC 创建自定义路由

我在我的控制器中有以下内容:

public ActionResult Details(string name)
{
    Student student = db.Students.FirstOrDefault(x => x.FirstName == name);
    if (student == null)
    {
        return HttpNotFound();
    }
    return View(student);
}
public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Student student = db.Students.Find(id);
    if (student == null)
    {
        return HttpNotFound();
    }
    return View(student);
}

RouteConfig.cs:

// /Student/Details/Id
routes.MapRoute(
    name: "StudentDetailsId",
    url: "{Student}/{Action}/{id}",
    defaults: new { controller = "Student", action = "Details", id = UrlParameter.Optional },
    constraints: new { id = @"\d+" }
);
// /Student/Details/Name
routes.MapRoute(
    name: "StudentDetailsName",
    url: "{Student}/{Details}/{name}",
    defaults: new { controller = "Student", action = "Details" }
);
// /Student/Name
routes.MapRoute(
    name: "StudentName",
    url: "{Student}/{name}",
    defaults: new { controller = "Student", action = "Details" }
);

所以基本上我想要具有相同的操作名称,但可以使用id:int或字符串来获取。

然而,我得到了以下错误信息:

在类型MySuperAwesomeMVCApp.Controllers.StudentController上控制器类型的操作'Details'的当前请求在以下操作方法之间存在歧义:
类型为MySuperAwesomeMVCApp.Controllers.StudentController的System.Web.Mvc.ActionResult Details(System.String)
类型为MySuperAwesomeMVCApp.Controllers.StudentController的System.Web.Mvc.ActionResult Details(System.Nullable`1[System.Int32])

0
0 Comments

MVC创建自定义路由的问题的出现原因是在同一个控制器中有两个具有相同名称的action方法。根据MVC的规定,同名的action方法必须一个是GET请求,另一个是POST请求。然而,MVC无法根据路由数据确定要调用的action方法。尽管方法的重载在C#中是有效的,但是MVC的action方法选择器不是强类型的。

解决这个问题的方法是使用AttributeRouting.NET库。该库是MVC5中最受关注的功能之一,虽然它最初是一个开源的副项目,但是在MVC4中也可以使用。只需下载NuGet包即可。使用该库后,不需要使用MapRoute方法。action方法的定义如下:

// GET: /Students/Details/5
[GET("students/details/{id:int}", ControllerPrecedence = 1)]
public ActionResult DetailsById(int? id)
{
    // method implementation
}
// GET: /Students/Details/Albert+Einstein or GET: /Students/Albert+Einstein
[GET("students/{name}", ActionPrecedence = 1)]
[GET("students/details/{name}")]
public ActionResult DetailsByName(string name)
{
    // method implementation
}

这样就不需要使用复杂的正则表达式约束了。只需要确保int类型的方法具有优先级,以防止MVC将数字传递给接受字符串的方法。

总结起来,MVC创建自定义路由的问题的解决方法是使用AttributeRouting.NET库,通过在方法上添加特性来定义路由,从而避免同一个控制器中出现同名的action方法。

0