MVC 3 Razor _ViewStart中的公共变量

时间:2010-11-27 11:24:09

标签: global-variables asp.net-mvc-3 razor

我正在使用MVC 3附带的新Razor引擎构建一个站点(并且喜欢新语法!)。但是,我对使用公共属性/常量感到茫然。我知道使用WebForms我们可以在代码中添加一个公共属性:

public string ImageFolder { get; set; }

我想在我的视图可以访问的一个全局位置定义重要变量,从CSS文件和图像的路径开始:

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

我已尝试将上述代码块放在_Layout以及_ViewStart内。但是,从子视图访问它们失败了。我想过在上面的代码块中定义一个公共属性但是它没有编译。

解决方案?

  • 据我所见,没有人使用Razor背后的代码。
  • 我想我应该能够从默认视图继承并在那里定义我的属性(如described on Stack)。

但我强烈希望有一种更简单的方法来做这么简单的事情?

6 个答案:

答案 0 :(得分:5)

您可以创建一个文件夹“App_Code”并创建一个文件“GlobalVal.cshtml”。 bellow是文件中的示例代码:

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

和下面是使用它的示例:

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

答案 1 :(得分:4)

我决定关注另一条路径,并扩展UrlHelper以提供我认为可能需要的所有三个文件夹的路径:

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

一切都好......几乎:-)我现在想知道是否有一个地方我可以定义using MyNamespace.Helper语句,以便这些扩展方法可用于应用程序 - 宽。在过去,我们将在web.config中添加一个条目:

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

这似乎不适用于Razor :-(我尝试在_ViewStart.cshtml中添加一个using语句,但也没有运气 - 我的扩展方法可见的唯一方法是在a上添加一个using语句特定的页面,这也是不理想的。

有什么建议吗?你有没有看过Razor的页面解析顺序和解释递送

答案 2 :(得分:1)

使用PageData属性:

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

_Layout.cshtml:

<%=PageData["ContentFolder"]%>

答案 3 :(得分:1)

在_layout视图中

@{
App.AnyName = "abc";
}

在继承视图中

@{

    var anyVariable = App.AnyName;

}

答案 4 :(得分:0)

只需将常量放在app_code文件夹中的公共模块中,或者如果您不想这样做,只需在app_code中创建一个clasas并使用using(imports)关键字在每个中导入命名空间(类名)查看,你可以这样使用它。

或者,如果这样做有意义,只需将它们添加到视图模型中 - 请记住,将这些变量添加到模型中可能没有意义,但将它们添加到视图模型中是有意义的!这是视图模型的用途,此视图模型可以从公共模块或类中获取常量值,或者您甚至可以在实际视图模型中设置它,这样您只能在一个地方定义值并且您不需要在每个视图中使用任何名称空间导入:)

让我知道它是怎么回事,以及我还能做些什么来帮助你。

在vb.net中但与csharp相同且易于理解,因为它是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

现在,您必须将MyNormalModel的值设置为当前模型实例,尽管您可以在ur控制器中执行此操作,但最佳做法是在MyViewModel类中创建一个方法,该方法将当前模型的副本作为参数,并且将MyNormalModel设置为我们刚刚在参数中传递的当前模型。

你仍然可以在你的控制器中进行调用,但另一方面,人们更喜欢做的是,而不是将整个普通模型作为属性传递,只需从正常模型中获取所需的部分和部分,将它们放入视图中(即:您可能只需要将普通模型中的一半属性放在视图模型中)。这是因为,请记住,视图模型将传递给视图,他们不想传递他们不会使用的东西:)。但这意味着您将需要逐个设置每个属性(除非那些确切的属性封装在通常不会偶然发生的子类中)。

我把它保存在一个中,所以你可以一次性复制普通模型,以简化。

现在,当您将视图模型传递给视图(MyViewModel)时,您将能够通过对象表示法及其属性使用和访问常规模型,例如...... Model.MyNormalModel.Property1。等等,在视图中用它做你想做的任何事情......另外,你可以访问你的视图模型的其余部分(我们设置的const值),如... Model.MyPathConstant1和Model.MyPathConstant2等......所以您可以访问几乎所有您想要的东西,普通模型以及您之后通过现在称为视图模型添加的任何其他内容。

请原谅typos-writing和ipad lol。如果这更有意义,请告诉我。

答案 5 :(得分:0)

您可以使用UrlHelper Content的内置属性:

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