如何在ASP.NET MVC 3 Razor视图中访问应用程序变量?

30

我在global.asa.cs中使用以下代码设置了一个应用程序变量:

    protected void Application_Start()
    {
        ...

        // load all application settings
        Application["LICENSE_NAME"] = "asdf";

    }

然后我尝试像这样使用我的Razor视图进行访问:

@Application["LICENSE_NAME"]

并且收到如下错误:

Compiler Error Message: CS0103: The name 'Application' does not exist in the current context

什么是正确的语法?


应用程序变量?是指.config文件中的appSettings吗?(请更具体说明) - Brad Christie
4
@Brad,他的意思是应用程序状态变量,如果你看一下代码,就会非常明确。 - Sanjeevakumar Hiremath
@Brad: 我认为他指的是应用程序状态对象中的值。 - Misko
1
@Sanjeevakumar/@CodemOnkey:已经注意到了。谢谢。;-) - Brad Christie
@BradChristie 已经注意到了,哈!我看到你的点子了。 - Mike Devenney
7个回答

64

视图不应该从某个地方获取数据,它们应该使用从控制器操作以视图模型的形式传递给它们的数据。因此,如果您需要在视图中使用此类数据,则正确的方法是定义一个视图模型:

public class MyViewModel
{
    public string LicenseName { get; set; }
}

让您的控制器动作从任何需要填充它的地方填充它(为了更好的关注点分离,您可能会使用仓储库):

public ActionResult Index()
{
    var model = new MyViewModel
    {
        LicenseName = HttpContext.Application["LICENSE_NAME"] as string
    };
    return View(model);
}

最后,让您的强类型视图向用户显示此信息:
<div>@Model.LicenseName</div>

这是正确的MVC模式,也应该这样做。

避免像害虫一样拉取数据的视图,因为今天它可能是应用状态,明天可能是一个foreach循环,下周可能是一个LINQ查询,不久您就会在视图中编写SQL查询。


3
感谢您指出的不仅提供问题解决方案,而且更符合MVC模式的方法,这得到了我一个赞。 - Tomas Aschan
如果您需要重复使用某些代码,例如在页眉菜单中,您还可以创建单独的ActionResult来呈现部分视图。我需要从我的_Layout页面向PartialView发送一个模型,并希望重用代码。我遵循了这个模式,并使用了**@{Html.RenderAction("ActionName", "ControllerName");}**。该操作返回了一个部分视图。 - Josh Simerman
嗨,我使用相同的模式,但有些代码使用静态变量而不是应用程序状态。我真的很想知道什么是正确的方法? - Nuri YILMAZ
你如何为_layout视图设置数据? - Craig Schwarze
我认为应该加上 Current,变成 HttpContext.Current.Application["LICENSE_NAME"]](添加了Current),是吗? - xr280xr
1
这个解决方案真的帮助我理解了视图和控制器之间的分离。感谢您,先生,加一赞。顺便说一句,在SO上使用Linq查询的答案比不使用的答案更多...也许我们可以做些什么? - tfrascaroli

25
@HttpContext.Current.Application["someindex"]

6
您可以使用自动生成的 ApplicationInstance 属性 获取当前应用程序:
@ApplicationInstance.Application["LICENSE_NAME"]

然而,这种逻辑不应该出现在视图中。

这个代码是可以运行的,但是Visual Studio和/或Resharper并不喜欢它。即使它们不是最佳实践,IDE更喜欢@HttpContext.Current.Application["someindex"]这种写法。 - Josh Simerman

5

您应该能够通过HttpContext.Current.Application[]访问此内容,但是MVC最佳实践会建议您考虑通过您的视图模型进行传递。


4

在@Darin-Dimitrov提供的模式基础上,我将一个模型传递给了一个局部视图,然后将其加载到了_Layout页面中。

我需要在应用程序加载时从外部资源加载一个网页,该网页将用作跨多个站点的页眉导航。这是在我的Global.asax.cs文件中实现的。

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    Application["HeaderNav"] = GetHtmlPage("https://site.com/HeaderNav.html");
}

static string GetHtmlPage(string strURL)
{
    string strResult;
    var objRequest = HttpWebRequest.Create(strURL);
    var objResponse = objRequest.GetResponse();
    using (var sr = new StreamReader(objResponse.GetResponseStream()))
    {
        strResult = sr.ReadToEnd();
        sr.Close();
    }
    return strResult;
}

这是我用于局部视图的控制器操作。

public class ProfileController : BaseController
{
    public ActionResult HeaderNav()
    {
        var model = new Models.HeaderModel
        {
            NavigationHtml = HttpContext.Application["HeaderNav"] as string
        };
        return PartialView("_Header", model);
    }
}

我在_Layout页面中这样加载了部分视图。

<div id="header">
     @{Html.RenderAction("HeaderNav", "Profile");}
</div>

_Header.cshtml 这个部分视图非常简单,只是从应用程序变量中加载HTML。

@model Models.HeaderModel
@MvcHtmlString.Create(Model.NavigationHtml)

1
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RouteConfig.RegisterRoutes(RouteTable.Routes);

        var e = "Hello";
        Application["value"] = e;
    }

@HttpContext.Current.Application["value"]


0

我在MVC控制器中遇到了这个问题,不得不为它创建完全限定的HttpContext才能使其正常工作..

System.Web.HttpContext.Current.Application["VarName"]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接