如何将2条路线映射到同一个URL?

时间:2015-07-11 05:15:57

标签: c# asp.net-mvc url model-view-controller routing

我想要一个网页根据之前访问过的网页做不同的事情。

基本上,我知道如何使用持久的持久性来创建数据。但是,我的方法涉及使用查询字符串,但我不希望第二个用户能够访问具有之前创建的查询字符串的网页。所以,我试图通过将多个路由映射到单个URL来解决这个问题。这可能在C#MVC中有用吗?

具体来说,每当我从我的视图中单击我的链接时(可以在下面找到),被调用的路径就是第一个具有URL Search_History_Page的路径。意味着不调用具有相应操作方法的路径。 The_Search_History_Page

这是我的route.config

using System.Web.Mvc;
using System.Web.Routing;

namespace CBCM_Audio_Searcher
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute(
                name: "Route_That_Leads_To_The_Home_Page_As_The_First_Page",
                url: "The_Home_Page",
                defaults: new { controller = "First_", action = "Goes_To_The_Home_Page_As_The_First_Page"}
            );

            routes.MapRoute(
                name: "Route_That_Leads_To_The_Search_History_Page_As_The_First_Page",

                url: "The_Search_History_Page",
              defaults: new { controller = "First_", action = "Goes_To_The_Search_History_Page_As_The_First_Page", id = 1}
            );

            routes.MapRoute(
               name: "Route_That_Leads_To_The_Search_History_Page_From_The_Home_Page",
               url: "The_Search_History_Page",
               defaults: new { controller = "First_", action = "Goes_To_The_Search_History_Page_From_The_Home_Page", id=0 }
           );
        }
    }
}

这是我的控制器。

using System.Web.Mvc;
using System.Diagnostics; 

namespace CBCM_Audio_Searcher.Controllers
{
    public class First_Controller : Controller
    {
        public ActionResult Goes_To_The_Home_Page_As_The_First_Page()
        {

            Database_Data_Modifier_And_Extractor  Database_Data_Modifier_And_Extractor=new  Database_Data_Modifier_And_Extractor();  

            if (Database_Data_Modifier_And_Extractor.Checks_If_A_User_Can_Access_The_Website() == false)
            {
                return Redirect("http://www.google.com");  
            }

            else 
            {
                ViewData["User_ID"]=Database_Data_Modifier_And_Extractor.User_ID;         
                return View("The_Home_Page");
            }
        }
        public ActionResult Goes_To_The_Search_History_Page_As_The_First_Page(string User_ID,string DummyVariable, int id)
        {
            Debug.WriteLine(id); 
            return View("The_Search_History_Page"); 
        }
        public ActionResult Goes_To_The_Search_History_Page_From_The_Home_Page(string User_ID, string DummyVariable, int id)
        {
            Debug.WriteLine(id);
            return View("The_Search_History_Page");
        }

    }
}

这是我的The_Home_Page_View。

@Html.ActionLink("Your Search Results", "Goes_To_The_Search_History_Page_From_The_Home_Page", "First_", new { User_ID = ViewData["User_ID"], DummyVariable = "a"}, null)  

我的The_Search_History_Page视图为空。

1 个答案:

答案 0 :(得分:2)

MVC具有为方法指定操作名称的功能。您可以通过使用ActionNameAttribute装饰方法并将新操作名称作为参数传递来指定名称。

因此,每当/Home/Bar发出请求时,都会将其传递给MyActionMethod方法进行处理。

public class HomeController : Controller
{
    [ActionName("Bar")]
    public ActionResult MyActionMethod()
    {
        return Content("Foo");
    }

    [MyActionSelector]
    [ActionName("Foo")]
    public ActionResult Foo()
    {
        return Content("Foo");
    }

    [MyActionSelector]
    [ActionName("Foo")]
    public ActionResult Foo2()
    {
        return Content("Foo2");
    }
}

当请求到来时,MVC将查找基于路由表的方法和将处理请求的ActionNameAttribute。当MVC为请求找到两个以上的方法时,它会抛出AmbiguousMatchException

从方法列表中,您可以通过创建自定义ActionMethodSelectorAttribute来指定处理请求的方法。当ActionMethodSelectorAttribute被装饰到任何方法时,MVC将在执行返回响应的方法之前执行IsValidForRequest。如果IsValidForRequest返回true,则MVC将执行返回响应的方法。其他MVC将找到符合路由标准的其他方法。

要创建自己的属性,您必须扩展ActionMethodSelectorAttribute类并覆盖IsValidForRequest方法。 IsValidForRequest方法有controllerContextmethodInfo作为输入参数。可以基于有多少方法能够满足请求来多次调用该方法。 每次methodInfo将有关于应该处理请求的方法的不同信息(基于路由表/ ActionNameAttribute)。

public class MyActionSelectorAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    {
        HttpRequestBase request = controllerContext.RequestContext.HttpContext.Request;
        // your custom method selection logic goes here
        // select method based on previously searched term
        if (request.QueryString["foo"] != null && methodInfo.Name == "Foo")
        {
            return true;
        }
        else if (request.QueryString["foo2"] != null && methodInfo.Name == "Foo2")
        {
            return true;
        }
        return false;
    }
}

在我们的情况下,当请求/Home/Foo时,MVC有两个应该处理请求的方法FooFoo2。正如我之前所说,在执行任何返回响应的方法之前,MVC将为两个方法调用MyActionSelectorAttribute.IsValidForRequest。为了便于说明,我们抓住QueryString并检查

1)如果查询字符串中存在foo且方法也是Foo则返回true(表示允许执行Foo方法)

2)否则,如果查询字符串包含Foo2且方法也是Foo2,则返回true(表示允许执行Foo2方法)

3)否则返回false。