I have an MVC app which runs fine on premise, it runs fine on azure web sites. But when deployed as a cloud service I have access denied problems accessing certain xml files.
These xml files are just bits of data required for the application which help determine certain settings within the application.
There is a large number of these under a hierarchical folder structure, as the idea is that each of these get processed to allow an inheritance of these settings I need within the application. But anyway that is largely irrelevant as at the end of the day these are simply xml files stored in a folder under the web root.
The build action properties of the xml files are set to content so that they do get deployed with a publish. In fact I have RDP'd onto the cloud service VM just to check the xml files are getting deployed and can confirm they are.
However whenever the application tried to read one of these files i get the following access denied error.
Access to the path 'E:\sitesroot\0\Templates\Applications\ControlProperties.xml' is denied.
(Note : This is not a hard coded path as assumed by the answer below, I am using HttpContext.Current.Server.MapPath to determine the physical path of the file relative to the web root)
This is just the standard access denied error indicating the application does not have access to read the file.
Now if I RDP again to the machine and grant everybody full access to this particular file (just for diagnostic purposes!), then the application works fine without throwing an error. So this proves it really is an access issue.
The question is, these are simply simple xml files deployed with the project, and I don't really want to be having to set file permissions on each deployment. This would just be wrong.
So I am trying to understand why as part of the standard deploy would the cloud service not have access to read these deployed xml files, and then am interested in a proper solution. i.e. Either some permission settings maybe which get deployed with the solution, or maybe there is a better alternative approach to this problem.
In terms of the code I am using to read the xml file, I am simply using the XmlSerializer to deserialize the contents of the file back into a object. (as below)
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;
}
}
I understand that there is local storage for web roles, and this would be fine for me to use if I wanted to be able to read and write to storage as part of my application. But essentially these are configuration settings files which need to be deployed along with the application.
In the end the problem turned out to be the file access method. I was initially using a Filestream to open the contents of the file, and even when running under elevated role permissions I was getting this accessed denied error.
However changing the code to read the file contents into a string first, I was able to avoid this error.
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;
}
}
not sure as to why the Filestream method needed these extra permissions, but the above solution works for me in this scenario.