Public variables in MVC 3 Razor _ViewStart

与世无争的帅哥 提交于 2020-05-13 04:32:34

问题


I'm building a site on the new Razor engine that comes with MVC 3 (and loving the new syntax!). However, I am at a loss about using public properties / constants with it. I know that with WebForms we could add a public property in code behind:

public string ImageFolder { get; set; }

I would like to define important variables in one global place that my views can access, starting with paths to CSS files and images:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    var ContentFolder = "~/Content";
    var CssFolder = ContentFolder + "/Stylesheets";
    var ImageFolder = ContentFolder + "/Images";
}

I have tried putting the above code block in _Layout, as well as inside _ViewStart. However, accessing them from child views fails miserably. I thought of defining a public property in the above code block but it doesn't compile.

Solutions?

  • As far as I have seen, noone uses code behind with Razor.
  • I guess I should be able to inherit from the default view and define my properties there (as described on Stack).

But I'm strongly hoping that there should be an easier way to do something so simple?


回答1:


Your can create a folder "App_Code" and create a file "GlobalVal.cshtml". bellow is a sample code in the file:

@functions{
    public static readonly string __siteHome = "http://www.example.com";
    public static readonly string __siteResource = "http://resource.example.com";
}

and bellow is a sample using it:

<a href="@GlobalVal.__siteHome/home/index">@GlobalVal.__siteHome</a>



回答2:


I decided to follow yet another path, and extended UrlHelper to provide paths to all three folders I think I might need:

public static class ExtensionMethods
{
    private const string ImagesFolder = "~/Images";
    private const string StylesheetsFolder = "~/Stylesheets";
    private const string ScriptsFolder = "~/Scripts";

    public static string Images(this UrlHelper url)
    {
        return url.Content(ImagesFolder);
    }

    public static string Stylesheets(this UrlHelper url)
    {
        return url.Content(StylesheetsFolder);
    }

    public static string Scripts(this UrlHelper url)
    {
        return url.Content(ScriptsFolder);
    }
}

All good to go... almost :-) I'm now wondering if there's a place where I would be able to define the using MyNamespace.Helper statement would go in order for these extension methods to be available application-wide. In the old days we would add an entry in web.config:

<system.web>
    <pages>
        <namespaces>
            <add namespace="MyNamespace.Helper"/>
        </namespaces>
    </pages>
</system.web>

This doesn't seem to work with Razor :-( I tried adding a using statement in _ViewStart.cshtml but no luck either - the only way for my extension methods to be visible is to add a using statement on a particular page, which again isn't ideal.

Any suggestions? Have any of you seen an explanation of Razor's order of page parsing & delivery?




回答3:


Use the PageData property:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    PageData.Add("ContentFolder", "~/Content");
}

and inside _Layout.cshtml:

<%=PageData["ContentFolder"]%>



回答4:


In _layout view

@{
App.AnyName = "abc";
}

In Inherit view

@{

    var anyVariable = App.AnyName;

}



回答5:


Just place the constants in a public module inside your app_code folder, or if you don't want to do that just create a clasas in app_code and use the using (imports) keyword to import the namespace (class name) in each view and you can use it that way.

Alternatively, if it makes sense to do so, just add them in your view model - remember, it might not make sense to add those vars to your model, but it can make sense to add them to your view model! This is what the view model is for, and this view model can grab the constant values from a public module or class or you can even set it in your actual view model itself, this way you will only define the values in one place and you don't need to use any namespace imports into each view :)

Let me know how it goes and if there is anything else I can do to help you out.

In vb.net but same as csharp and its easy to understand since it's vb.

Public class YourModel

    // this is where you have the normal model you have... No big deal

End Class

...

// now you make the view model urself

...

Public class MyViewModel

    Public MyNormalModel as YourModel

    //notice we r declaring ur normal model as a variable, u can use a property instead

    Public MyPathConstant1 as string = "abc"

    Public MyPathConstant2 as string = "abc"

    Public MyPathConstant3 as string = "abc"

End Class

Now, you gotta set the value of MyNormalModel to ur current model instance, although you can do that in ur controller, it's best practice to create a method inside the MyViewModel class that takes a copy of ur current model as argument and does the setting of MyNormalModel to the current model we just passed in the argument.

You can still make that call in your controller, but on another note, what people prefer to do is, instead of passing the whole normal model as a property, the just take the bits and pieces they need from the normal model and place them into the view (ie: you might just need half the properties in the normal model to be in the view model). This is because, remember, the view model will be passed to the view and they don't wanna pass things they wont use :). But this means you are going to need to set each of those properties one by one most likely (unless those exact ones are encapsulated in a sub class which usually doesn't happen by chance lol).

I kept it in one so you can just copy the normal model over in one shot for simplicity.

Now when you pass the view model to your view (MyViewModel) you will be able to use and access the normal model through the object notation and it's properties, eg... Model.MyNormalModel.Property1. Etc and do whatever you want with it in the view... Also, you can access the rest of your view model (the const values that we set) like this... Model.MyPathConstant1 and Model.MyPathConstant2 etc... So you have access to practically everything you want, ur normal model and whatever else you added later on all through what is now called your view model.

Please excuse typos -writing from and ipad lol. Let me know if this is making more sense.




回答6:


You could use the built-in property of UrlHelper Content:

@Url.Content("~/Content/Stylsheets")
@Url.Content("~/Content/Images")


来源:https://stackoverflow.com/questions/4291381/public-variables-in-mvc-3-razor-viewstart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!