Monday, August 22, 2011

Jsonify an ExpandoObject in MVC3

I’ve recently stumbled across a scenario where it would make sense to use an ExpandoObject to populate an object which then would be serialized to JSON. But this cannot be done in MVC 3. The reason being that an ExpandoObject implements IDictionary<TKey, TValue>, and the JavaScriptSerializer interprets it as such, and results in the following output:

[{"Key":"data","Value":"Title"}]

How to fix this? Well there is no easy way, and the the only way I could come up with are described in this StackOverflow post, How to flatten an ExpandoObject returned via JsonResult in MVC?. The post supplies us with to possibilities, an extension method to convert the ExpandoObject to a string, and a custom JsonConverter used only for ExpandoObjects.

All of these methods require that we client-side parses the JSON returned, using either eval(jsonString) or JSON.parse(jsonString) (preferred because of security issues). Not a nice way to do it, but of course the JavaScriptSerializer serializes a string as a JSON string, so this is currently the only way to do so.

You could implement a custom ActionResult, which removes the the start and end “, but then this method can only be used of non-string objects which would introduce a whole new set of problems.

Monday, August 8, 2011

Deep clone an XDocument

I’ve recently needed to clone an XDocument, and started looking in how to do this easy. The standard way to clone objects in .NET is by using the Clone method on a object implementing ICloneable, but XDocument doesn’t implement ICloneable. Now what to do?
I started my trusted browser, and the only way I found was to do this manually, and so I did. But I couldn’t let the thought go away, there had to be an easier way as cloning could be used a lot in LINQ.
I looked through the MSDN documentation, I sure enough I’ve found it, one of the constructors can do this, XDocument(XDocument). There is simply no reason to manual clone the document, and a constructor just like this exists for an XElement.
Many people may know this constructor exists, but I sure didn’t as it doesn’t following the “standard” .NET cloning methods. But the constructor way is much better, as we now are explicitly told whether or not the clone will be a shallow or deep clone.

Update: Added example as requested.

XmlDocument originalXml = new XmlDocument();
XmlDocument xmlCopy = new XmlDocument(originalXml);

Wednesday, June 8, 2011

Holiday for 4 weeks

As I’m going on a holiday for 4 weeks tomorrow, no new posts or at least not many will be published during that time. Wish you all a nice day and stay happy. I’m looking forward to start posting again after July the 5th.

Sunday, June 5, 2011

.NET Compiler Directives

