sim*_*nwh 11 .net asp.net asp.net-mvc asp.net-mvc-4
我正在用ASP.Net MVC 4重写一个网站项目,我发现很难设置正确的路线.url结构不是RESTful或遵循控制器/操作模式 - 页面具有以下slug结构.所有slugs都保存在数据库中.
/country
/country/carmake
/country/carmake/carmodel
/custom-landing-page-slug
/custom-landing-page-slug/subpage
Run Code Online (Sandbox Code Playgroud)
例:
/italy
/italy/ferrari
/italy/ferrari/360
/history-of-ferrari
/history-of-ferrari/enzo
Run Code Online (Sandbox Code Playgroud)
因为Country
,Car Make
并且Car Model
是不同的模型/实体,我想有像CountriesController,CarMakesController和CarModelsController这样的东西,我可以处理不同的逻辑并从中呈现适当的视图.此外,我有自定义登录页面,可以有包含一个或多个斜杠的slugs.
我的第一次尝试是有一个全能的PagesController
,它将在数据库中查找slug并根据页面类型调用适当的控制器(例如CarMakesController
),然后执行一些逻辑并渲染视图.但是,我从未成功"调用"其他控制器并呈现适当的视图 - 而且感觉不对.
任何人都能指出我在正确的方向吗?谢谢!
编辑:为了澄清:我不想重定向-我要委派请求到不同的控制器,用于处理逻辑和呈现视图,取决于内容的类型(Country
,CarMake
等).
Smi*_*eek 25
由于您的链接看起来很相似,因此无法在路由级别将它们分开.但这里有个好消息:您可以编写自定义路由处理程序并忘记典型的ASP.NET MVC链接的解析.
首先,让我们附加RouteHandler
到默认路由:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Default", action = "Index", id = UrlParameter.Optional }
).RouteHandler = new SlugRouteHandler();
Run Code Online (Sandbox Code Playgroud)
这允许您以不同方式使用URL,例如:
public class SlugRouteHandler : MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var url = requestContext.HttpContext.Request.Path.TrimStart('/');
if (!string.IsNullOrEmpty(url))
{
PageItem page = RedirectManager.GetPageByFriendlyUrl(url);
if (page != null)
{
FillRequest(page.ControllerName,
page.ActionName ?? "GetStatic",
page.ID.ToString(),
requestContext);
}
}
return base.GetHttpHandler(requestContext);
}
private static void FillRequest(string controller, string action, string id, RequestContext requestContext)
{
if (requestContext == null)
{
throw new ArgumentNullException("requestContext");
}
requestContext.RouteData.Values["controller"] = controller;
requestContext.RouteData.Values["action"] = action;
requestContext.RouteData.Values["id"] = id;
}
}
Run Code Online (Sandbox Code Playgroud)
这里需要一些解释.
首先,你的处理程序应该派生MvcRouteHandler
自System.Web.Mvc
.
PageItem
代表我的DB结构,其中包含有关slug的所有必要信息:
ContentID
是内容表的外键.
GetStatic
是行动的默认值,在我的情况下很方便.
RedirectManager
是一个与数据库一起使用的静态类:
public static class RedirectManager
{
public static PageItem GetPageByFriendlyUrl(string friendlyUrl)
{
PageItem page = null;
using (var cmd = new SqlCommand())
{
cmd.Connection = new SqlConnection(/*YourConnectionString*/);
cmd.CommandText = "select * from FriendlyUrl where FriendlyUrl = @FriendlyUrl";
cmd.Parameters.Add("@FriendlyUrl", SqlDbType.NVarChar).Value = friendlyUrl.TrimEnd('/');
cmd.Connection.Open();
using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
if (reader.Read())
{
page = new PageItem
{
ID = (int) reader["Id"],
ControllerName = (string) reader["ControllerName"],
ActionName = (string) reader["ActionName"],
FriendlyUrl = (string) reader["FriendlyUrl"],
};
}
}
return page;
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用此代码库,您可以添加所有限制,异常和奇怪的行为.
它适用于我的情况.希望这有助于你的.
归档时间: |
|
查看次数: |
6260 次 |
最近记录: |