在MVC _Layout.cshtml页面中设置背景

时间:2015-03-14 17:26:20

标签: asp.net-mvc url razor background-image

在ASP.Net WebForms中设置每个页面的背景相当简单,您可以在MasterPage的代码隐藏中访问Page_Load事件但是如何在MVC中最好地完成?在花了几个小时研究各种替代方案后,我选择通过" base"将值分配给ViewBag。 controller,从该基础派生后续控制器,然后在_Layout.cshtml中访问该值。

这是基本控制器,我在其中指定一个指向特定图像的URL:

public class BaseController : Controller
{
    public BaseController()
    {
        ViewBag.url = BingImageLoader.getBingImageUrl();    
    }
}

下一步是派生后续控制器,在本例中是来自该基类的HomeController:

public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return View();
    }
    .
    .

最后,使用_Layout.cshtml的head元素中的ViewBag来设置背景图像样式属性。

    .
    .   
    <style type="text/css">
        body {
            background-image: url(@ViewBag.url);  
            background-repeat: no-repeat;
            background-size: cover;
        }
    </style>
</head>

这确实完成了我的目标;但是,在此过程中还有许多替代方案,包括使用ActionFilters。老实说,创建​​一个CustomActionFilter并使用ActionFilterAttributes并重写OnActionExecuting似乎有点矫枉过正,但有时候最简单的方法并不总是最好的。

最终,问题归结为&#34;有更好的方法吗?&#34;引入中间人是否有副作用?如果我在各个控制器方法中覆盖我的ViewBag.url,则图像会相应更改。所以我还没有发现任何问题,但这种方法可能会产生其他问题。

再次,&#34;有更好的方式&#34;?

1 个答案:

答案 0 :(得分:2)

我可以通过这种方法看到的一个可能的问题是开发人员是否忘记从BaseController继承hist控制器。

使用global action filter将确保永远不会发生这种情况,并且该属性将始终可用:

public class BackgroundImageFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        context.Controller.ViewBag.url = BingImageLoader.getBingImageUrl();
    }
}

只会在Application_Start

中注册一次
protected void Application_Start()
{
    ...
    // Register global filter
    GlobalFilters.Filters.Add(new BackgroundImageFilterAttribute());
}

如果您发现这种过滤方法很麻烦,我可以建议您编写一个可以在_Layout.cshtml中使用的自定义Html帮助程序:

<style type="text/css">
    body {
        background-image: url(@Html.GetBackgroundImageUrl());
        background-repeat: no-repeat;
        background-size: cover;
    }
</style>

可能被定义为一个简单的扩展方法:

public static class HtmlExtensions
{
    public static IHtmlString GetBackgroundImageUrl(this HtmlHelper html)
    {
        string url = BingImageLoader.getBingImageUrl();
        return new HtmlString(url);
    }
}