Not sure how to use .NET compiler directives (#pragma) or not sure when to use it?

Take a look at this blog post, Compiler directive #Pragma reference, by Daily .NET Tips. It contains a short description of the two different types of Pragma, and when they are used.

Saturday, June 4, 2011

Glimpse ASP.NET debugger

Glimpse is a Firebug like debugger used to debug ASP.NET. Among others it can help you debug routes and enable tracing in ASP.NET MVC, it also has a plugin to help you debug Ajax. Glimpse also allows you to take a look at the execution stack, including all action filters and etc. called to display the view or page.

At the moment Glimpse supports ASP.NET Web Forms and ASP.NET MVC, but more technologies are going to be supported, including PHP, Ruby on Rails, and Node.js.

It is a very powerful tool and enables you to debug stuff, which can be difficult to debug using Visual Studio.

I strongly recommend you to watch the introduction video at http://getglimpse.com/, and try it out. Glimpse can be downloaded via NuGet.

Routes in ASP.NET MVC: The Rails Way

Some think that using routes in ASP.NET MVC, are a little to noisy and likes the Rails way better.

The Rails Way

home_url

The ASP.NET MVC way

@Html.RouteLink("Home", "Root")

A bright individual, Rob Conery, wanted to change this a wrote a blog post called, Referencing Routes in ASP.NET MVC The Rails Way. Basically it allows you to use routes in ASP.NET MVC this way

Routes in MVC the Rails way

@Routes.home_url
// And set route variables like this
@Routes.home_url(new { id = "stuff" });

HtmlTags 1.0 released

A new release of the HtmlTags library has been released. If you don’t know what the library does I suggest you take a look at the HtmlTags readme, and the Announcing HtmlTags 1.0 blog post.
 
The library allows you to create HTML tags in a fluent way, instead of the StringBuilder.
A quick example would be
Default way

@Html.TextBox("FirstName", "Lucas", new Dictionary<string, object> {{"id", "first-name"}, {"class", "required"})
Using HtmlTags

@Html.TextBoxTag("FirstName").Id("first-name").AddClass("required")

Clearing ASP.NET Session Variables

How to clear the ASP.NET session correctly and what are the difference between Session.Clear(), Session.Remove() and Session.Abandon()?

The blog post ASP.NET Internals: “Clearing ASP.NET Session Variables” a in-depth look, written by Abhijit Jana, answers these questions.

 

Friday, June 3, 2011

Data Annotations Extensions

The System.ComponentModel.DataAnnotations contains the most basic validation rules like

  • String length
  • Required
  • Range
  • Regular expression

These validators can be used for many things, but sometimes they just aren’t enough. That’s where the open source project DataAnnotationsExtensions comes to the rescue. It contains many of the most sought after validators, and some less used ones too. Currently it contains the following validators:

I’ve added links for each validator to the demo page on their web site. The project comes in two versions, one which only contains server side validation, and one which also supports client-side validation with ASP.NET MVC3. Both versions are available for download from NuGet and from the DataAnnotationsExtensions download page.

The library just makes data validation in ASP.NET Dynamic Data and ASP.NET MVC much easier and more readable.

ASP.NET Dynamic Data - Part 8 - Customizing Field Validation

In ASP.NET Dynamic Data you can customize and extend data validation in several different ways.

  • Using DataAnnotations attributes on individual data fields.
  • Overriding the partial class method that processes changes for the individual data field.
  • Override the OnValidating or Validate event, to customize validation for any data field.
  • Create a custom validation attribute

Creating a partial class for validation

The first thing we need to do, is to create the partial class that extends the data model. This makes it possible to add metadata through attributes and implementing partial class methods to create your own validation logic. We have already done this in this serie in part 2, so take a look there if you don’t know how to do this, after that we need to create the metadata class which is done in part 3.

Customize validation using attributes

This is the easiest way. It allows you to use default validation rules provided by the DataAnnotations attributes.

  1. In the partial class create a property or field with the same name as the data field to validate.
  2. Apply one of the attributes from the DataAnnotations namespace to the field or property.
Example 1

public class TableMetaData {
	[Required]
	public object Name { get; set; }

	[StringLength(10)]
	public object Description;
}

The example makes the Name attribute required and the length of the description at least 10 characters long. You can also apply several validation attributes to the same field.

Using partial class method for an individual field

Another way to do more complex validation, is to override a partial class method that processes changes made to an individual data field. The naming convention for this is On<FieldName>Changing.

  1. Override the partial class method.
  2. Add the validation logic.
Example 2

public partial class Table {
	partial void OnNameChanging(string value) {
		if (value.Length < 5) {
			throw new ValidationException("Name must be at least 5 characters long.");
		}
	}

	partial void OnPriceChanging(double price) {
		if (price < 0) {
			throw new ValidationException("Price cannot be negative!");
		}
	}
}

The example validates the name is at least 5 characters long, and the price is non-negative. This example could also be done using the built-in attrbutes. All exceptions thrown in the data model are caught by the DynamicValidator control, which also displays it in the page. The parameter is typed to match the data type in the model.

Using partial class method for all fields in the model

This method allows you to control the validation logic for all fields in the data model at the same time, which is very useful when the logic can be applied to more than one data field, and allows you to validate combinations of multiple data fields.
The way to do this is different whether you use a Linq to SQL or Entity Framework data model.

Linq to SQL

  1. Override the OnValidate method
  2. Add to validation logic
Example 3

partial void OnValidate(ChangeAction action) {
	if (this._IsStock && this._Amount <= 0) {
		throw new ValidationException("The product cannot be in stock when the amount is 0 or less");
	}
}

The example validate that a product only can be in stock, when the amount is greater than zero.

Entity Framework

  1. Create a partial class for the entity class you want to implement custom validation on
  2. Language specific step
    • If C# create a partial method called OnContextCreated which registers an event handler for the SavingChanges event
    • If VB just create an event handler for the SavingChanges event
  3. Add the logic to the partial class method
Example 4

public partial class ProductsEntities {
	partial void OnContextCreated() {
		SavingChanges += OnSavingChanges;
	}
	
	public void OnSavingChanges(object sender, EventArgs e) {
		var stateManager = ((ProductsEntities)sender).ObjectStateManager;
		var changedEntities = stateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added);
		foreach (var entry in changedEntities) {
			if (entry.Entity is Product) {
				Product prod = (Product)entry.Entity;
				if (prod.InStock && prod.Amount <= 0) {
					throw new ValidationException("Product cannot be in stock when the amount is zero or less");
				}
			}
		}
	}
}

Custom validation attribute

Let’s you create an attribute you can reuse across projects and/or models for a single data field. The attribute must derived from ValidationAttribute.

  1. Create a new class
  2. Add references to System, System.Globalization and System.ComponentModel.DataAnnotations
  3. Make the class sealed
  4. Derive the class from ValidationAttribute
  5. Apply the AttributeUsageAttribute and indicate that the attribute only can be applied to a property or field one time
  6. Override the IsValid and add the validation logic inside
  7. Optionally you can override the FormatErrorMessage to perform error-message formatting.
  8. Apply the attribute just as you would with one of the built-in validation attributes

An example of a attribute could look like this


[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false]
public sealed class CapitalizeAttribute : ValidationAttribute {
	public override bool IsValid(object value) {
		return Char.Uppercase(value.ToString()[0]);
	}

	public override string FormatErrorMessage(string name) {
		return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name);
	}
}

Type-Safe ASP.NET Session

I just hate loosing object types such as you do in when retreving objects from the ASP.NET session, like done here


// Fails if the key does exists in the session
// as an integer cannot be null
int id = (int)Session["id"];
// Doesn't throw an error as we handle null
int id = Session["id"] == null ? -1 : (int)Session["id"];
Wouldn’t it be nice if we handled this more gracfully? And actually  got the object back we expected? This could easily be accomplished using extension methods.

public static class SessionExtensions
{
    public static T Get<T>(this HttpSessionStateBase session, string key)
    {
        return (T)session[key];
    }

    public static bool TryGet<T>(this HttpSessionStateBase session, string key, out T item)
    {
        object sessionItem = session[key];
        if (sessionItem == null)
        {
            item = default(T);
            return false;
        }

        try
        {
            item = (T)sessionItem;
        }
        catch (InvalidCastException)
        {
            item = default(T);
            return false;
        }

        return true;
    }

    public static Result<T> SafeGet<T>(this HttpSessionStateBase session, string key)
    {
        object sessionObject = session[key];
        if (sessionObject == null)
        {
            return new Result<T> { Success = false };
        }

        try
        {
            T item = (T)sessionObject;
            return new Result<T> { Success = true, Value = item };
        }
        catch (InvalidCastException)
        {
            return new Result<T> { Success = false };
        }
    }
}

