Introduction
ASP.NET 4.5 Web Forms support model binding. A part of the overall model binding features are Value Providers. A value provider grabs values from a request and binds those values with method parameters. ASP.NET provides several inbuilt value providers and also allows you to create your own. This article discusses what value providers are with examples. It also shows how a custom value provider can be created.
What are Value Providers?
ASP.NET 4.5 model binding makes it possible to have custom methods to perform select, insert, update and delete operations. A value provider is a class whose primary responsibility is to extract a value from an incoming request and bind it with parameters of the select method. ASP.NET provides several inbuilt value providers and also allows you to create your own. A value provider is used as an attribute to select method parameters. The following list enumerates the main value providers readily available to you:
- Form : The form value provider binds values from the Request.Form collection to the method parameters.
- Control : The control value provider binds values selected or entered in controls to the method parameters.
- QueryString : The QueryString value provider binds querystring parameters to the method parameters.
- Cookie : The cookie value provider binds cookie values to the method parameters.
- Session : The session value provider binds session variables to the method parameters.
- Profile : The profile value provider binds profile properties to the method parameters.
- RouteData : The route data value provider binds route parameters to the method parameters.
- ViewState : The ViewState value provider binds ViewState values to method parameters.
In addition to the above value providers you can build your own. To do so you need to create a class that implements IValueProvider interface (as discussed later in this article).
Using Inbuilt Value Providers
In this section you will use a couple of inbuilt value provides – Control and QueryString. So, begin by creating a new Web Form application. Add a new Web Form and design it as shown below:
New Web Form
As you can see the Web Form consists of a DropDownList at the top and a GridView below it. The DropDownList allows you to pick a Country and the GridView shows Employee records for that Country. This example uses the Employees table from the Northwind database. You will need to add the Entity Framework data model for the Employees table to your project. The Employee data model class is shown below:
Employee Data Model Class
Now set the ItemType property of the GridView to ValueProvidersDemo.Employee. Remember to adjust the namespace name as per your setup. Also, set the SelectMethod property to GridView1_GetData. On the same lines set the SelectMethod property of DropDownList1 to DropDownList1_GetData. You will need to write these methods in the code behind. The GridView1_GetData() and DropDownList1_GetData() methods are shown below:
NorthwindEntities db = new NorthwindEntities(); public IQueryable<ValueProvidersDemo.Employee> GridView1_GetData([Control("DropDownList1","SelectedValue")]string country) { var data = from emp in db.Employees where emp.Country == country select emp; return data; } public IQueryable<string> DropDownList1_GetData() { var data = (from emp in db.Employees select emp.Country).Distinct(); return data; }
The GridView1_GetData() method returns IQueryable of Employee objects. Notice the country parameter of this method. It is decorated with the [Control] attribute. To get this attribute you will need to import System.Web.ModelBinding namespace. The [Control] attribute indicates that the value of the parameter will come from a server control. The two parameters of the [Control] attributes indicate the ID of the control and property name of the control whose value is to be bound. In this case the SelectedValue property of DropDownList1 is being bound with the country parameter. Inside, the method selects all of the Employee records whose Country column matches with the country parameter.
The DropDownList1_GetData() method doesn’t use any value provider. Inside, it simply selects unique Country values from the Employees table and returns them as IQueryable of strings.
If you run the form you will find that whenever you change a country in the DropDownList, its value is passed to the GridView1_GetData() method and the grid shows the corresponding records.
Now, let’s use the QueryString value provider before shifting our attention to developing a custom value provider. To use QuertString value provider you will need two Web Forms – one that lists all the Employee records and one that displays just one Employee according to EmployeeID passed in the querystring. Develop the first Web Form as shown below:
First Web Form
The GridView shown above has a HyperLinkField followed by other BoundField columns. The HyperLinkField essentially renders hyperlinks of the form ~/WebForm3.aspx?empid=1. Thus EmployeeID is passed to WebForm3.aspx via a querystring parameter empid. WebForm3.aspx houses a DetailsView that gets its data from DetailsView1_GetItem() method. The DetailsView1_GetItem() method is given below:
NorthwindEntities db = new NorthwindEntities(); public ValueProvidersDemo.Employee DetailsView1_GetItem([QueryString("empid")]int EmployeeID) { var data = from emp in db.Employees where emp.EmployeeID == EmployeeID select emp; return data.SingleOrDefault(); }
Notice that DetailsView1_GetItem() method uses the [QueryString] attribute for the EmployeeID parameter. The [QueryString] attribute specifies the querystring parameter that will be supplying the value. Inside, the DetailsView1_GetItem() method simply selects an Employee record matching the supplied EmployeeID and returns it for the purpose of binding with the DetailsView.
Creating a Custom Value Provider
Now that you know how inbuilt value providers are used, let’s learn to create a custom value provider. You may need to create a custom value provider if none of the existing value providers meet your requirements. Creating a custom value provider is a two-step process:
- Create a class that implements the IValueProvider interface
- Create an attribute class that inherits from the ValueProviderSourceAttribute class
The second step outlined above involves instantiating the custom value provider created in the first step. So, add a new class to the project and name it MyValueProvider1. The MyValueProvider1 class is shown below:
public class MyValueProvider1:IValueProvider { public bool ContainsPrefix(string prefix) { return false; } public ValueProviderResult GetValue(string key) { if (HttpContext.Current.Request.QueryString[key] != null) { string value = HttpContext.Current.Request.QueryString[key]; ValueProviderResult result = new ValueProviderResult(value, value, CultureInfo.CurrentCulture); return result; } else { return null; } } }
The MyValueProvider1 class implements the IValueProvider interface. The IValueProvider expects you to implement the ContainsPrefix() and GetValue() methods. In this example GetValue() is important since it checks for an existence of a querystrinf parameter. The GetValue() method receives a key parameter that is used to pick the correct value. Although this example simply uses querystring parameters (something available through [QueryString] value provider) you can customize the code to pick the value from any data source of your choice. It then creates a new instance of ValueProviderResult class. The ValueProviderResult class represents the result of the value provider and its constructor takes three parameters. The first two parameters are raw value and attempted value respectively and the third parameter is the CultureInfo. The ValueProviderResult is then returned from the GetValue() method.
Now, you need a class that inherits from the ValueProviderSourceAttribute base class. The MyValueProviderAttribute class shown below does just that.
public class MyValueProviderAttribute : ValueProviderSourceAttribute { private string key = ""; public MyValueProviderAttribute(string key) { this.key = key; } public override IValueProvider GetValueProvider(ModelBindingExecutionContext modelBindingExecutionContext) { return new MyValueProvider1(); } public override string GetModelName() { return key; } }
The MyValueProviderAttribute class has a parameterized constructor that takes a string parameter (key). This parameter represents the querystring parameter name that is to be bound with a method parameter. It overrides GetValueProvider() and GetModelName() methods of the ValueProviderSourceAttribute base class. The GetValueProvider() method returns a new instance of MyValueProvider1 class and the GetModelName() returns the key name.
To use MyValueProviderAttribute in the Web Form you will need to replace the code in the WebForm3.aspx as shown below:
NorthwindEntities db = new NorthwindEntities(); public ValueProvidersDemo.Employee DetailsView1_GetItem([MyValueProvider("empid")]int EmployeeID) { var data = from emp in db.Employees where emp.EmployeeID == EmployeeID select emp; return data.SingleOrDefault(); }
As you can see this time instead of using the [QueryString] attribute the code uses the [MyValueProvider] attribute and passes empid as its parameter.
Summary
Value providers are classes that bind values from a request to select method parameters. ASP.NET provides several inbuilt value providers such as [Control] and [QueryString]. You can also create your own value provider by implementing IValueProvider interface.
About the Author:
Bipin Joshi is a blogger, author and an IT trainer who writes about apparently unrelated topics – Yoga & technology! Bipin has been programming since 1995 and is working with .NET framework ever since its inception. He has authored or co-authored half a dozen books and numerous articles on .NET technologies. He has also penned a few books on Yoga. You can read more about him here.