Pages

Sunday, 20 May 2012

Hosting RavenDB on Azure under a worker role

We decided to use RavenDB as the store for the new codewrap internet application, as we decided to use Azure as our PaaS we had to find a solution to run RavenDB on Azure. I found a really good post by Mike Hanley on RavenDB Running in Windows Azure. We now have a really good starting point and a base platform to build on.

The next steps are to secure access to RavenDB more and I will be making some changes to run the endpoints as Internal instead of Input. This should be sufficient for now, as we are still actively in the development phase and data will be dropped and recreated on a regular basis.

I ran into two problems when I followed Mike’s blog, and they were mainly due to my lack of knowledge on Azure.

You need to configure your “StorageAccount” as a connection with YOUR storage account details, to allow the mounting of the cloud drive when deployed to Azure

image

I also had to set the executionContext to elevated as mentioned in the comments to allow RavenDB to listen for HTTP request. You can do this by editing the SeviceDefinition.csdef file.

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="........." xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WorkerRole name="raven.worker" vmsize="Small">
<Runtime executionContext ="elevated" />
<Imports>
<Import moduleName="Diagnostics" />
</Imports>
<Endpoints>
<InternalEndpoint name="Raven" protocol="http" port="8080" />
</Endpoints>
<LocalResources>
<LocalStorage name="RavenCache" cleanOnRoleRecycle="false" sizeInMB="1024" />
</LocalResources>
<ConfigurationSettings>
<Setting name="StorageAccount" />
</ConfigurationSettings>
</WorkerRole>
</ServiceDefinition>

We are now in a good position to evaluate RavenDB on Windows Azure and start some RnD using it as our primary data store.

Sunday, 6 May 2012

Using bind prefix in ASP.NET MVC with overlays

Lets say you want to build an application where you add friends and hobbies to your profile using Ajax. The approach I would take is to include the markup for the friend and hobby forms as part of the profile page markup to make the UI more responsive when the overlays are shown. By doing this you could end up with duplicate element names and ids which can break UI behaviour or if the elements are in a form will not bind correctly when you submit it.

Models:

Here is the view model for the profile page, note that I added the friend and hobby edit models as properties, this is not required but my view is that it important to make it clear that the view for the profile page depends on the friend and hobby models.

public class ProfileViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
public FriendModel FriendModel { get; set; }
public HobbyModel HobbyModel { get; set; }
}

public class HobbyModel
{
public int Id { get; set; }
public string Name { get; set; }
}

public class FriendModel
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}

Views with no bind prefix


When you render the partial views with no prefix the Name elements will have the same name and id, creating duplicate elements in the markup.

<div id="friendOverlay" class="overlay">
@Html.Partial("_AddFriend", Model.FriendModel)
</div>

<div id="hobbyOverlay" class="overlay">
@Html.Partial("_AddHobby", Model.FriendModel)
</div>

Html rendered with no bind prefix


Note the id and name attributes are the same for both input elements.

FriendModel:
<div class="editor-field">
<input class="text-box single-line" id="Name" name="Name" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
</div>

HobbyModel:
<div class="editor-field">
<input class="text-box single-line" id="Name" name="Name" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
</div>

Views with bind prefix


Note the HtmlFieldPrefix is a property on the TemplateInfo property of the ViewDataDictionary that is passed to the Partial method.


The code is not the most elegant, you could create a html helper to improve this.

<div id="friendOverlay" class="overlay">
@Html.Partial("_AddFriend", Model.FriendModel, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "friend" } })
</div>

<div id="hobbyOverlay" class="overlay">
@Html.Partial("_AddHobby", Model.HobbyModel, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "hobby" } })
</div>

Html rendered with bind prefix


Note the id and name attributes of the input elements are now prepended with the prefix specified.

FriendModel:
<div class="editor-field">
<input class="text-box single-line" id="friend_Name" name="friend.Name" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="friend.Name" data-valmsg-replace="true"></span>
</div>

HobbyModel:
<div class="editor-field">
<input class="text-box single-line" id="hobby_Name" name="hobby.Name" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="hobby.Name" data-valmsg-replace="true"></span>
</div>

Binding the form to the model:


The final change we need to make is to tell the model binder to use the relevant prefix when binding the forms data to the model on post back. We do this by simply adding the BindAttribute to the property of the action we are posting to.

public ActionResult AddFriend([Bind(Prefix = "friend")] FriendModel model)
{
// code to process the model
// code to return result
}

public ActionResult AddHobby([Bind(Prefix = "hobby")]HobbyModel model)
{
// code to process the model
// code to return result
}