public class Result<T>
{
    public T Value { get; set; }
    public bool Success { get; set; }
}

I’ve created several methods to get the value from session. The Get method just gets the object and casts it to the specified object, the downside here is the possibility for an InvalidCastException. The TryGet method, uses the standard .NET way, and uses and out parameter. The last method, SafeGet, is my prefered way (I just hate out parameters), and returns an object which contains the success and the value. Each method can be used like this


Session["test"] = 10;
int integer = Session.Get<int>("test");
if (Session.TryGet("test", out integer)) {
    // Use value
}
var resultObject = Session.SafeGet<int>("test");
if (resultObject.Success) {
        // Use value (result.Value)
}

This method can of course easily be adapted to similar situations like TempData.

Thursday, June 2, 2011

Wrap another tag inside a Label tag (MVC extension method)

A web developer at work recently wanted to wrap a input tag inside a label tag for easier layout. The HTML wanted looked like this:

<label for="name">Name:<input type="text" id="name" name="name" /></label>

This was a in MVC project, and because of this I’ve decided to create an extension method to do this. The extension method should also support adding attributes to the label tag. The extension method I came up with looks like this:

  1: public static string LabelWrap(this HtmlHelper helper, string label, MvcHtmlString @object, object attribtues = null)
  2: {
  3:   StringBuilder sb = new StringBuilder();
  4:   Match match = Regex.Match(@object.ToHtmlString(), @"id=""(?<ID>\w+)""");
  5:   if (match.Success)
  6:   {
  7:     sb.AppendFormat(@"<label for=""{0}""", match.Groups["ID"].Value);
  8:     if (attribtues != null)
  9:       {
 10:         PropertyInfo[] propertyInfos = attribtues.GetType().GetProperties();
 11:         foreach (PropertyInfo propertyInfo in propertyInfos)
 12:         {
 13:           sb.AppendFormat(@" {0}=""{1}""", propertyInfo.Name, propertyInfo.GetValue(attribtues, null));
 14:         }
 15:       }
 16:       sb.AppendFormat(">{0}{1}", label, @object.ToHtmlString());
 17:       sb.Append("</label>");
 18:     }
 19:     return sb.ToString();
 20:   }
 21: }

The method doesn’t take into account, whether or id could be found.

Using the method is very simple

@Html.LabelWrap("Name:", Html.TextBoxFor(model => model.Name))

And adding attributes to the label tag, just as easy

@Html.LabelWrap("Name:", Html.TextBoxFor(model => model.Name), new { @class = "cssClass" })
Could it be easier?

Using CDNs and Browser Caching to Improve Web Site Performance

Web Site performance is of great importance to many developers, and a lot of techniques can be used to increase performance. An example could be using CDNs (Content Delivery Networks) and browser caching, both a very easy to implement in ASP.NET. Just take a look at the blog post Using CDNs and Expires to Improve Web Site Performance written by Rick Anderson. The post focuses on how to do this in MVC, but can easily be adapted to Web Forms, just by writing the full links instead of using the in-page Razor helper.

ASP.NET MVC Validation with the Entity Framework

Model validation in ASP.NET MVC are very easy and effective, especially if you create the model yourself. It gets a little more complicated when using the entity framework or Linq to SQL, but when know how to do it, it’s a breeze.

If you have read my series on ASP.NET Dynamic Data you’ve almost read the answer in part 3. You have to create a partial class, extending the entity class and define some meta data for the entity.

The tutorial on the ASP.NET MVC web site, Validation with the Data Annotation Validators, explains this in more detail with focus on MVC.

Disable RequestValidation in ASP.NET MVC3

In a recent ASP.NET MVC3 project I’ve got the dreaded yellow screen of death with the error

A potentially dangerous Request.Form value was detected from the client

What to do? I’ve got the error in ASP.NET forms, and know how to fix it by disabling request validation. Request validation can be disabled both globally and on a single page. Generally I would recommend not disabling request validation globally as it is very effective against simple cross-site scripting (XSS) attacks.

But how to fix this in MVC? After some searching on the web, I found a blog post by David Hayden describing how to do this in MVC, AllowHtml Attribute in ASP.NET MVC3. As the post describes you can use the AllowHtml attribute to disabled request validation on a single property on the model. If you don’t use a model and just want to receive some HTML in a action, you can still use the ValidateInput attribute, which disables request validation on the whole action.

Wednesday, June 1, 2011

ASP.NET Dynamic Data - Part 7 - Customize Edit Field Templates


So far we've only concentrated on customize the "simple" fields, the display fields, but what about the edit fields?
Exactly this are the topic of this post. We are going to create a custom field template, and adapt the edit template to our needs.
The field template are created as described in ASP.NET Dynamic Data - Part 3 - Customize Field Templates. This is the template we'll continue working on.

The default template

The default edit template looks like this.
PriceCustom_Edit.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="PriceCustom_Edit.ascx.cs" Inherits="DynamicData_FieldTemplates_PriceCustom_EditField" %>

<asp:TextBox ID="TextBox1" runat="server" Text='<%# FieldValueEditString %>'></asp:TextBox>

<asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator1" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
<asp:RegularExpressionValidator runat="server" ID="RegularExpressionValidator1" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
<asp:DynamicValidator runat="server" ID="DynamicValidator1" ControlToValidate="TextBox1" Display="Dynamic" />
PriceCustom_Edit.ascx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using System.Web.DynamicData;

