共享视图的MVC路由优先级

时间:2016-02-23 19:53:27

标签: c# asp.net-mvc routing

我的解决方案在不同的文件夹位置共享具有相似名称的视图

public class AreaViewEngine : WebFormViewEngine
{
    public AreaViewEngine() : base()
    {
        ViewLocationFormats = new[] {
            "~/Views/Shared/{0}.ascx",
            "~/Views/Dashboard/Shared/{0}.ascx"
        };

        MasterLocationFormats = new[] {
            "~/Shared/{0}.master"
        };

        PartialViewLocationFormats = ViewLocationFormats;
    }
}

我正在扩展 WebFormViewEngine 以定义用于路由的视图引擎

CREATE TABLE #case_sensitivity_training (my_str VARCHAR(40) NOT NULL)

INSERT INTO #case_sensitivity_training (my_str)
VALUES ('AABWcFABmAAAyWJAAb'), ('AABWcFABmAAAyWJAAB')

SELECT
    my_str COLLATE SQL_Latin1_General_CP1_CS_AS,
    COUNT(*)
FROM
    #case_sensitivity_training
GROUP BY
    my_str COLLATE SQL_Latin1_General_CP1_CS_AS
HAVING
    COUNT(*) > 1

这会导致名称相似的视图出现问题。如果网址包含 / Dashboard /

,我想将更高优先级设置为〜/ Views / Dashboard / Shared / {0} .ascx

任何人都知道怎么做?或者是否意识到处理这种情况的更好方法?

1 个答案:

答案 0 :(得分:-1)

您可以覆盖自定义ViewEngine类中的FindView方法,并在回退到默认行为之前查找包含URL片段的匹配项。

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
    var fragment = ... // access URL via controllerContext
    var preferred = ViewLocationFormats.Where(x => x.Contains(fragment)).ToList();
    // return retult from preferred or fall back to base.FindView
}
但是,我不是这种方法的忠实粉丝。如果需要视图为“可覆盖”,则可以简单地使其输出有条件或依赖于模型值,例如向视图模型添加DiscountView属性,然后使用此属性的值来决定视图应该发出的内容。

如果您想要的是“聪明的命名冲突处理”,那么我建议使用T4MVC。它允许您专门引用您的视图而不使用魔术字符串,解决了同名多个视图可能导致的任何歧义。