Как сопоставить 2 маршрута одному и тому же URL?
Я хочу, чтобы веб-страница делала разные вещи в зависимости от того, к какой веб-странице обращались раньше.
По сути, я знаю, как создавать данные с постоянным постоянством. Тем не менее, мой метод предполагает использование строк запроса, но я не хочу, чтобы второй пользователь мог получить доступ к веб-странице со строками запроса, которые были созданы ранее. Итак, я пытаюсь обойти эту проблему, сопоставляя несколько маршрутов в один 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 ответ
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
верните истину, MVC выполнит метод для возврата ответа. Еще MVC найдет другой метод, который соответствует критериям маршрутизации.
Чтобы создать свой собственный атрибут, вы должны расширить ActionMethodSelectorAttribute
класс и переопределение IsValidForRequest
метод. IsValidForRequest
метод имеет controllerContext
а также methodInfo
в качестве входного параметра. Этот метод может вызываться несколько раз в зависимости от того, сколько методов способно выполнить запрос. Каждый раз 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 имеет два метода Foo
а также Foo2
это должно обработать запрос. Как я сказал ранее, перед выполнением любого метода для возврата ответа MVC будет вызывать MyActionSelectorAttribute.IsValidForRequest
для обоих методов. Для иллюстрации мы берем QueryString и проверяем
1) если foo присутствует в строке запроса и метод также является Foo, вернуть true (значит, разрешить выполнение для Foo
метод)
2) в противном случае, если строка запроса содержит Foo2, а метод также является Foo2, вернуть true (значит, разрешить выполнение для Foo2
метод)
3) иначе вернуть false.