public partial class DynamicData_FieldTemplates_PriceCustom_EditField : System.Web.DynamicData.FieldTemplateUserControl {
    protected void Page_Load(object sender, EventArgs e) {
        TextBox1.MaxLength = Column.MaxLength;
        if (Column.MaxLength < 20)
            TextBox1.Columns = Column.MaxLength;
        TextBox1.ToolTip = Column.Description;

        SetUpValidator(RequiredFieldValidator1);
        SetUpValidator(RegularExpressionValidator1);
        SetUpValidator(DynamicValidator1);
    }
    
    protected override void ExtractValues(IOrderedDictionary dictionary) {
        dictionary[Column.Name] = ConvertEditedValue(TextBox1.Text);
    }

    public override Control DataControl {
        get {
            return TextBox1;
        }
    }
}
By default three validators are present, RequiredFieldValidator, RegularExpressionValidator and DynamicValidator. The RequiredFieldValidator of course makes the field required, the RegularExpressionValidator is empty and does nothing, the DynamicValidator takes care of all the validations defined in the data model.
In this case we'll add a custom validator, that ensures the entered value is an integer between 0 and 100.

Add and implement the custom validator

First we'll add a custom validator in the markup, which looks like this
<asp:CustomValidator runat="server" ID="CustomValidator1" ControlToValidate="TextBox1" Display="Dynamic" OnServerValidate="PriceValidation" />
Next we have to implement the validation method, called PriceValidation. This method checks if this the entered value is a interger between 0 and 100.
protected void PriceValidation(object source, ServerValidateEventArgs args)
{
    bool result = false;
    int value;
    result = Int32.TryParse(TextBox1.Text, out value);
    if (!result)
    {
        CustomValidator1.ErrorMessage = "The entered value is not an integer";
        args.IsValid = false;
        return;
    }

    if (value < 0 || value > 100)
    {
        CustomValidator1.ErrorMessage = "The entered value not between 0 and 100";
        args.IsValid = false;
        return;
    }

    args.IsValid = true;
}
That's it we have now customized the edit field template. This hopefully gives an idea of how to customize the edit template, anything you could normally do in a user control, are possible here.
Here at the end is a screenshot of the custom error message.

Monday, May 30, 2011

ASP.NET Dynamic Data - Part 6 - Customize Field Templates For Non-Intrinsic Types

Sometimes it is necessary to assign a type more specific than the data field inferred by Dynamic Data. For example a text field which contains an e-mail address, could be defined as a specific type of text. The template that processes the field can generate special UI for displaying and editing the e-mail type.
All this is done by using a DataTypeAttribute on the data-model field.
In this post I'll change the type of the Price field in the Products table, from the default double to a currency datatype, which displays the price correctly.

Add the Currency datatype to the Price field

  1. Defined the tables metadata as described in part 3.
  2. Create a property for the data field to customize.
  3. Add the DataType attribute to the property and set the data type to DataType.Currency.
[ScaffoldTable(true)]
[MetadataType(typeof(ProductsMetadata))]
public partial class Products
{
}

public class ProductsMetadata
{
    [UIHint("StockCustom")]
    public object Stock { get; set; }

    [DataType(DataType.Currency)]
    public object Price { get; set; }
}
Now the price are displayed correctly, with the currency defined in windows.
Now what to do if this is still not good enough? What if the currency defined in Windows are incorrect? Well, read on and you'll get the answer.

Modify the field template

If the default behavior for the datatype aren't enough you can customize it. To do this create a a custom field template as described in part 3 and modify it to support you needs.
In my case I need to use USD instead of DKK. I'll create a custom field template for the Price field, and edit the code to look like this.
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using System.Web.DynamicData;
using System.ComponentModel.DataAnnotations;
using System.Globalization;

public partial class DynamicData_FieldTemplates_PriceCustom : System.Web.DynamicData.FieldTemplateUserControl {
    public override Control DataControl {
        get {
            return Label1;
        }
    }

    protected override void OnDataBinding(EventArgs e)
    {
        base.OnDataBinding(e);

        var metadata = MetadataAttributes.OfType().FirstOrDefault();
        if (String.IsNullOrEmpty(FieldValueString) || metadata == null)
            return;

        if (metadata.DataType == DataType.Currency)
        {
            Label1.Text = ((double)FieldValue).ToString("C", new CultureInfo("en-US"));
        }
    }
}
The reason for me to choose this rather explicit way to check the datatype, is to show how to handle this when the field template are used by multiple data fields with different data types, for example customizing the default template.
You also need to indicate in the tables metadata that the custom field template should be used instead of the default, this is done by adding the attribute to the data field UIHint, just as described in part 3.
The custom field template looks like this.
PriceCustom.ascx:
<%@ Control Language="C#"  AutoEventWireup="true" CodeFile="PriceCustom.ascx.cs" Inherits="DynamicData_FieldTemplates_PriceCustom" %>
PriceCustome.ascx.cs:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using System.Web.DynamicData;
using System.ComponentModel.DataAnnotations;
using System.Globalization;

public partial class DynamicData_FieldTemplates_PriceCustom : System.Web.DynamicData.FieldTemplateUserControl {
    public override Control DataControl {
        get {
            return null;
        }
    }

    protected override void OnDataBinding(EventArgs e)
    {
        base.OnDataBinding(e);

        var metadata = MetadataAttributes.OfType().FirstOrDefault();
        if (String.IsNullOrEmpty(FieldValueString) || metadata == null)
            return;

        if (metadata.DataType == DataType.Currency)
        {
            Label label = new Label();
            label.Text = ((decimal)FieldValue).ToString("C", new CultureInfo("en-US"));
            Controls.Add(label);
        }
    }
}
The new page looks like this

