System.Data.SqlClient.SqlException: Cannot open database "OldFashionedDB" requested by the login. The login failed.
Login failed for user 'IIS APPPOOL\ASP.NET v4.0'.
由于完整的IIS作为服务运行,也许使用传统的基于服务的SQL Server Express是正确的方法?我们可以安装SQL Server 2012 Express RC 0并在其中创建OldFashionedDB数据库。我们甚至可以使用我们全新的SQL Server数据工具来做到这一点,因为它适用于任何SQL Server版本和版本。我们的连接字符串必须更改为:
Data Source=.\SQLEXPRESS;Initial Catalog=OldFashionedDB;Integrated Security=True
型 当然,与前面的情况一样,我们需要确保ApplicationPoolIdentity帐户可以访问我们的SQL Server Express示例。我们可以使用与之前相同的脚本:
型 之后,运行我们的Web应用程序再次带来了令人愉快的画面: 这种方法的缺点是什么?显然,我们失去了使用LocalDB的好处。安装SQL Server Express可能比安装LocalDB花费更多的时间,并且可能需要进行一些计算机清理才能成功。SQL Server Express安装程序可能会因损坏的WMI数据库、受污染的注册表或SQL Server或Visual Studio CTP和Beta留下的组件等问题而受阻。SQL Server Express将继续在后台运行,即使在不需要的时候,就像服务一样。
4条答案
按热度按时间jbose2ul1#
您应该使用LocalDB的共享示例功能。这两篇关于在完整的IIS中使用LocalDB的文章应该会给予你更多的信息。尤其是第二部分似乎相关,但第一部分也包含一些背景。
(note:原始链接不再可用,请使用archive.org代替)
原始(截至2019年3月不工作)链接:
hfwmuf9z2#
为了防止链接再次消失,我从文章中复制粘贴解决方案,以方便访问:
帖子一:
我们面临的问题是需要加载用户配置文件。这应该不难,因为每个IIS应用程序池都有一个名为加载用户配置文件的选项,可以在高级设置部分找到。不幸的是,在Windows 7的Service Pack 1中,事情变得稍微复杂一些。如KB 2547655中所述,启用loadUserProfile不足以完全加载用户配置文件,还需要启用setProfileEnvironment。这需要编辑applicationHost.config文件,该文件通常位于C:\Windows\System32\inetsrv\config中。按照KB 2547655中的说明,我们应该为应用程序池ASP.NET v4.0启用这两个标志,如下所示:
字符串
完成后,我们重新启动应用程序池,以确保应用新设置,并再次运行Web应用程序。
**我这边注意:**只要在applicationHost文件中找到“applicationPools”标签,并将这两个变量更新为true,就像这样:
型
就这样,保存文件并重新启动IIS池。
帖子二:
私有示例问题
我们可以看到,我们面临着以下错误:
型
这一次的错误是非常明显的。LocalDB已启动,Web应用程序能够连接到它,但连接随后因登录失败而终止。IIS应用程序池的ApplicationPoolIdentity帐户(在本例中为IIS APPPOOL\ASP.NET v4.0)无法登录到LocalDB示例,因为未找到连接字符串(OldFashionedDB)中指定的数据库。多么奇怪,因为使用相同的连接字符串从Visual Studio连接成功!
为什么Visual Studio可以很好地连接到LocalDB,而Web应用程序的连接却失败了?在这两种情况下,连接字符串如下所示:
型
答案是这里有两个不同的LocalDB示例。与作为Windows服务运行的SQL Server Express示例不同,LocalDB示例作为用户进程运行。当不同的Windows用户连接到LocalDB时,他们最终会为每个用户启动不同的LocalDB进程。当我们从Visual Studio连接到**(localdb)\v11.0时,会为我们启动一个LocalDB示例,并以我们的Windows帐户运行。但是,当Web应用程序(在IIS中作为ApplicationPoolIdentity运行)连接到LocalDB时,另一个LocalDB示例将为其启动,并作为ApplicationPoolIdentity运行!实际上,即使Visual Studio和Web应用程序都使用相同的LocalDB连接字符串,它们也连接到不同的LocalDB示例。显然,在我们的LocalDB示例上从Visual Studio创建的数据库在Web应用程序的LocalDB示例中不可用。
一个很好的类比是Windows中的我的文档文件夹。假设我们打开Visual Studio并在My Documents文件夹中创建一个文件。然后,我们以不同的用户身份登录到同一台计算机,并再次转到我的文档文件夹。我们不会在那里找到该文件,因为第二个用户的“我的文档”和我们的“我的文档”是两个不同的文件夹。类似地,两个不同用户拥有的LocalDB示例(localdb)\v11.0是两个不同的进程,具有两组不同的数据库。
这也是Web应用程序能够从IIS Express连接到LocalDB的原因。与LocalDB一样,IIS Express也是一个用户进程。它由Visual Studio启动,并以与Visual Studio进程相同的Windows帐户运行。以相同Windows帐户运行的两个不同进程(Visual Studio和IIS Express,都以我们的Windows帐户运行)连接到(localdb)\v11.0**,连接到同样以相同Windows帐户启动的LocalDB进程。
可能的解决方案
理解问题的本质会带来多种解决问题的方法。由于不同的方法有不同的权衡,而不是规定一个解决方案,下面我提出了三种对我来说最可行的方法。我希望能听到你的一个最适合你!以下是列表:
方法1:以Windows用户身份运行IIS
方法2:使用LocalDB共享示例
方法3:使用完整的SQL Server Express
让我们仔细看看他们每一个。
方式一:以Windows用户身份运行IIS
如果不同的用户帐户是问题所在,为什么不尝试在我们的Windows帐户下运行我们的Web应用程序?Web应用程序将连接到与Visual Studio相同的LocalDB,一切都应该正常工作。
进行配置更改相对容易,只需启动IIS管理器并找到正确的应用程序池:
打开高级设置屏幕(在上下文菜单中可用):
单击Identity属性中的小按钮,弹出Application Pool Identity界面:
再次启动Web应用程序将确认问题已解决:
这种方法的缺点是什么?当然,在我们的帐户下运行Web应用程序会带来一定的安全风险。如果有人劫持了我们的Web应用程序,他们将能够访问我们帐户所能访问的所有系统资源。以ApplicationPoolIdentity身份运行Web应用程序提供了额外的保护,因为ApplicationPoolIdentity帐户对本地系统资源的访问非常有限。因此,我一般不推荐这种方法,但在某些情况下,如果小心使用,它是一个可行的选择。
方式二:使用LocalDB共享示例
我们还可以使用LocalDB的示例共享特性。它允许我们与同一台机器上的其他用户共享LocalDB示例。共享示例将可以在公共名称下访问。
共享示例的最简单方法是使用SqlLocalDB.exe实用程序。只需启动管理命令行提示符,然后键入以下命令:
型
它将在公共名称IIS_DB下共享私有LocalDB示例v11.0。计算机上的所有用户都可以连接到此示例,使用(localdb).\IIS_DB作为服务器地址。请注意示例名称前的.,表示这是一个共享示例名称。我们应该将Web应用程序中的连接字符串替换为更新后的字符串:
型
在Web应用程序可以使用共享示例之前,我们需要启动它并为ApplicationPoolIdentity创建登录名。启动示例很容易,只需从SQL Server对象资源管理器连接到该示例即可启动该示例并使其保持活动状态。进入SQL Server对象资源管理器后,我们还可以为ApplicationPoolIdentity创建登录名。我们可以使用以下查询:
型
此脚本将对LocalDB示例的完全管理访问权限授予ApplicationPoolIdentity帐户。只要有可能,我建议使用更有限的数据库级甚至表级权限。
现在我们可以再次运行Web应用程序。这一次它应该工作得很好:
这种方法的缺点是什么?主要的一点是,在Web应用程序可以连接到共享示例之前,我们需要确保示例已经启动。要做到这一点,拥有该示例的Windows帐户必须连接到它,并且连接必须保持打开,否则LocalDB示例将关闭。
方式三:使用完整版SQL Server Express
由于完整的IIS作为服务运行,也许使用传统的基于服务的SQL Server Express是正确的方法?我们可以安装SQL Server 2012 Express RC 0并在其中创建OldFashionedDB数据库。我们甚至可以使用我们全新的SQL Server数据工具来做到这一点,因为它适用于任何SQL Server版本和版本。我们的连接字符串必须更改为:
型
当然,与前面的情况一样,我们需要确保ApplicationPoolIdentity帐户可以访问我们的SQL Server Express示例。我们可以使用与之前相同的脚本:
型
之后,运行我们的Web应用程序再次带来了令人愉快的画面:
这种方法的缺点是什么?显然,我们失去了使用LocalDB的好处。安装SQL Server Express可能比安装LocalDB花费更多的时间,并且可能需要进行一些计算机清理才能成功。SQL Server Express安装程序可能会因损坏的WMI数据库、受污染的注册表或SQL Server或Visual Studio CTP和Beta留下的组件等问题而受阻。SQL Server Express将继续在后台运行,即使在不需要的时候,就像服务一样。
其他选项
还有其他在完整IIS下使用LocalDB的方法,这里没有介绍。我们可以接受Web应用程序的私有LocalDB示例,并通过执行ASP.NET代码中的T-SQL脚本,通过Web应用程序与它进行通信。我们还可以使用ADO.NET连接字符串的AttachDbFileName选项,并使用一个数据库文件(.mdf),该文件将在开发期间附加到我们的LocalDB,并在Web应用程序的LocalDB上进行调试。我两个都试过了,我发现它们太麻烦了,无法进一步讨论。
enyaitl33#
基于@KrzysztofKozielczyk的回答。
我最初在这里发布了一个答案:
https://stackoverflow.com/a/62810876/3850405
在此之后,我验证了
Load User Profile
对于我的Application Pool
设置为true,然后在applicationHost.config
中将setProfileEnvironment
设置为true
。我通过编辑位于以下位置的applicationHost.config
完成了最后一部分:字符串
x1c 0d1x的数据
o2g1uqev4#
由于某种原因(localdb)\mssqllocaldb示例在我的情况下无法从IIS 10网站访问。
尝试了许多设置,但没有任何工作。
最后,在IIS中的网站的相应应用程序池的高级设置中设置**'加载用户配置文件= True'解决了我的问题。
我的应用程序池标识是Windows用户帐户**。