我正在玩其中的区域和路由。我想要实现的是能够拥有这样的URL;
PracticeAdmin/Practice/[Practice Name]
然后我可以将编辑和删除等内容添加到。
的末尾过去我通过在动作
中添加此注释来处理区域时已经实现了这一点[Route("PracticeAdmin/Practices/{practiceName}")]
public ActionResult Details(string practiceName)
这会生成我想要的网址。我遇到的问题是,当我尝试使用区域时,我会得到这样的链接;
PracticeAdmin/Practices?practiceName=Practice1
这不是我想要的。
我用来尝试生成此代码的代码是
using System.Web.Mvc;
namespace TrainingPortal.Areas.PracticeAdmin
{
public class PracticeAdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "PracticeAdmin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"PracticeAdmin_default",
"PracticeAdmin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new[] { "TrainingPortal.Areas.PracticeAdmin.Controllers" }
);
}
}
}
namespace TrainingPortal
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "TrainingPortal.Controllers" }
);
}
}
}
我在这里调用了MapMvcAttributeRoutes,我认为这应该意味着即使在区域内也可以注册路由。我也尝试在PracticeAdminAreaRegistration中放置必要的代码来做同样的事情而没有效果。
namespace TrainingPortal.Areas.PracticeAdmin.Controllers
{
public partial class PracticesController : Controller
{
private TpContext db = new TpContext();
// GET: PracticeAdmin/Practices
public virtual ActionResult Index()
{
return View(db.Practices.ToList());
}
[Route("PracticeAdmin/Practice/{practiceName}")]
public virtual ActionResult Details(string practiceName)
{
if (string.IsNullOrWhiteSpace(practiceName))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Practice practice = db.Practices.FirstOrDefault(m => m.PracticeName.ToLower() == practiceName);
if (practice == null)
{
return HttpNotFound();
}
return View(practice);
}
...
显然它继续使用其他方法,但它们都遵循与此相同的方法。
@Html.ActionLink("Delete", MVC.PracticeAdmin.Practices.Delete(item.PracticeName))
@Html.ActionLink("Delete2", "Delete", new { practiceName = item.PracticeName })
在PracticeAdminArea / Views / Practices / Index.cshtml中,我尝试过使用T4MVC和普通的ActionLink方法生成完全相同的链接(不出所料)。
我不知道为什么在尝试在某个区域创建ActionLink时,我指定的路径没有出现,所以我想知道是否有人能够指出我如何解决这个问题的方向并获取URL以了解我希望如何?
答案 0 :(得分:5)
经过一段时间的游戏,我设法让它发挥作用。我最终解决问题的方法是在调用AreaRegistration.RegisterAllAreas()
后调用RouteConfig.RegisterRoutes()
MapMvcAttributeRoutes()
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "TrainingPortal.Controllers" }
);
}
}
由于你不允许两次调用这个方法(或者你因为你已经注册了两次相同的路由名而感到非常不安)我从Global.asax中移除了对AreaRegistration.RegisterAllAreas()
的调用,使它看起来像这;
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
不幸的是,仅此一项并未解决问题,我还必须对Controller进行一些修改。修改是将RoutePrefix
和RouteArea
属性添加到Controller中,如下所示;
[RouteArea("PracticeAdmin")]
[RoutePrefix("Practice")]
public partial class PracticesController : Controller
{
这具有额外的好处,当通过Route
属性指定特定操作的路由时,您不必再指定这些部分,因此最初操作的签名看起来像这样;
// GET: PracticeAdmin/Practices/{practiceName}/Members
[Route("PracticeAdmin/Practices/{practiceName}/Members")]
public virtual ActionResult Members(string practiceName)
{
现在看起来像这样;
// GET: PracticeAdmin/Practices/{practiceName}/Members
[Route("{practiceName}/Members")]
public virtual ActionResult Members(string practiceName)
{
完成所有这些更改后,网站的行为符合预期。