ASP.NET Dynamic Data - Part 5 - Customize Page Templates

Another way to customize a table's layout is custom page templates, the other way, entity templates are described in part 3.

How to create a custom page template

  1. Create the subfolder named according to the table accessor in the data-context class.
  2. Copy an existing page template from /DynamicData/PageTemplates to the newly created subfolder.
  3. If you're project is a Web Application, the namespace must be changed in the copied template, in order to avoid name collision.
Now just customize the copied template, as needed.
Again building on the previous project in the series, my example for the page template for the Categories table looks like this.
Details.aspx:
<%@ Page Language="C#" MasterPageFile="~/Site.master" CodeFile="Details.aspx.cs" Inherits="Details" %>

<asp:Content ID="headContent" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <asp:DynamicDataManager ID="DynamicDataManager1" runat="server" AutoLoadForeignKeys="true">
        <DataControls>
            <asp:DataControlReference ControlID="FormView1" />
        </DataControls>
    </asp:DynamicDataManager>

    <h2 class="DDSubHeader">Details for <%= table.DisplayName %> entry</h2>

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:ValidationSummary ID="ValidationSummary1" runat="server" EnableClientScript="true"
                HeaderText="List of validation errors" CssClass="DDValidator" />
            <asp:DynamicValidator runat="server" ID="DetailsViewValidator" ControlToValidate="FormView1" Display="None" CssClass="DDValidator" />

            <asp:FormView runat="server" ID="FormView1" DataSourceID="DetailsDataSource" OnItemDeleted="FormView1_ItemDeleted" RenderOuterTable="false">
                <ItemTemplate>
                    <table id="detailsTable" class="DDDetailsTable" cellpadding="6">
                        <asp:DynamicEntity runat="server" />
                        <tr class="td">
                            <td colspan="2">
                                <asp:DynamicHyperLink runat="server" Action="Edit" Text="Edit" />
                                <asp:LinkButton runat="server" CommandName="Delete" Text="Delete"
                                    OnClientClick='return confirm("Are you sure you want to delete this item?");' />
                            </td>
                        </tr>
                    </table>
                </ItemTemplate>
                <EmptyDataTemplate>
                    <div class="DDNoItem">No such item.</div>
                </EmptyDataTemplate>
            </asp:FormView>

            <asp:EntityDataSource ID="DetailsDataSource" runat="server" EnableDelete="true" />

            <asp:QueryExtender TargetControlID="DetailsDataSource" ID="DetailsQueryExtender" runat="server">
                <asp:DynamicRouteExpression />
            </asp:QueryExtender>

            <br />

            <div class="DDBottomHyperLink">
                <asp:DynamicHyperLink ID="ListHyperLink" runat="server" Action="List">Show all items</asp:DynamicHyperLink>
            </div>
        </ContentTemplate>
    </asp:UpdatePanel>
</asp:Content>
Details.aspx.cs:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.DynamicData;
using System.Web.Routing;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.Expressions;

public partial class Details : System.Web.UI.Page {
    protected MetaTable table;

    protected void Page_Init(object sender, EventArgs e) {
        table = DynamicDataRouteHandler.GetRequestMetaTable(Context);
        FormView1.SetMetaTable(table);
        DetailsDataSource.EntityTypeFilter = table.EntityType.Name;
    }

    protected void Page_Load(object sender, EventArgs e) {
        Title = table.DisplayName;
        DetailsDataSource.Include = table.ForeignKeyColumnsNames;
    }

    protected void FormView1_ItemDeleted(object sender, FormViewDeletedEventArgs e) {
        if (e.Exception == null || e.ExceptionHandled) {
            Response.Redirect(table.ListActionPath);
        }
    }
}
I've just changed the page headline from Entry from table Categories to Details for Categories entry. I haven't made any changes to the default Details code-behind or markup other than the change described above.
The details page for the Categories table now looks like this:

Entity Template vs. Page Template

The page template allows control over the page layout and contents, the entity template only allows control on the table contents itself. Whether to use entity templates or page templates depends on the use case. Both templates are very easy to create and modify. Also page templates required zero code, except on the template itself, if more advanced functionality are required.

Series about logging errors with ELMAH

ELMAH (Error Logging Modules and Handlers) is an error-logging facility, that can be added to ASP.NET applications without need for recompilation or deployment. It is very extensible and can do a lot of very advanced logging, to several different back-end storages, including MSSQL, Orcale, MySQL, SQLite, XML, memory and others.
It can be difficult to setup correctly, because of this a very comprehensive series about ELMAH has been posted on joel.net. Currently the series consists of 5 parts.

Sunday, May 29, 2011

C# 5: Async from the compilers view

As many may know, one of the main features in the next version of C#, C# 5, is the new keywords, async and wait. But how does the compiler handle these new keywords? After all they're only syntactic sugar.
Jon Skeet has an excellent blog series called Eduasync about this, so far it consists of 8 parts, and are definitely recommended reading, if you are interested in the internals of the asynchronous functionality.
Eduasync part 1: introduction
Eduasync part 2: the shape of the caller / async method boundary
Eduasync part 3: the shape of the async method / awaitable boundary
Eduasync part 4: Filling in AsyncTaskMethodBuilder
Eduasync part 5: making Task awaitable
Eduasync part 6: using the infrastructure manually
Eduasync part 7: generated code from a simple async method
Eduasync part 8: generated code from a complex async method
The Async CTP are available from MSDN for everyone to try.

