@model for _layout.cshtml on MVC4?

2020-03-01 20:24发布

问题:

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

回答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);
    });
});


回答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.



回答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.



回答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;
}