在ASP.NET MVC中使用全局变量

时间:2015-10-15 11:34:52

标签: c# asp.net-mvc

首先看一下示例控制器代码。在那里,你会发现两个重复的陈述 -

public class DashboardController : Controller
{
    //the following line is repetitive for every controller.
    String ConnectionString = WebConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
    public ActionResult Index()
    {
        try
        {
            //codes
        }
        catch (Exception Ex)
        {
            //The following line is repetitive for every action method.
            var path = HttpContext.Server.MapPath("~/App_Data");
            ExceptionLog.Create(Ex, path);
        }
        return View("AdminDashboard");
    }
}

我想避免这种重复。有没有办法可以将整个应用程序用作全局变量?

4 个答案:

答案 0 :(得分:4)

如果是我,并且我需要访问频繁的配置选项,我会创建/公开某些IAppConfiguration,我可以将其放入我的控制器(使用依赖注入)。类似的东西:

public interface IAppConfguration
{
    String MyConnectionString { get; }
    String ServerPath { get; }
}
public class AppConfiguration : IAppConfiguration
{
    private readonly HttpContext context;
    public AppConfiguration(HttpContext context)
    {
        this.context = context;
    }

    public String MyConnectionString
    {
        get { return COnfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
    }
    public String ServerPath
    {
        get { return context.Server.MapPath("~/"); }
    }
}

然后你可以针对不同的情况,子站点/区域等扩展它。然后,通过控制器的构造函数将其引入:

public class MyController : Controller
{
    private readonly IAppConfiguration config;
    public MyController()
        : this(new AppConfiguration(HttpContext.Current))
    {
    }
    public MyController(IAppConfiguration config)
    {
        this.config = config;
    }

    // reference config.ServerPath or config.MyConnectionString;
}

更进一步,您可以在此处添加工厂,将其作为参考,并允许您获取其他环境的配置设置。 e.g。

IAppConfiguration config = configFactory.GetConfig(/* environment */);

我喜欢这种方法的东西允许我替换本地[单元/集成]测试的设置。使用基本控制器/静态类将很难在以后替换这些值。

答案 1 :(得分:3)

以下是使用基本控制器方法的示例:

public abstract class BaseController : Controller
{
    protected string ConnectionString = WebConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;

    protected void LogException(Exception ex)
    {
        var path = HttpContext.Server.MapPath("~/App_Data");
        ExceptionLog.Create(Ex, path);
    }    
}

public class DashboardController : BaseController
{
    public ActionResult Index()
    {
        try
        {
            string conn = base.ConnectionString;
            //codes
        }
        catch (Exception ex)
        {
            base.LogException(ex);
        }
        return View("AdminDashboard");
    }
}

答案 2 :(得分:1)

为避免异常捕获,您可以将其记录在global.asax.cs中的OnError事件处理程序中:

protected void Application_Error(object sender, EventArgs e)
{
    HttpContext ctx = HttpContext.Current;

    Exception ex = ctx.Server.GetLastError();

    var path = HttpContext.Server.MapPath("~/App_Data");
    ExceptionLog.Create(Ex, path);
}

你可以使用连接字符串名称" MyConnectionString"将其传递给dbcontext或ADO Connection时,而不是WebConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString

但更合适的方法是在控制器类中注入(使用依赖注入),它将负责与数据库一起工作,而不是在控制器中创建它并传递连接字符串。

答案 3 :(得分:0)

您可以继承控制器,然后将其用于所有其他控制器,查看类似的问题How can I inherit an ASP.NET MVC controller and change only the view?

但是这只能在控制器中访问,你也可以使用静态方法或属性创建一个返回连接字符串的类。这可以在您有权访问该类的任何代码路径中使用。