Update
Eduasync part 9: generated code for multiple awaits

ASP.NET Dynamic Data - Part 4 - Customize Entity Templates

The next topic in my series on ASP.NET Dynamic Data, I'll focus on how to customize the table layout using entity templates. I'll continue to work on my project described in part 3. The only thing changed from part 3 is instead of the custom field template which changed the background color, based on the stock count, now changes for foreground color instead.
At the moment the Web Site uses the default details table layout, which looks like this:
This is a very basic template, are a very often not what you need. In this case I would like something different, something like this:

I'm not a designer so no fancy colors or anything here, but this could be added easily.

Create the custom entity template

First we need to create the custom entity template, this template will be used for all entities in the Products table. We need to Add New Item, on the /DynamicData/EntityTemplates folder and choose the Web User Control item, the name of the control must be the same as the data model entity that represents the table, in my case it must be Products.ascx.
The markup for the new table contents are easily added, and could look like this:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Products.ascx.cs" Inherits="DynamicData_EntityTemplates_Products" %>
<tr>
    <td class="DDLightHeader" colspan="4">Producy Entry</td>
</tr>
<tr>
 <td class="DDLightHeader">Id:</td>
 <td>
        <asp:DynamicControl runat="server" DataField="Id" />
    </td>
 <td class="DDLightHeader">Name:</td>
 <td>
        <asp:DynamicControl ID="DynamicControl1" runat="server" DataField="Name" />
    </td>
</tr>
<tr>
 <td class="DDLightHeader">Stock:</td>
 <td>
        <asp:DynamicControl ID="DynamicControl2" runat="server" DataField="Stock" />
    </td>
 <td class="DDLightHeader">Price:</td>
 <td>
        <asp:DynamicControl ID="DynamicControl3" runat="server" DataField="Price" />
    </td>
</tr>
<tr>
 <td class="DDLightHeader" colspan="4">Description:</td>
</tr>
<tr>
 <td colspan="4">
        <asp:DynamicControl ID="DynamicControl4" runat="server" DataField="Description" />
    </td>
</tr>
After the markup are written, you need to change to base class from UserControl to EntityTemplateUserControl, this is done in the usercontrol's code-behind file. The code looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.DynamicData;

public partial class DynamicData_EntityTemplates_Products : EntityTemplateUserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

Test the Web Site

This is all that needs to be done in order to create a custom entity template, easy right? When the Web Site is tested in looks like this:

ASP.NET Dynamic Data - Part 3 - Customize Field Templates

Now it's time for part 3 in the series about ASP.NET Dynamic Data, how to customize the appearance and behavior of default field templates.
All changes in the default template will affect all pages and controls where the template is used.
All templates used by the Dynamic Data framework are placed in /DynamicData, for example field templates are placed in the /DynamicData/FieldTemplates.
The default field templates are all usercontrols, which you are free to edit as you like, they are all named descriptively, making it easy to quickly recognize the place where it is used.
For example, the display control for text are called, Text.ascx, the edit template are called, Text_Edit.ascx.
Since all these controls are using familiar technology they can be easily customized to fit you own needs.

Creating a custom template

If needed a custom field template can easily be created. In my example if got a data model which looks like this:
The custom data field template I need, is a template which displays the stock count with a red background in below 10, a yellow background in between 10 and 20, otherwise the default background color will be used.
To create the custom template a add a new item to the /DynamicData/FieldTemplates folder, the new item is a Dynamic Data Field item, available from the Add New Item dialog.
In my case the default markup needs to be changed from a literal control to a label control, as literal controls, don't allow me to change the background color.
Markup:
<%@ Control Language="C#"  AutoEventWireup="true" CodeFile="StockCustom.ascx.cs" Inherits="DynamicData_FieldTemplates_StockCustom" %>
<asp:Label runat="server" ID="Label1" Text="<%# FieldValueString %>" />
To change the background color based on the value, you need to override the OnDataBinding method. The code-behind file for my custom field template are shown below. The value of the field are available in the FieldValue property on the base class.
Code-behind:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using System.Web.DynamicData;
using System.Drawing;

public partial class DynamicData_FieldTemplates_StockCustom : System.Web.DynamicData.FieldTemplateUserControl {
    public override Control DataControl {
        get {
            return Label1;
        }
    }

    protected override void OnDataBinding(EventArgs e)
    {
        int currentValue = (int)FieldValue;
        if (currentValue < 10)
            Label1.BackColor = Color.Red;
        else if (currentValue < 20)
            Label1.BackColor = Color.Yellow;
    }
}
Now the last thing we need to do is to associate the field template with a data field. First we need to modify the partial class from part 2. The new code looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DatabaseModel;
using System.ComponentModel.DataAnnotations;

namespace DatabaseModel
{
    [ScaffoldTable(true)]
    [MetadataType(typeof(ProductsMetadata))]
    public partial class Products
    {
    }

    public class ProductsMetadata
    {
        [UIHint("StockCustom")]
        public object Stock;
    }

    [ScaffoldTable(true)]
    public partial class Categories
    {
    }
}
The MetadataTypeAttribute indicates which class contains the necessary metadata for the table. The metadata class, contains a field which has the same name as the field in the database, the field itself has another attribute, the UIHintAttribute, which defines the name of the field template to used instead of the default.
When I view my products table in the web interface now, it indicates the stock count in red if the count is less than 10, yellow if the count is between 10 and 20, and default color if greater than 20.

Wednesday, May 25, 2011

ASP.NET Dynamic Data - Part 2 - Create a Web Site From Scratch

