MVC映射路由到导航菜单并避免硬编码链接

时间:2013-09-29 09:54:17

标签: asp.net-mvc asp.net-mvc-4

我已设置路线,以便我有以下平面网址结构:

mywebsite/service-option-one (goes to Home Controller, Option1 action)
mywebsite/service-option-two (goes to Home Controller, Option2 action)
mywebsite/ (goes to Home Controller, Index)
mywebsite/about (goes to Home Controller, Index with path=about)
mywebsite/contact (goes to Home Controller, Index with path=contact)

这很重要,因为我有很多内容视图,并且不希望对这些通用信息页面有单独的操作,解析视图的简单代码就在本文末尾。

在构建菜单时,MVC Html.ActionLink帮助程序,但是它们为通用内容提供了错误的地址,这些地址是有意义的,因为这些操作不存在!

鉴于我的地址方案,我怎么能用一个辅助方法来设置我的锚链接目标,或者我只需要在html中使用硬编码(即<a href="~/contact>Contact us</a>)?

// note that the order of the routes is very important!
public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    // error route
    routes.MapRoute(
        "Error", // Route name
        "Oops", // URL with parameters
        new { controller = "Home", action = "Error" }
    );

    routes.MapRoute(
        "Service1",
        "service-option-one",
        new { controller = "Home", action = "Option1" }
    );

    routes.MapRoute(
        "Service2",
        "service-option-two",
        new { controller = "Home", action = "Option1" }
    );

    // default home controller route for general site content (/content), uses default path value set to Index
    routes.MapRoute(
        name: "Catchall",
        url: "{path}",
        defaults: new { controller = "Home", action = "Index", path = "Index" }
    );

    // home page route, blank url (/)
    routes.MapRoute(
        "HomePage", // Route name
        "", // URL with parameters
        new { controller = "Home", action = "Index" }
    );

    // default route
    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "{controller}", action = "{action}", id = UrlParameter.Optional } // Parameter defaults
    );
}


public class HomeController : Controller
{
    private bool ViewExists(string name)
    {
        ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, name, null);
        return (result.View != null);
    }

    public ActionResult Index(string path)
    {
        System.Diagnostics.Debug.WriteLine("looking for..." + path);

        if (ViewExists(path)==true)
        {
            System.Diagnostics.Debug.WriteLine("general controller action...");
            return View(path);
        }
        else
        {
            System.Diagnostics.Debug.WriteLine("page not found...");
            return RedirectToRoute("Error");
        }
    }

    public ActionResult Error()
    {
        return View();
    }

    public ActionResult Option1()
    {
        return View();
    }

    public ActionResult Option2()
    {
        return View();
    }
}

1 个答案:

答案 0 :(得分:1)

您正在使用ActionLink帮助程序,使用的是与使用帮助程序时相反的位置。你试图告诉Razor链接的路由网址应该是什么,而实际上这就是Razor将要为你做的事情。因此,对于 mywebsite / service-option-one 的示例,您应该将service-option-one写下来的唯一位置在路线图中。在你的观点中,你应该做

@Html.ActionLink("The Anchor Text You Want To Display","Option1","Home")

然后当Razor呈现视图时,它将转换为

<a href="mywebsite/service-option-one">The Anchor Text You Want To Display</a>

http://msdn.microsoft.com/en-us/library/dd505070(v=vs.118).aspx