Thorsten Westheider
Thorsten Westheider

Reputation: 10932

Can I no longer pass ViewData to _Layout.cshtml in MVC Core 1.0?

I'm trying to pass a URL for a background image to my _Layout.cshtml,

public HomeController()
{
    this.ViewData["BackgroundImage"] = "1920w/Stipula_fountain_pen.jpg";
}

and

<body style="background-image: url(@(string.Format("assets/images/{0}", ViewData["BackgroundImage"])))">
    ...
</body>

but ViewData is always empty inside _Layout.cshtml. Is that working as intended? I'd rather not go down the BaseViewModel/BaseController route as that feels like overkill.

EDIT: It seems as if ViewData set in the constructor isn't actually used, because once an action is executing the collection is empty. If I set ViewData inside the action then that data is passed on to _Layout.cshtml - feels like a bug to me.

Upvotes: 3

Views: 2190

Answers (2)

Thorsten Westheider
Thorsten Westheider

Reputation: 10932

Expanding on adem caglin's answer I went with this filter attribute, which can take an arbitrary URL:

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method, AllowMultiple = false)]
public class SetBackgroundUrlAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        if (!string.IsNullOrWhiteSpace(this.Url))
        {
            var result = filterContext.Result as ViewResult;

            if (result != null)
                result.ViewData["BackgroundImage"] = this.Url;
        }
    }

    public string Url { get; set; }
}

and is used like so:

[SetBackgroundUrl(Url = "1920w/Stipula_fountain_pen.jpg")]
public class HomeController : Controller
{
    ...
}

Upvotes: 1

adem caglin
adem caglin

Reputation: 24123

You can use an action filter to set ViewData for all controller actions:

public class SetBackgroundUrlAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.ViewData["BackgroundImage"] = "1920w/Stipula_fountain_pen.jpg";
        }
    }
}

[SetBackgroundUrl]
public HomeController()
{

}

Or just override OnActionExecuted method of the controller:

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        base.OnActionExecuted(context);
        var result = context.Result as ViewResult;
        if (result != null)
        {
            result.ViewData["BackgroundImage"] = "1920w/Stipula_fountain_pen.jpg";
        }
    }

Upvotes: 4

Related Questions