Part 1 in the serie about ASP.NET Dynamic Data gave a very quick overview over the Dynamic Data framework. Now how do you create a Dynamic Data Web Site from scratch using in built-in scaffolding support?

Create the Web Site

It's very easy to create a Dynamic Data Web Site from scratch. In Visual Studio just choose File -> New -> Web Site -> ASP.NET Dynamic Data Entities.
Dynamic Data can of course also be create using Linq to SQL, and as a Web Application.
The structure of the project looks like this

Create and use the DataContext

Next the DataContext used to scaffold the database should be created. If you don't know how to create the entity model, see the How to: Create a New .edmx File (Entity Data Model Tools) from MSDN.
To use the generated open the Global.asax file, and find the line on the picture below, the line should be uncommented and YourDataContext should be changed to the name of you own DataContext, in my case the context in DatabaseEntities.
The line also allows you to control if all tables should be scaffoleded, the default is not to scaffold all tables. In my case I could scaffold all tables, but for the sake for this tutorial, I'll defined which tables to scaffold using partial classes.

Choose the tables to scaffold

My database consists of two tables named Products and Categories, the entity classes have the same name, this means that my two partial classes looks like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DatabaseModel;
using System.ComponentModel.DataAnnotations;

namespace DatabaseModel
{
    [ScaffoldTable(true)]
    public partial class Products
    {
    }

    [ScaffoldTable(true)]
    public partial class Categories
    {
    }
}
The ScaffoldTable attribute indicates that the table should be scaffolded. Remember to place the partial classes in the same namespace as the original entity classes, otherwise this won't work.

Test the site

You can know publish the Web Site, are it is now possible to view, edit, create and delete data from the database. This is how easy Dynamic Data allows you to create a basic web interface to you database.
It the next part of this serie, I'll show you how to customize the default field templates.

ASP.NET Dynamic Data - Part 1 - Introduction

ASP.NET Dynamic Data has been out for a while, but good tutorials about it, can be hard to find. In this and a couple of future post, I'll try to introduce you to some of the framework and how to use it.

Overview of ASP.NET Dynamic Data

ASP.NET Dynamic Data lets you create extensible data-driven Web applications by inferring at run time the appearance and behavior of data entities from the database schema and deriving UI behavior from it. - ASP.NET Dynamic Data Overview (Microsoft MSDN)
The quote above, quickly summarizes the purpose of Dynamic Data. As Dynamic Data supports scaffolding, to automatically generate Web Pages for the tables in a database, both for editing and viewing data. After this has been done, you can customize the elements or create new ones to change the default behavior, to suite you needs.
Of course this can also be done without using scaffolding, which makes it easy to use Dynamic Data in an existing Web Site.

Architecture

Dynamic Data obtains data entities information from an underlying framework use to represent data entities as CLR types.

Presentaion layer elements

All the template types can be customize, new can be created, etc.

Page Templates

Are pages that render data from a table in the database. Templates for different data views are included in the framework. Among others listing a whole table, displaying master/detail tables, end editing data.

Entity Templates

Templates for a data entity, such as data row and table. Very useful for customizing a custom UI, as it is more flexible than customizing the individual field.

Field Templates

UI templates for the individual data fields. A lot of default templates exists, such as Boolean and text. Normally a different template for displaying and editing data are used.

Filter Templates

Templates for UI filtering, for example displaying tables rows based on another value. Default templates are Boolean, foreign-key and enumeration templates.

A more complete overview can be found the corresponding MSDN page, ASP.NET Dynamic Data Overview.

The next post will be how to create a new Dynamic Data Web Site from scratch using scaffolding.

Friday, May 20, 2011

How to choose between ASP.NET Web Forms, MVC, Dynamic Data, etc.

I've just been attending TechEd 2011 North America, and there was a lot of interesting stuff. Among all the sessions I've attended was a Birds-of-a-Feather (BOF) session called "Choosing between WebForms, MVC, WebPages, Dynamic Data and More", which wasn't a success. The whole point in a BOF session is interactivity and almost none were present, as almost no one in the audience had tried MVC. Because of all the buzz around MVC, this was the most asked question, "Why should I convert my Web Forms page to MVC? What do I get out of it?".
Almost everyone looks for a compelling reason to change, but in fact this question aren't answer easily. There are several reasons for this:
  1. It depends on the project.
  2. Even though the industry are moving towards MVC, Web Forms are still actively developed, and will continue to be.
  3. Most things you can do in MVC, you can also do in Web Forms.
I'll try to address each of these points in this blog post, but first lets start with the difference between Web Forms and MVC.

ASP.NET Web Forms has been around from the start of ASP.NET, it has a very similar structure to ordinary Windows programming with events, but are also very different, specifically with the ASP.NET Page Life Cycle. Because of this it can be relatively hard to unit test, there is a lot of classes involved which can't be mocked easily. Even though there are several ways to make this easier, such as the MVVM and MVP pattern, it all depends on the code structure. A well formed Web Forms page can be just as easy as to maintain as a MVC page.

ASP.NET MVC is a relatively new addition to the .NET framework, but has been around for a long time. MVC stands for Model-View-Controller and works quietly different than Web Forms. It has an totally different structure, but it encourages the developer to use a cleaner separation of concerns.

It depends on the project
Choosing between all different alternatives can be very difficult, as most of it depends on the project. For example if you have a existing site in Web Forms, you create a new site or you site it mostly data driven. All of the technologies can be used in all of the situations, they all have they pros and cons. If the site is mainly data driven, such as an interface to a database, Dynamic Data could be an option. If it is a site that enables a lot of data editing, but also functions a "regular" website, I would personally prefer Web Forms. If you would like strict control over the HTML I would prefer MVC. It all depends.

