在哪里写连接字符串?在app.config或web.config中?

时间:2014-04-29 11:42:42

标签: c# asp.net asp.net-mvc

我正在开发MVC应用程序。 我的申请中有两个项目。 一个是MVC应用程序包含,Controller和Views,第二个是DataLayer项目。

我对编写连接字符串的位置感到困惑,因为在发布应用程序时它会获取web.config文件并从DataLayer项目中获取数据,因此我应该在app.config / Web.config中添加连接字符串数据层项目?

另外,想知道app.config和web.config之间的目的和区别是什么?

4 个答案:

答案 0 :(得分:7)

每个项目在创建时都附带一个配置文件。通用类库有一个名为app.config的通用库。 Web项目更具体,因此其文件名为web.config,并附带特定于Web的参数。它们都有同样的目的。

您面临的问题是默认情况下仅部署可执行项目的配置文件(web.config)。您有几个选择:

  1. 将您的连接字符串添加到web.config并将其传递给您的数据层。这很简单(最常见),但将配置信息与数据层项目分开。
  2. 让您的数据层使用System.Configuration.ConfigurationManager读取web.config。这可以减轻您将数据传递到数据层的影响,但会产生强依赖性(如果没有格式正确的web.config文件,您的数据层将无法工作)。
  3. 将app.config部署为XML内容并编写自定义代码,以便您的数据层可以读取它。这是更多的工作,但它从Web配置中获取您的数据配置。
  4. 稍微更改为#2,您可以在web.config中创建名为“dataLayer”的custom config section。这可以通过System.Configuration.ConfigurationManager阅读。我更喜欢这种方法,因为它似乎是一种很好的平衡。您在“默认”配置文件中有一个自定义强类型配置部分。
  5. related question也有一些好消息。

答案 1 :(得分:3)

连接字符串位于Web.config中。默认情况下,它将查看正在执行的程序集的配置,并忽略引用程序集的配置文件。

可以在设计时使用引用的程序集的配置文件。例如,如果您在数据层程序集中使用Entity Framework,它将存储用于从app.config中的数据库构建模型的连接信息。

当我到达Web项目将要运行并通过数据层访问数据时,我通常只是将连接信息复制到web.config。

答案 2 :(得分:3)

  • Web.Config用于asp.net Web项目/ Web服务。
  • App.Config用于Windows窗体,Windows服务,控制台 应用和WPF应用程序。

数据层项目

Web.config中添加您的连接字符串

答案 3 :(得分:1)

我先回答你的问题,然后再继续讨论,IMO是一个更重要的考虑因素。对于这个特定的用例,我更喜欢DI模式,其中消费者告诉提供者连接字符串是什么。这使您的数据层与数据库无关,并允许它与满足其合同的任何数据存储进行通信。简而言之,由于您的MVC项目是数据层的使用者,因此连接字符串存储在web.config中。 BUT IT IS STORED ENCRYPTED!!!

现在,这里实际上存在一个比你实际编写连接字符串更深层次的问题,那就是在你的消费代码和配置存储之间建立一个抽象。如果这样做,存储配置值的位置变得基本无关紧要。

我总是在每个图层(项目)中创建一个Configuration类,它提供该图层中消耗的配置值。这提供了几个好处:

  1. 在使用时允许使用强类型值。如果您的配置值是int,那么您将得到一个int,并且在使用它时不需要转换它。
  2. 它允许可能无意中遗漏配置文件的默认值。这使您的代码更加健壮。
  3. 它允许您存储值的灵活性。您可以在配置文件中放置一些值,在数据库中放置其他值,还可以从远程Web服务获取更多值。如果您决定更改商店,则只需在一个地方编辑代码 - 而不是每个地方都会使用该值。
  4. 随着您的解决方案的增长和项目的增加,模式可以很好地扩展并保持配置隔离。
  5. 它会从您的代码中删除魔术字符串。
  6. 而不是以下,它有一个令人讨厌的魔术字符串:

    return System.Configuration.ConfigurationManager.AppSettings["DefaultUserName"];
    
    你会写

    MyApp.Configuration.DefaultUserName
    

    这是一个非常基本的实现示例,它返回一个强类型(在本例中为DayOfWeek)。它有一个帮助方法来帮助您抽象从商店拉出的行为。如果您需要包含多个商店,则此方法将采用类型T的泛型,其中T是商店的类型。在下面的简化示例中,它只是从配置文件中提取:

     public class Configuration
        {
            private const DayOfWeek FailsafeDefaultDayOfWeek = DayOfWeek.Saturday;
    
            /// <summary>
            /// A default for the day of week
            /// </summary>
            public static DayOfWeek DefaultDayOfWeek
            {
                get
                {
                    string dayOfWeekString = GetSettingValue("DefaultDayOfWeek");
    
                    try
                    {
                        return (DayOfWeek)Enum.Parse(typeof(DayOfWeek), dayOfWeekString);
                    }
                    catch (Exception)
                    {
                        // If someone screws up and forgets to include a value, or the value cannot be cast:
                        return FailsafeDefaultDayOfWeek;
                    }
                }
            }
    
            /// <summary>
            /// Helper method to easily pull a value from a configuration store.
            /// </summary>
            /// <param name="settingName"></param>
            /// <returns></returns>
            private static string GetSettingValue(string settingName)
            {
                try
                {
                    return System.Configuration.ConfigurationManager.AppSettings[settingName];
                }
                catch (Exception)
                {
                    throw new MissingConfigurationValueException(settingName);
                }
            }
        }