@model for _layout.cshtml on MVC4?

14,091

Solution 1

Even though you already accepted an answer, based on your saying you are just pulling an image URL you should do it using JQuery, not a model.

This code is untested, apologies for that. Feel free to point out if I typed a bug. The HTML element containing the background image has the id="url" attribute so the selectors work.

Controller

[HttpGet]
public string GetSessionUrl()
{
    //logic to detmine url
    return url;
}

JQuery

$(document).ready(function () {
    var $url = $('#url');
    var options = {
        url: "/Home/GetSessionUrl",
        type: "get",
        async:false
    };

    $.ajax(options).done(function (data) {
        $url.attr('src', data);
    });
});

Solution 2

You should delegate the parts of your layout that "need a model" to a separate controller using partial views and RenderAction:

@Html.RenderAction("SomeAction", "LayoutController")

Have LayoutController.SomeAction return a PartialViewResult, which you can then strongly type to a model.

Solution 3

You can add BaseModel to _Layout.

@model BaseModel

Then all models inherit from that BaseModel class.

public class MyModel : BaseModel
{
}

As others stated, it is not a good practice. If your model forgets to inherit from BaseModel, it'll throws exception at run time. However, it is up to you.

Solution 4

In BaseController you can declare any model as property.

public class BaseController : Controller
{
    public BaseController ()
    {
        MyTag = new TagModel ();  // or get db, take any value from there           
    }

    public TagModel MyTag { get; set; }
}

In action:

ViewBag.MyTag = MyTag ;

And in _Layout.cshtml, you can use

@{
  var myTag = (TagModel)ViewBag.MyTag;
}
Share:
14,091
leandro koiti
Author by

leandro koiti

Updated on July 24, 2022

Comments

  • leandro koiti
    leandro koiti almost 2 years

    I was wondering if there's a way to specify a model for the _layout.cshtml file, i've seen lots of posts with the basic same question with people replying with "alternative" solutions, not saying it's not possible nor showing how exactly we could achieve this

    having some experience with webforms I've been trying to migrate to MVC and often find myself with such questions, I've found this website: http://blog.bitdiff.com/2012/05/sharing-common-view-model-data-in.html which partially solved my problem but even them don't bind their _layout.cshtml with a @model, as far as I know, I have to specify a model on each view if I want to access the SharedContext, please correct if I'm wrong

    what I wanted to do is declare a "@model Namespace.MyModel" on _layout.cshtml so it could retrieve its information by itself, instead of having to implement a model for each view inherinting from the LayoutModel

    *I hope I'm being clear, basically, I wanted to know how can I declare @model tag on a _layout.cshtml so it can access its own model

    with the solution I linked before (even though it's not linked to my question) I have to do: @(((BaseController)ViewContext.Controller).Context.Property) to get the shared information, and if I could simply declare (and use) a @model instead, I could accomplish the same thing by doing something like: @Model.Property*

    as you can see, im struggling trying to migrate whatever I already know from webforms to MVC and it's being quite difficult for me since I have to adopt certain practices which are completely different from what I'm used to

    thanks in advance

  • leandro koiti
    leandro koiti almost 11 years
    thank you Ant P, I guess it is the same thing as Jasen commented, so I went through that direction, I have a child action which renders the section I need inside the _layout file and so I didn't have to tie my layout with a model and now I have a child action that simply renders what I need inside the layout, I guess this is the best solution, thanks a lot!
  • leandro koiti
    leandro koiti almost 11 years
    hey Jhoon, although I really liked your idea I went to the direction noted by Ant P and Jasen and decided to create a child action, thanks a lot for the idea though, I really appreciate the help!
  • leandro koiti
    leandro koiti almost 11 years
    hey Win, thx a lot, since I'm trying to avoid bad practices I went to the direction pointed by Jasen and Ant P and created a child action to render what I needed inside the _layout file, thanks a lot for your help!
  • leandro koiti
    leandro koiti almost 11 years
    hey James thanks again for taking your time, I switched to your answer because you stated that a model is not suited for this job in particular, and Ant P solved my problem on a broader scope, I wish I could choose both as answers since they both solve my problem in two different ways, but since you solved specifically what I was trying to achieve I selected yours and I really thankful for your help, that code did the job, just needed to add () after "function" on the first line of the JS hehe
  • Ant P
    Ant P almost 11 years
    You're welcome - Jasen's is a solid answer; I hadn't read through all the comments.