Windows Azure云服务 - 拒绝访问已部署的xml文件

时间:2013-04-25 09:27:31

标签: c# .net azure azure-web-roles access-denied

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

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

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

xml文件的构建操作属性设置为content,以便它们可以使用发布进行部署。事实上,我已经将RDP加入云服务VM,只是为了检查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;
        }
    }

我知道网络角色有本地存储空间,如果我希望能够作为应用程序的一部分读取和写入存储空间,那么我可以使用它。但基本上这些是配置设置文件,需要与应用程序一起部署。

3 个答案:

答案 0 :(得分: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方法需要这些额外的权限,但上述解决方案在这种情况下适用于我。

答案 1 :(得分:0)

项目本身,您可以添加文件夹并在web.config而不是E:\sitesroot\0\Templates\Applications\ControlProperties.xml中映射该文件路径。因此,当您托管到Cloud Service时,将自动避免访问权限问题。

我在下面做过,

在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中也改变了连接字符串和其他东西。

答案 2 :(得分:0)

区别在于文件访问方法。 事实证明,您无法打开Azure Web / Worker角色内的文件进行编写。即使您只是从文件中读取File.Open,也可以通过读/写访问权限打开它们。 所以这也应该有效:

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

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