2013-04-25 76 views
1

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

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

在分层文件夹结构下有很多这样的想法,因为它们的每一个都经过处理以允许我在应用程序中继承这些设置。 但是,无论如何,这在一天结束时基本上是不相关的,这些只是存储在web根目录下的文件夹中的xml文件。

将xml文件的生成操作属性设置为内容,以便它们可以通过发布进行部署。事实上,我已将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角色的本地存储,这将是罚款对我来说,如果我想能够读取和写入存储为我的应用程序的一部分使用。但实质上这些是需要与应用程序一起部署的配置设置文件。

+0

如果他们的配置,你为什么不使用web.config文件? – mattytommo 2013-04-25 09:35:15

+0

因为它们不适合在Web配置中存储。因为它们有一个嵌套的层次结构,最终可能会有数百个这样的结果。加上德从web配置耦合它们可以让我在未来更灵活,因为我们可能开始更新应用程序本身这些文件,如果我们允许用户修改这些模板设置。 – Kramer00 2013-04-25 10:42:56

回答

1

在端部的问题被证明是该文件存取方法。我最初使用文件流来打开文件的内容,甚至在提升的角色权限下运行时,我得到了这个访问被拒绝的错误。

但是改变代码首先读取文件内容为一个字符串,我能够避免这种错误。

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

0

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

我也喜欢做以下,

在网页。配置:

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

代码背后:

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

在云URL这不会给任何访问权限错误。在这种web.config中,你也可以进行调试。只需要指出我在web.config中提到的上述路径即可。在web.config中更改连接字符串和其他东西。

+0

嗨,访问问题不是因为路径不存在。路径/文件确实存在。我使用HttpContext.Current.Server.MapPath根据其相对于Web根目录的位置来确定文件的物理路径。 – Kramer00 2013-04-25 13:21:06

0

所不同的是在文件存取方法。 事实证明,你不能对书面Azure中的Web /辅助角色里面打开的文件。即使您只是从文件File.Open中读取以读/写访问权限打开它们。 所以这应该工作太:

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

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