Azure and edit or delete deployed files from your website

by ingvar 21. december 2010 09:32

If you change the file permission on deployed files in the WebRole, you will be able to edit or delete those files from you website. This includes the web.config file!
Also if you write new files in the WebRole, you also need to change the file permission for those files.

My colleague at Composite Marcus Wendt found the code for changing the file permission here. Ill restate the code below. This code is not enough, you also need to edit the ServiceDefinition.csdef file. You need to add '<Runtime executionContext="elevated" />' to the ServiceDefinition.csdef file to give your WebRole rights to change file permissions:


<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="AzureTest"
                   xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WebRole">
    
    <Runtime executionContext="elevated" />

  </WebRole>
</ServiceDefinition>

And here is the code for changing the permission for a given file:

void ChangePermission(string filePath)
{
    SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);

    IdentityReference act = sid.Translate(typeof(NTAccount));

    FileSecurity sec = File.GetAccessControl(filePath);
    sec.AddAccessRule(new FileSystemAccessRule(act, FileSystemRights.FullControl,
                                               AccessControlType.Allow));

    File.SetAccessControl(filePath, sec);
}

Tags:

.NET | Azure | C#

Azure and Response is not available in this context

by ingvar 17. december 2010 10:29

Application_Start and 'Response is not available in this context'

I have experienced the the HttpException 'Response is not available in this context' a lot when working with Azure. It appens if you try to do Azure stuff like accessing the blob in the Application_Start method.

After some time I found out that it was because HttpContext.Current.Response was accessible. So I though, why do Azure needs access to the Response object? I knew that it was possible to access the blob storage from a console app. Though I'm not sure about this, but I think that Azure uses the Response object for logging. In any case, if you need to access the blob in your web app or do any other Azuer stuff AND want to do this even though there is not a Response object, like in the Application_Start method. You simply set HttpContext.Current to null, but in a smart way!

Here is my code for Application_Start and below is the code for the smart way of setting HttpContext.Current to null:

protected void Application_Start(object sender, EventArgs e)
{
    CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
    {
        configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
    });

    using (new AzureContext())
    {
        CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting("BlobConnectionString");

        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

        CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
        container.CreateIfNotExist();
        container.FetchAttributes();
    }
}

 

And the code for AzureContext:

public class AzureContext : IDisposable
{
    HttpContext _oldHttpContext;
    bool _restoreOldHttpContext = false;


    public AzureContext(bool forceSettingContextToNull = false)
    {
        if (forceSettingContextToNull)
        {
            _oldHttpContext = HttpContext.Current;
            HttpContext.Current = null;
            _restoreOldHttpContext = true;
        }
        else
        {
            try
            {
                HttpResponse response = HttpContext.Current.Response;
            }
            catch (HttpException)
            {
                _oldHttpContext = HttpContext.Current;
                HttpContext.Current = null;
                _restoreOldHttpContext = true;
            }
        }
    }


    public void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (_restoreOldHttpContext)
            {
                HttpContext.Current = _oldHttpContext;
            }
        }
    }


    public void Dispose()
    {
        Dispose(true);
    }


    ~AzureContext()
    {
        Dispose(false);
    }
}

Tags:

.NET | Azure | C#

Azure Blob AppendAllText

by ingvar 14. december 2010 10:04

There are a very limited way of reading/writing to a blob on Windows Azure. Basically you are stuck with OpenRead and OpenWrite which returns a read stream and a write stream respectively. So if you want to append some text to a file you have to do some coding your self. Here is an example of doing this in a read/write in same file version. Here I use a Exists method to determine if a blob exists or not. The implementation of the method can be found here.

CloudBlobContainer container; /* Initialize this */
CloudBlob blob = container.GetBlobReference("myblob.txt");
string contents; /* content to append */

if (blob.Exists())
{
    using (Stream blobStream = blob.OpenRead())
    {
        byte[] buffer = new byte[4096];
        using (Stream tempBlobStream = blob.OpenWrite())
        {
            int read;
            while ((read = blobStream.Read(buffer, 0, 4096)) > 0)
            {
                tempBlobStream.Write(buffer, 0, read);
            }

            using (StreamWriter writer = new StreamWriter(tempBlobStream))
            {
                writer.Write(contents);
            }
        }                       
    }
}
else
{
    using (Stream blobStream = blob.OpenRead())
    {
        using (StreamWriter writer = new StreamWriter(blobStream))
        {
            writer.Write(contents);
        }
    }
}

If you prefer you can do it in a in-memory version like this:

CloudBlobContainer container; /* Initialize this */
CloudBlob blob = container.GetBlobReference("myblob.txt");
string contents; /* content to append */

string oldContent;
if (!blob.Exists())
{
    oldContent = "";
}
else
{
    using (StreamReader reader = new StreamReader(blob.OpenRead()))
    {
        oldContent = reader.ReadToEnd();
    }
}

using (StreamWriter writer = new StreamWriter(blob.OpenWrite()))
{
    writer.Write(oldContent);
    writer.Write(contents);
}

Tags:

.NET | Azure | C# | Blob

Azure Blob Exists

by ingvar 14. december 2010 08:40

Here is a really simple way of determining of a blob exists or not. I have added the 'DebuggerStepThrough' attribute so my debugger won't break every time a blob does not exists.

public static class CloudBlobUtils
{
    [DebuggerStepThrough]
    public static bool Exists(this CloudBlob blob)
    {
        try
        {
            blob.FetchAttributes();
            return true;
        }
        catch (StorageClientException ex)
        {
            if (ex.ErrorCode == StorageErrorCode.ResourceNotFound)
            {
                return false;
            }

            throw;
        }
    }
}

Tags:

.NET | Azure | C# | Blob

About the author

Martin Ingvar Kofoed Jensen

Architect and Senior Developer at Composite on the open source project Composite C1 - C#/4.0, LINQ, Azure, Parallel and much more!

Follow me on Twitter

Read more about me here.

Read press and buzz about my work and me here.

Stack Overflow

Month List