Asp.net 是否可以对多个控制器使用相同的路由?
我想为各种控制器创建一个独特的路由,以简化URL。我想为控制器定义优先级顺序,如下所示:Asp.net 是否可以对多个控制器使用相同的路由?,asp.net,asp.net-mvc,asp.net-mvc-5,Asp.net,Asp.net Mvc,Asp.net Mvc 5,我想为各种控制器创建一个独特的路由,以简化URL。我想为控制器定义优先级顺序,如下所示: public class CommonController : Controller { public ActionResult GenericUrl(string url) { if (url is a category) { return RedirectToAction("Index", "Category", new { cat
public class CommonController : Controller
{
public ActionResult GenericUrl(string url)
{
if (url is a category)
{
return RedirectToAction("Index", "Category", new { categoryId = id });
}
if (url is a product)
{
return RedirectToAction("Index", "Product", new { productId = id });
}
if (url is a user)
{
return RedirectToAction("Index", "User", new { userId = id });
}
return HttpNotFound(); // Might also be the homepage for example.
}
}
RouteConfig:
routes.MapRoute("Category", "{*url}", new { controller = "Category", action = "Index" });
routes.MapRoute("Product", "{*url}", new { controller = "Product", action = "Index" });
routes.MapRoute("User", "{*url}", new { controller = "User", action = "Index" });
public class CategoryController : Controller
{
public ActionResult Index(string url)
{
var categoryManager = new CategoryManager();
var category = categoryManager.GetByURL(url);
if (category != null)
{
return View(category);
}
// ignore and try next controller
}
}
public class ProductController : Controller
{
public ActionResult Index(string url)
{
var productManager = new ProductManager();
var product= productManager.GetByURL(url);
if (product!= null)
{
return View(product);
}
// ignore and try next controller
}
}
public class UserController : Controller
{
public ActionResult Index(string url)
{
var userManager = new UserManager();
var user = userManager.GetByURL(url);
if (user != null)
{
return View(user);
}
// ignore and try next controller
}
}
类别控制器:
routes.MapRoute("Category", "{*url}", new { controller = "Category", action = "Index" });
routes.MapRoute("Product", "{*url}", new { controller = "Product", action = "Index" });
routes.MapRoute("User", "{*url}", new { controller = "User", action = "Index" });
public class CategoryController : Controller
{
public ActionResult Index(string url)
{
var categoryManager = new CategoryManager();
var category = categoryManager.GetByURL(url);
if (category != null)
{
return View(category);
}
// ignore and try next controller
}
}
public class ProductController : Controller
{
public ActionResult Index(string url)
{
var productManager = new ProductManager();
var product= productManager.GetByURL(url);
if (product!= null)
{
return View(product);
}
// ignore and try next controller
}
}
public class UserController : Controller
{
public ActionResult Index(string url)
{
var userManager = new UserManager();
var user = userManager.GetByURL(url);
if (user != null)
{
return View(user);
}
// ignore and try next controller
}
}
ProductController:
routes.MapRoute("Category", "{*url}", new { controller = "Category", action = "Index" });
routes.MapRoute("Product", "{*url}", new { controller = "Product", action = "Index" });
routes.MapRoute("User", "{*url}", new { controller = "User", action = "Index" });
public class CategoryController : Controller
{
public ActionResult Index(string url)
{
var categoryManager = new CategoryManager();
var category = categoryManager.GetByURL(url);
if (category != null)
{
return View(category);
}
// ignore and try next controller
}
}
public class ProductController : Controller
{
public ActionResult Index(string url)
{
var productManager = new ProductManager();
var product= productManager.GetByURL(url);
if (product!= null)
{
return View(product);
}
// ignore and try next controller
}
}
public class UserController : Controller
{
public ActionResult Index(string url)
{
var userManager = new UserManager();
var user = userManager.GetByURL(url);
if (user != null)
{
return View(user);
}
// ignore and try next controller
}
}
用户控制器:
routes.MapRoute("Category", "{*url}", new { controller = "Category", action = "Index" });
routes.MapRoute("Product", "{*url}", new { controller = "Product", action = "Index" });
routes.MapRoute("User", "{*url}", new { controller = "User", action = "Index" });
public class CategoryController : Controller
{
public ActionResult Index(string url)
{
var categoryManager = new CategoryManager();
var category = categoryManager.GetByURL(url);
if (category != null)
{
return View(category);
}
// ignore and try next controller
}
}
public class ProductController : Controller
{
public ActionResult Index(string url)
{
var productManager = new ProductManager();
var product= productManager.GetByURL(url);
if (product!= null)
{
return View(product);
}
// ignore and try next controller
}
}
public class UserController : Controller
{
public ActionResult Index(string url)
{
var userManager = new UserManager();
var user = userManager.GetByURL(url);
if (user != null)
{
return View(user);
}
// ignore and try next controller
}
}
示例:
routes.MapRoute("Category", "{*url}", new { controller = "Category", action = "Index" });
routes.MapRoute("Product", "{*url}", new { controller = "Product", action = "Index" });
routes.MapRoute("User", "{*url}", new { controller = "User", action = "Index" });
public class CategoryController : Controller
{
public ActionResult Index(string url)
{
var categoryManager = new CategoryManager();
var category = categoryManager.GetByURL(url);
if (category != null)
{
return View(category);
}
// ignore and try next controller
}
}
public class ProductController : Controller
{
public ActionResult Index(string url)
{
var productManager = new ProductManager();
var product= productManager.GetByURL(url);
if (product!= null)
{
return View(product);
}
// ignore and try next controller
}
}
public class UserController : Controller
{
public ActionResult Index(string url)
{
var userManager = new UserManager();
var user = userManager.GetByURL(url);
if (user != null)
{
return View(user);
}
// ignore and try next controller
}
}
当URL为/computers时:
- CategoryController找到类别实体并返回正确的视图李>
- CategoryController找不到类别并忽略李>
- ProductController找到产品实体并返回正确的视图李>
- CategoryController找不到类别并忽略李>
- ProductController未找到产品并忽略李>
- UserController找到用户实体并返回正确的视图李>
注意:我希望每个控制器都有一个控制器,以便更好地组织工作。从逻辑上讲,这没有多大意义。但是,您可以创建一个控制器和部分控制器,并根据您的结构将其创建到不同的文件中,然后使用一个索引方法,该方法将继续下去,然后返回正确的视图
// Category.cs
public partial MainController :
// Product.cs
public partial MainController :
// User.cs
public parital MainController :
MainController.cs将有一个索引方法,可以根据URL从每个文件调用一个方法
public ActionResult Index(string url){
// Logic for determining which method to call in the specific file here
}
这允许您通过拥有单独的文件但只有一个控制器来拥有组织边界。但我不认为我会推荐它 本文可能会帮助您: 基本上,您可以创建路由约束,这些约束是指定是否应执行路由的规则。您以前在路线中设置这些,但最近它们已更改为属性:
routes.MapRoute(
name: "ProductPage",
url: "{productId}/{productTitle}",
defaults: new { controller = "Products", action = "Show" },
constraints: new { productId = "\\d+" }
);
[Route("{productId:int}/{productTitle}")]
public ActionResult Show(int productId) { ... }
属性:
routes.MapRoute(
name: "ProductPage",
url: "{productId}/{productTitle}",
defaults: new { controller = "Products", action = "Show" },
constraints: new { productId = "\\d+" }
);
[Route("{productId:int}/{productTitle}")]
public ActionResult Show(int productId) { ... }
当然,这不是编写约束的唯一方法。MVC的每个版本都有这种能力。需要注意的是,在使用这些函数时要小心,不要通过编写查询数据库的函数无意中引入性能问题。如果需要(例如,在捕获路由之前测试对象是否存在),则缓存值
祝你好运 据我所知,基本路由库中没有内置该功能 您需要创建一个新的自定义路由类,该类继承RouteBase,并在未能获得命中时从GetRouteData覆盖返回
null
。返回null将允许回退到下一个路由处理程序
例如:
public class CategoryRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
if (we dont find our category)
return null;
else
{
var routeData = new RouteData(this, new MvcRouteHandler());
routeData.Values.Add("controller", "Category");
routeData.Values.Add("action", "Index");
routeData.Values.Add("url", catUrl);
return routeData;
}
}
}
然后,不调用MapRoute,只需调用Add,如下所示:
routes.Add("CategoryRoute", new CategoryRoute());
一种简单但可能不是非常有效和健壮的方法是在控制器中路由到一个通用操作,在这里您可以确定实际操作。它看起来像这样:
public class CommonController : Controller
{
public ActionResult GenericUrl(string url)
{
if (url is a category)
{
return RedirectToAction("Index", "Category", new { categoryId = id });
}
if (url is a product)
{
return RedirectToAction("Index", "Product", new { productId = id });
}
if (url is a user)
{
return RedirectToAction("Index", "User", new { userId = id });
}
return HttpNotFound(); // Might also be the homepage for example.
}
}
您只需定义一条路线:
routes.MapRoute("", "{*url}", new { controller = "Common", action = "GenericUrl"});
它也是在数据库中维护“slug”表的一个选项,在该表中,您可以查找slug并检索其关联的实体类型、唯一id和控制器/操作。有一个使用自定义路由类型的实现。谢谢你的回答,我尝试过,但效果很慢,路由类上的数据库调用无法重用。我想了一下,但似乎很疯狂。我不认为我也会推荐它。这种方式需要URI的前缀。你读过我发送的链接吗?它解释了路线约束并给出了示例。我猜你不是在寻找努力。享受你的黑客解决方案。我认为简单的方法是最好的方法。。。总是。你说得对!“slug”表将大大减少对数据库的调用,是保持唯一URI的好方法。我将改变我的实体。谢谢你的建议。