0

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

    public ActionResult Details(string name)
    {
        Student student = db.Students.FirstOrDefault(x => x.FirstName == name);
        if (student == null)
        {
            return HttpNotFound();
        }
        return View(student);
    }

    // GET: /Student/Details/5
    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 或字符串获取。

但是我得到以下信息:

The current request for action 'Details' on controller type 'StudentController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Details(System.String) on type MySuperAwesomeMVCApp.Controllers.StudentController
System.Web.Mvc.ActionResult Details(System.Nullable`1[System.Int32]) on type MySuperAwesomeMVCApp.Controllers.StudentController
4

1 回答 1

2

控制器:

public ActionResult DetailsByName(string name)
{
    Student student = db.Students.FirstOrDefault(x => x.FirstName == name);
    if (student == null)
    {
        return HttpNotFound();
    }
    return View(student);
}

// GET: /Student/Details/5
public ActionResult DetailsById(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Student student = db.Students.Find(id);
    if (student == null)
    {
        return HttpNotFound();
    }
    return View(student);
}

路线:

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

    // /Student/Details/Name
    routes.MapRoute(
        name: "StudentDetailsName",
        url: "{controller}/{action}/{name}",
        defaults: new { controller = "Student", action = "DetailsByName" }
    );

    // /Student/Name
    routes.MapRoute(
        name: "StudentName",
        url: "{controller}/{name}",
        defaults: new { controller = "Student", action = "DetailsByName" }
    );

在 MVC 中,您最多只能有 2 个同名方法,并且当您这样做时,其中一个必须是 GET,另一个必须是 POST。

不,MVC 无法确定在给定一组路由数据的情况下要调用哪个操作方法。尽管您的方法是有效的 C# 重载,但 MVC 的操作方法选择器不是强类型的。这个问题我已经回答过了,我去看看链接。。。

更新

这是链接:https ://stackoverflow.com/a/10668537/304832

另一个更新

我之所以提出这个问题,是因为其他人感谢我在回答其他路由问题时提到它……查看AttributeRouting.NET。它太棒了,它是 MVC5 中最受关注的特性,尽管它最初是一个开源项目,你没有理由不能在 MVC4 中使用它。只需下载 NuGet 包。使用此库,您无需使用MapRoute. 您的操作方法如下所示:

// GET: /Students/Details/5
[GET("students/details/{id:int}", ControllerPrecedence = 1)]
public ActionResult DetailsById(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Student student = db.Students.Find(id);
    if (student == null)
    {
        return HttpNotFound();
    }
    return View(student);
}

// GET: /Students/Details/Albert+Einstein
// or GET: /Students/Albert+Einstein
[GET("students/{name}", ActionPrecedence = 1)]
[GET("students/details/{name}")]
public ActionResult DetailsByName(string name)
{
    Student student = db.Students.FirstOrDefault(x => x.FirstName == name);
    if (student == null)
    {
        return HttpNotFound();
    }
    return View(student);
}

不需要MapRoute或需要神秘的正则表达式约束。您只需要确保您的int方法具有优先级,这样 MVC 就不会尝试将数字传递给您的方法,该方法采用string.

于 2013-11-05T13:55:30.527 回答