C# 如何将两条路由映射到同一URL?
我想一个网页做不同的事情取决于什么网页访问之前 基本上,我知道如何使数据持久化。然而,我的方法涉及使用查询字符串,但我不希望第二个用户能够使用以前创建的查询字符串访问网页。所以,我试图通过将多个路由映射到一个url来解决这个问题。这在C#MVC中可能吗 具体地说,每当我从我的视图中单击我的链接时(可以在下面找到),被调用的路由只是第一个在搜索历史页面上有url的路由。这意味着不调用具有相应操作方法的路由。搜索历史页面 这是我的route.config 这是我的控制器。 这是我的主页视图。C# 如何将两条路由映射到同一URL?,c#,asp.net-mvc,url,model-view-controller,routing,C#,Asp.net Mvc,Url,Model View Controller,Routing,我想一个网页做不同的事情取决于什么网页访问之前 基本上,我知道如何使数据持久化。然而,我的方法涉及使用查询字符串,但我不希望第二个用户能够使用以前创建的查询字符串访问网页。所以,我试图通过将多个路由映射到一个url来解决这个问题。这在C#MVC中可能吗 具体地说,每当我从我的视图中单击我的链接时(可以在下面找到),被调用的路由只是第一个在搜索历史页面上有url的路由。这意味着不调用具有相应操作方法的路由。搜索历史页面 这是我的route.config 这是我的控制器。 这是我的主页视图。
我的搜索历史页面视图为空 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为一个请求找到两个以上的方法时,它抛出含糊不清的MatchException
从方法列表中,您可以通过创建自定义的操作方法SelectorAttribute
来指定哪个方法将处理请求。当ActionMethodSelectorAttribute
修饰为任何方法时,MVC将在执行返回响应的方法之前执行IsValidForRequest
。如果IsValidForRequest
返回true,MVC将执行返回响应的方法。否则MVC将找到符合路由条件的其他方法
要创建自己的属性,必须扩展ActionMethodSelectorAttribute
类并重写IsValidForRequest
方法IsValidForRequest
方法将controllerContext
和methodInfo
作为输入参数。根据有多少方法能够满足请求,可以多次调用此方法。
每次methodInfo
都会有关于应该处理请求的方法的不同信息(基于路由表/ActionNameAttribute
)
在我们的例子中,当请求来自/Home/Foo
时,MVC有两种方法Foo
和Foo2
来处理请求。正如我前面所说,在执行任何返回响应的方法之前,MVC都将为这两种方法调用MyActionSelectorAttribute.IsValidForRequest
。为了便于说明,我们正在抓取QueryString并进行检查
1) 如果查询字符串中存在foo,并且方法也是foo,则返回true(表示允许执行foo
method)
2) 否则,如果查询字符串包含Foo2,并且方法也是Foo2,则返回true(表示允许执行Foo2
method)
3) 否则返回false。动作选择器在这种情况下可能会有所帮助。我认为这对我没有帮助。我希望url是相同的。操作选择器更改url。属性路由是否可以解决您的问题?其思想是可以使用查询字符串参数作为路由条件。谁能给我解释一下上面的代码吗?我认为这段代码对我帮助不大,因为我认为编写自定义方法选择逻辑是一个令人困惑的部分。@AlexanderKao我已经更新了答案,并进行了解释。我实际上找到了一种方法,仅使用基本知识就可以完成我想要的任务。是啊!无论如何,谢谢。我将总结一下如何在不破坏url的情况下使查询字符串url不可访问(99%的时间)的方法。总体思路是使用查询字符串创建至少两个url路径。在您希望人们能够访问的路径中,创建一个中间方法,重定向到您希望返回视图的操作。第二条路径将直接访问我前面提到的操作。在中间方法中,您告诉数据库将“以前是否访问过此页面”的值增加到1。
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");
}
}
}
@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)
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");
}
}
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;
}
}