我的控制器中有以下内容:
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或string获取。
但是我得到以下内容:
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
答案 0 :(得分: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
。