Web Forms is not dead
Because of all the buzz around MVC, a lot of people starts to think "Is Web Forms dead?", and the answer is "Certinaly not". Web Forms are actively develop, and has and will get a lot of new features which only are available in MVC at the moment. The next version of ASP.NET will among others get:

  • Much better data binding, and customization of the data model, same way as in MVC.
  • JS and CSS combination and minification.
  • Better support for asynchronous operations.
Most things in MVC is possible in Web Forms too
Many people using MVC are very happy for the routing possibilities, with friendly URLs. This is also possible in ASP.NET, using MapPageRoute. Controlling the HTML are also possible in Web Forms, although it is more difficult, because of all the controls you don't know how renders HTML. But the possibility to disable the default auto generated control IDs has helped a lot, making it much easier to control the HTML and use Javascript interaction with these.

Conclusion
The conclusion is that there are now conclusion, it all depends on your project and the requirements. It should be noted that it is possible to use both Web Forms, MVC and Dynamic Data in a single web project, if you start with a Web Forms project it requires some modification to the project file, and manual creation of the folder structure, but when this is done, very things works, and you can mix as required. This is very powerful if you aren't allowed or don't have time to convert the whole web site to MVC. If you start with a MVC project, no modification are necessary, you can just start adding Web Forms pages. Personally I use a Web Forms and MVC hybrid website, and it works like a charm. If your Web Forms site works, are maintainable and you know what your doing, I see no reason to change if unless necessary for some reason. There is a learning curve to MVC, it requires a totally different mindset, but if strict control is necessary, I would say "Take a look at it!".
ASP.NET Web Pages are more hobbyist, easy website creation, but leans more towards MVC than Web Forms.
Hopes this post helps anyone to decide what to do, feel free to leave a comment, question or whatever and I'll try to answer.

Monday, May 9, 2011

Changing database when using ADO.NET

I like ADO.NET and the entity framework, but it also has it shortcomings.
Recently I discovered another shortcoming.
I have a lot databases on the same server, with identical table design, the only reason for using two databases, are for security purposes. The problem here is that the Entity Framework, doesn't allow me to change database, when I need to query all the databases. Of course you can change to connection string at runtime, but this also creates a new connection, and with 200 databases, it is alot of connections.
The solution I came up with was to use the underlying StoreProvider's ChangeDatabase method, the extension method looks like this:
public static void ChangeDatabase(this ObjectContext context, string databaseName)
{
  DbConnection connection = ((EntityConnection)context.Connection).StoreConnection;
            
  // The connection must be open before changing database.
  if (connection.State != ConnectionState.Open)
  {
    connection.Open();
  }

  connection.ChangeDatabase(databaseName);
}
A very easy to use extension method, which works as long as the underlying store provider supports changing the database. Of course you have to ensure that the table schemas are exactly alike, otherwise all kinds of errors could occur.

Tuesday, January 25, 2011

Autofac Part 4 - ContainerBuilder: Advanced

ContainerBuilder - Advanced
Much more than the basic features, explained in Autofac - Part 1, can be done with Autofac.
This post will try to highlight some of them.

Choosing the constructor
Sometimes you are interested in using a specific constructor when resolving a type.
class TwoCtors
{
  public Type[] CalledCtor { get; private set; }

  public TwoCtors(A1 a1)
  {
    CalledCtor = new[] { typeof(A1) };
  }

  public TwoCtors(A1 a1, A2 a2)
  {
    CalledCtor = new[] { typeof(A1), typeof(A2) };
  }
}

public void ResolveWithTwoCtors()
{
  var cb = new ContainerBuilder();
  cb.RegisterType<A1>();
  cb.RegisterType<A2>();
  cb.RegisterType<TwoCtors>().UsingConstructor(selected)
}

There are also another option for choosing constructors, which is using named parameters.
class WithParam
{
  public int I { get; private set; }
  public WithParam(int i, int j) { I = i + j; }
}

public void ResolveWithParams()
{
  var ival = 10;
  var cb = new ContainerBuilder();
  cb.RegisterType<WithParam>()
    .WithParameter(new NamedParameter("i", ival))
    .WithParameter(new NamedParameter("j", ival));
}

Property Injection
Another feature of Autofac is property injection. Which basically means properties are set when an instance are created. There are several ways to do this.

Object initalizer which actually isn't a Autofac feature, but a .NET feature.
builder.Register(c => new A { B = "test" });
Or more advanced
builder.Register(c => new A { B = c.Resolve<B>() });

Using an activated event handler, which supports circular dependencies
builder.Register(c => new A()).OnActivated(e => e.Instance.B = "test");
Or more advanced
builder.Register(c => new A()).OnActivated(e => e.Instance.B = e.Context.Resolve<B>());

And last but not least, property autowiring.
class A
{
  public Val { get; set; }
}
var builder = new ContainerBuilder();
var val = "test";
builder.RegisterInstance(val);
builder.RegisterType<A>().PropertiesAutowired();
var container = builder.Build();
containter.Resolve<A>();

Collection registration
The last feature that will be touched in this post is collection registration.
var builder = new ContainerBuilder();
var cname = "s";
builder.RegisterCollection<string>(cname)
       .As<IEnumerable<string>>();
var s1 = "hello";
var s2 = "world";
builder.RegisterInstance(s1).MemberOf(cname);
builder.RegisterInstance(s2).MemberOf(cname);
var container = builder.Build();
container.Resolve<IEnumerable<string>>();