MVC动态更改ViewName

时间:2015-08-11 20:07:30

标签: c# asp.net-mvc-3

我有一个项目,我想向Desktop e Mobile用户展示不同的视图,主要是为了获得更好的体验和速度。现在我使用 51degrees 告诉我,如果请求来自移动或桌面用户,然后在我的操作过滤器中,我将更改视图名称来自& #34;指数"对于" Index.Mobile",问题是我在使用“视图”时遇到了一些问题,我根本不想使用布局。

这是我的方法:

public override void OnActionExecuted( ActionExecutedContext filterContext )
{
    var result   = filterContext.Result as ViewResult;
    var view     = filterContext.ActionDescriptor.ActionName;

    //IsMobile is filled on my OnActionExecuting method
    var IsMobile = filterContext.Controller.ViewBag.IsMobile;

    if( result == null ) return;

    string viewName;
    string masterName;

    if( IsMobile )
    {
        viewName   = view + ".Mobile";
        masterName = "_Layout.Mobile";

        //Check if view exists
        var viewResult = ViewEngines.Engines.FindView( filterContext.Controller.ControllerContext, viewName, null );

        if( viewResult.View == null )
        {
            viewName = view;
        }
    }
    else
    {
        viewName   = view;
        masterName = "_Layout";
    }

    result.ViewName   = viewName;
    result.MasterName = masterName;
}

会发生什么情况,这里我为 MasterName 布局设置一个值,在两个特定的控制器我需要将其设置为< strong> null 但它仍然提取我之前设置的布局

我需要的是,此方法将设置视图和布局名称,如果需要,我将在我加载的视图中将Layout设置为null。

能做到吗?

修改

我尝试实现另一种方法Link,但我无法找到更改布局视图的方法,只能更改操作。

3 个答案:

答案 0 :(得分:1)

您可以在项目中创建一个文件夹,例如“区域/移动”,并保留您的视图,控制器甚至模型(移动设备的视图模型)。您只需创建一个路由规则,将来自移动设备的请求传递到“区域/移动”内的控制器。管理和构建移动版本的网站会容易得多。

答案 1 :(得分:1)

经过一些调试后,我发现设置View内的值并不起作用,因为ViewEngine会忽略这个新值,并保留OnActionExecuted方法设置的值

我设法使用相同的方法解决了我的问题,但添加了ViewBag,告诉我这个特定视图是否需要布局。由于OnActionExecuted将在Controller之后和View之前执行,因此可以在Controller将值设置为true / false,然后在内部读取OnActionExecuted

这是工作示例:

public override void OnActionExecuted( ActionExecutedContext filterContext )
{
    var result   = filterContext.Result as ViewResult;
    var IsMobile = filterContext.Controller.ViewBag.IsMobile;
    var view     = filterContext.ActionDescriptor.ActionName;

    if( result == null ) return;

    string viewName;
    string masterName;
    bool hasLayout = filterContext.Controller.ViewBag.HasLayout ?? true;

    if( IsMobile )
    {
        viewName   = view + ".Mobile";
        masterName = hasLayout ? "_Layout.Mobile" : null;

        //Check if new view exists
        var viewResult = ViewEngines.Engines.FindView( filterContext.Controller.ControllerContext, viewName, null );

        if( viewResult.View == null )
        {
            viewName = view;
        }
    }
    else
    {
        viewName   = view;
        masterName = hasLayout ? "_Layout" : null;
    }

    result.ViewName = viewName;
    result.MasterName = masterName;
}

如果有人有更好的选择,请分享,这种解决方法看起来不错,但感觉有点不对。

答案 2 :(得分:1)

要动态更改视图名称,您也可以使用它,这很简单

 public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsLocal)
            {
                filterContext.Result = new ViewResult { ViewName = "Index" };
            }
        }

这对我有用:)