1

我有一个 MVC 应用程序,它在本地运行良好,它在 azure 网站上运行良好。但是,当部署为云服务时,访问某些 xml 文件时出现访问被拒绝的问题。

这些 xml 文件只是应用程序所需的一些数据,有助于确定应用程序中的某些设置。

在分层文件夹结构下有大量这些,因为想法是处理每个这些以允许在应用程序中继承我需要的这些设置。但无论如何,这在很大程度上是无关紧要的,因为归根结底,这些只是存储在 Web 根目录下的文件夹中的 xml 文件。

xml 文件的构建操作属性设置为内容,以便它们可以通过发布进行部署。事实上,我已经在云服务 VM 上进行了 RDP,只是为了检查 xml 文件是否已部署并可以确认它们是否已部署。

但是,每当应用程序尝试读取其中一个文件时,我都会收到以下拒绝访问错误。

拒绝访问路径“E:\sitesroot\0\Templates\Applications\ControlProperties.xml”。

(注意:这不是下面的答案所假设的硬编码路径,我使用 HttpContext.Current.Server.MapPath 来确定文件相对于 Web 根目录的物理路径)

这只是标准访问被拒绝错误,表明应用程序无权读取文件。

现在,如果我再次 RDP 到机器并授予每个人对此特定文件的完全访问权限(仅用于诊断目的!),那么应用程序可以正常工作而不会引发错误。所以这证明它确实是一个访问问题。

问题是,这些只是随项目部署的简单 xml 文件,我真的不想在每次部署时都设置文件权限。这是错误的。

因此,我试图了解为什么作为标准部署的一部分,云服务将无权读取这些已部署的 xml 文件,然后对适当的解决方案感兴趣。即,一些权限设置可能与解决方案一起部署,或者可能有更好的替代方法来解决这个问题。

就我用来读取 xml 文件的代码而言,我只是使用 XmlSerializer 将文件的内容反序列化回一个对象。(如下)

 public static T Deserialise(string settingsFile)
    {
        using (var fs = new FileStream(settingsFile, FileMode.Open))
        {
            var sr = new XmlSerializer(typeof (T));
            var obj = (T) sr.Deserialize(fs);
            fs.Close();
            return obj;
        }
    }

我知道有用于 Web 角色的本地存储,如果我希望能够在我的应用程序中读取和写入存储,那么我可以使用它。但本质上,这些是需要与应用程序一起部署的配置设置文件。

4

3 回答 3

1

最后问题出在文件访问方法上。我最初使用 Filestream 来打开文件的内容,即使在提升的角色权限下运行时,我也会收到此访问被拒绝错误。

但是,首先将代码更改为将文件内容读入字符串,我能够避免此错误。

    public static T Deserialise(string settingsFile)
    {
        var fileContents = File.ReadAllText(settingsFile);
        using (var fs = new MemoryStream(Encoding.ASCII.GetBytes(fileContents)))
        {
            var sr = new XmlSerializer(typeof (T));
            var obj = (T) sr.Deserialize(fs);
            fs.Close();
            return obj;
        }
    }

不确定为什么 Filestream 方法需要这些额外的权限,但上述解决方案在这种情况下适用于我。

于 2013-05-01T07:16:12.427 回答
0

项目本身,您可以在 web.config 而不是E:\sitesroot\0\Templates\Applications\ControlProperties.xml. 因此,当您托管到云服务时,将自动避免访问权限问题。

我已经完成了如下操作,

在 web.config 中:

<configuration>
        <appSettings>
             <add key="DocsPath" value="http://somesitename.cloudapp.net/Files/"/>
        </appSettings>
  <connectionStrings>

在后面的代码中:

string Location = ConfigurationManager.AppSettings["DocsPath"] + "ChildFolderName" + "\\" + Filename.XML;

在 Cloud URL 中,这不会给出任何访问权限错误。通过这种 web.config 方式,您也可以进行调试。只需要像上面提到的那样指向路径web.config。在 web.config 中也更改连接字符串和其他内容。

于 2013-04-25T11:59:21.910 回答
0

不同之处在于文件访问方法。事实证明,您无法在 Azure Web/Worker 角色中打开文件进行写入。即使您只是从文件中读取文件 File.Open 也会以读/写访问权限打开它们。所以这也应该有效:

using (var stream = File.Open(settingsFile, FileMode.Open, FileAccess.Read))
{
...
}

我想这背后的全部原因是,如果出现某些问题,Azure 会使用最初上传的包自动重新部署您的角色。在这种情况下,之前对文件所做的任何修改都将丢失并替换为包中的原始文件。

于 2016-02-11T17:06:02.063 回答