Strongly Typed Data Controls and Modal Binding in ASP.NET 4.5- Part 1

Recently, I took  a session on KolkataGeeks and discussed on  ASP.NET 4.5 enhancements. I mainly discussed on changes in data controls and model binding feature added in ASP.NET4.5.

I am going to write a series of post on the same feature here also. Till date, you all must have  had a look on the enhancement and new features introduced in ASP.NET 4.5. The main change in data control that now it provides intellisense support at aspx pages. You need to assign the ItemType property to model that is going to be associated with the data controls. As

Strongly Typed Data Control

These controls are also referred as Strongly Typed Data Controls.

There are also other major changes took place, in the way we provide the DataSource to the our DataControls. Here in my example, I have taken a GridView.

Earlier, we used to provide DataSource to our Data Control and then call DataBind. We used multiple Data Sources like SQLDataSource, ObjectDataSource etc. But now, you have another option which allows us to not set DataSource property and call the DataBind specifically.

There is a property got introduced named as SelectMethod. We can write our own method at server side and assign the method to this property. One thing, we need to take care that it must return the collection of objects and it should be either IEnumerable or IQueryable. Server side method could be as

public IQueryable<Product> GetProducts()
{
return dbcontext.Products.AsQueryable().OrderBy(i => i.Name);
}

And my gridview at aspx

<asp:GridView ID="gridProducts" runat="server" ItemType="AdventureWorksLTModel.Product" AutoGenerateColumns="false"
SelectMethod="GetProducts" >
<Columns>
<asp:TemplateField HeaderText="Product Name" SortExpression="Name">
<ItemTemplate>
<%#Item.Name %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price" SortExpression="ListPrice">
<ItemTemplate>
<%#Item.ListPrice %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Product Color" SortExpression="Color">
<ItemTemplate>
<%#Item.Color %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

Now why this method should return only IEnumerable or IQueryable . Controls like GridView provides many features like Paging, Sorting etc. As soon as you assign the method to SelectMethod property. You don’t need to write any special code for Paging, Sorting.. feature. For that it creates Linq  queries on the fly and it can be written only on the collection that implements IEnumerable or IQueryable.

That’s not it, in many cases we provide some kind of filter criteria to the users, based on user can view only filtered data.

ASP.NET4.5 provides many Value Providers that can be used and these value providers are

  • Querystring
  • Session
  • Cookie
  • Control Value
  • Form Value etc..

These value provider can be directly used to filter the data. But how?

These value providers must be passed as a parameter in the method, that is going to be assigned to Select method. Let’s if we want Query String as value provider so we can pass it as

public IQueryable<AdventureWorksLTModel.Product> GetProducts([QueryString("key")]string parameter)
{
AdventureWorksLTEntities dbcontext = new AdventureWorksLTEntities();
return dbcontext.Products.Where(p => p.Color == parameter).AsQueryable().OrderBy(i => i.Name);
}

where key is the Query String parameter and it can access the value directly in the method as above.

Similarly other value providers can be used. One more example, we can have some control’s value as value provider. For that in my example, I have created a drop down and I want to use drop down’s selected value for filtering the data it can be used as

<asp:DropDownList ID="ddlColors" runat="server" SelectMethod="GetColors" AutoPostBack="true" ></asp:DropDownList>

Above one is my dropdown. And as you can see, It also has SelectMethod, I have assigned it a GetColors method and it is also written as

public IEnumerable<string> GetColors()
{
var colors = (from c in dbcontext.Products
where c.Color != null
select  c.Color).Distinct();
return colors.ToList();
}

Now my SelectMethod method for gridview is

<pre>public IQueryable<AdventureWorksLTModel.Product> GetProducts([Control]string ddlColors)
{
AdventureWorksLTEntities dbcontext = new AdventureWorksLTEntities();
return dbcontext.Products.Where(p => p.Color == ddlColors).AsQueryable().OrderBy(i => i.Name);
}

You can see the parameter name and it is ddlColors is Id of the dropdown.

Now this is not all. You can also create your own custom value provider. To create your very own Value provider, you need to implement IValueProvider. Here you need to implement a method GetValue which takes a key (string) as a parameter. It returns an instance of ValueProviderResult . It contains the value returned by the ValueProvider.

I created a value provider which takes a value from querystring based on it fetch some data from database and return it. As

public class MyCategoryProvider : IValueProvider
{
private HttpContextBase context;
private string value;
private int limit;
public MyCategoryProvider(HttpContextBase hcb, string val)
{
context = hcb;
value = val;
}

public bool ContainsPrefix(string prefix)
{
throw new NotImplementedException();
}

public ValueProviderResult GetValue(string key)
{
string category = context.Request.QueryString[this.value] as string;
GetPriceLimit(category);
return new ValueProviderResult(limit, limit.ToString(), System.Globalization.CultureInfo.CurrentCulture);
}
}

Now this can not be used directly. Because ValueProvider is used as an Attribute. So now, you need to create a custom attribute which returns the your Value provider.

To Create a Custom attribute you need to inhert from ValueProviderSourceAttribute which is available in namespace System.Web.ModelBinding . Here override the method GetValueProvider which returns the valueprovider. It is wrtitten as

[AttributeUsage(AttributeTargets.Parameter)]
public class CategoryAttribute : System.Web.ModelBinding.ValueProviderSourceAttribute
{
private string code;
public CategoryAttribute(string _code)
{
this.code = _code;
}

public override IValueProvider GetValueProvider(ModelBindingExecutionContext modelBindingExecutionContext)
{
return new MyCategoryProvider(modelBindingExecutionContext.HttpContext, this.code);
}
}

Now your custom value provider is ready for use. Let’s use this

public IQueryable<Product> GetProducts([Category("cat")]int parameter)
{
AdventureWorksLTEntities dbcontext = new AdventureWorksLTEntities();
return dbcontext.Products.AsQueryable().Where(p => p.ListPrice <= parameter).OrderBy(i => i.Name);
}

So, you can see that I have used Category as a Value Provider.

Hope you all have enjoyed the post. I’ll discuss more on Validation and other things in my next post.

Cheers,
Brij

5 thoughts on “Strongly Typed Data Controls and Modal Binding in ASP.NET 4.5- Part 1

  1. Pingback: Strongly Typed Data Controls and Modal Binding in ASP.NET 4.5- Part 2 « Brij's arena of .NET

  2. Pingback: Explore and Learn ASP.NET 4.5 « Brij's arena of .NET

  3. In previous versions of the ASP.NET framework, we have the ObjectDataSource control. But now in ASP.NET 4.5 Microsoft has integrated the ObjectDataSource control with Data ControlsNow the developer can easily bind data controls with the help of the SelectMethod and the developer can also do other Data Control operations with the help if UpdateMethod and DeleteMethod dapfor. com

  4. Great post man, thank you very much!

    I somehow cant make the Control Value as Parameter work.
    The Error on [Control] says:
    ‘System.Web.UI.Control’ is not an attribute class.
    Am I missing something?

    Thanks a lot
    S

Leave a comment