ASP. net mvc simplifies "list control" binding through HtmlHelper Extension

Source: Internet
Author: User


Among many form elements, a <select> element is used to bind a set of predefined lists. In the traditional ASP. NET Web Form, it corresponds to a group of important control types, that is, ListControl. We often use DropDownList, ListBox, CheckBoxList, and RadioButtonList, which are their subclasses. ASP. net mvc binds different types of <select> elements by extending HtmlHelper and HtmlHelper <TModel>. They are defined in SelectExtensions as extension methods. When operating these extension methods, you must manually provide list items represented by the IEnumerable <SelectListItem> object. If we create an independent component to maintain these predefined lists, we can define some simpler extension methods to avoid manually specifying list items. [Download the source code from here]
1. Create an independent list maintenance component
The elements bound to the predefined list of <select> elements are called Code. As a simple demo simulation, we created a component named CodeManager. Let's take a look at the definition of the CodeDescription type used to describe a single Code. The following Code shows that CodeDescription has the ID, Code, Description, inclutivestartdate, and inclutiveenddate. Take the list of countries as an example. Code represents the Code of a country (such as CN), and Description is a readable Description (such as China ). Inclutivestartdate and inclutiveenddate determine the Code validity period. For example, if a group of lists that indicate "tax rates", different lists may be used in different time ranges. In other words, the list as a unified Category (represented by the Category attribute) may have "multiple sets" and they can share the same Code, we use IDs to differentiate these list items with the same Code.
1: public class CodeDescription
2 :{
3: public string Id {get; set ;}
4: public string Code {get; set ;}
5: public string Description {get; set ;}
6: public string Category {get; set ;}
7: public DateTime inclutivestartdate {get; set ;}
8: public DateTime inclutiveenddate {get; set ;}
9:
10: public CodeDescription (string code, string description, string category)
11 :{
12: this. Id = Guid. NewGuid (). ToString ();
13: this. Code = code;
14: this. Description = description;
15: this. Category = category;
16: this. Required tivestartdate = DateTime. MinValue;
17: this. Required tiveenddate = DateTime. MaxValue;
18 :}
19 :}
The following CodeCollection represents a list of CodeDescription, which is directly inherited from the Collection <CodeDescription> type. Since CodeDescription has the concept of validity period, we need to filter out the currently valid Code, so we define the next getinclutivecodes method.
1: public class CodeCollection: Collection <CodeDescription>
2 :{
3: public IEnumerable <CodeDescription> getinclutivecodes ()
4 :{
5: return this. Where (code => code. Required tivestartdate <= DateTime. Today & code. Required tiveenddate> = DateTime. Today). ToList ();
6 :}
7 :}
When binding Code, we all use "category" as the unit. We always get the Code list of a certain category (such as country, gender, marital status and political outlook) bound to the interface. The following Code manager defines a GetCode method to obtain the Code list of a specified category. As Code storage, we use static fields. From the Code shown below, we can see that three types of codes are actually defined, namely Gender, MaritalStatus, and Country, gender, marital status, and nationality.
1: public static class CodeManager
2 :{
3: private static CodeDescription [] codes = new CodeDescription []
4 :{
5: new CodeDescription ("M", "Male", "Gender "),
6: new CodeDescription ("F", "Female", "Gender "),
7: new CodeDescription ("S", "Single", "MaritalStatus "),
8: new CodeDescription ("M", "Married", "MaritalStatus "),
9: new CodeDescription ("CN", "China", "Country "),
10: new CodeDescription ("US", "Unite States", "Country "),
11: new CodeDescription ("UK", "Britain", "Country "),
12: new CodeDescription ("SG", "Singapore", "Country ")
13 :};
14: public static CodeCollection GetCodes (string category)
15 :{
16: CodeCollection codeCollection = new CodeCollection ();
17: foreach (var code in codes. Where (code => code. Category = category ))
18 :{
19: codeCollection. Add (code );
20 :}
21: return codeCollection;
22 :}
23 :}

2. Define the extension method of HtmlHelper to realize binding based on "list category"
Now let's define the Extension Method for HtmlHelper to bind the "List Control" through the Code list obtained from CodeManager. It indicates that the SelectListItem of the list item has two attributes: Text and Value, indicating the displayed Text and the corresponding Value respectively. By default, they correspond to the Description and Code of CodeDescription, but sometimes they need to be customized accordingly. For example, sometimes we want to use the CodeDescription ID as the value of SelectListItem, or display SelectListItem as a combination of Code and Description, such as "CN-China ". For this reason, we define the next BindingOption type.
1: public class BindingOption
2 :{
3: public string OptionalLabel {get; set ;}
4: public string TextTemplate {get; set ;}
5: public string ValueTemplate {get; set ;}
6:
7: public BindingOption ()
8 :{
9: this. OptionalLabel = null;
10: this. TextTemplate = "{Description }";
11: this. ValueTemplate = "{Code }";
12 :}
13 :}
OptionalLabel indicates the Text of the added prompt (for example, "select a Xxx"), while TextTemplate and ValueTemplate indicate the template that is finally used as the Text and Value Attribute of SelectListItem, the template contains the corresponding site signs ({Id}, {Code}, and {Description }).
We have compiled the following four extension methods for HtmlHelper to bind the DropDownList and ListBox. In the parameter, we do not need to provide the SelectListItem list, but only the Code and category. The BindingOption determines the final attributes of Text and Value as SelectListItem, and whether to add a prompt Text and Text content. In a real project, we can define the BindingOption settings in the configuration file.
1: public static class SelectExtensions
2 :{
3: public static MvcHtmlString DropDownList (this HtmlHelper htmlHelper, string name, string codeCategory, BindingOption bindingOption = null)
4 :{
5: bindingOption = bindingOption ?? New BindingOption ();
6: var listItems = GenerateListItems (codeCategory, bindingOption );
7: return htmlHelper. DropDownList (name, listItems, bindingOption. OptionalLabel );
8 :}
9: public static MvcHtmlString DropDownListFor <TModel, TProperty> (this HtmlHelper <TModel> htmlHelper, Expression <Func <TModel, TProperty> expression, string codeCategory, BindingOption bindingOption = null)
10 :{
11: bindingOption = bindingOption ?? New BindingOption ();
12: var listItems = GenerateListItems (codeCategory, bindingOption );
13: return htmlHelper. DropDownListFor <TModel, TProperty> (expression, listItems, bindingOption. OptionalLabel );
14 :}
15:
16: public static MvcHtmlString ListBox (this HtmlHelper htmlHelper, string name, string codeCategory, BindingOption bindingOption = null)
17 :{
18: bindingOption = bindingOption ?? New BindingOption ();
19: var listItems = GenerateListItems (codeCategory, bindingOption );
20: return htmlHelper. ListBox (name, listItems, bindingOption. OptionalLabel );
21 :}
22: public static MvcHtmlString ListBoxFor <TModel, TProperty> (this HtmlHelper <TModel> htmlHelper, Expression <Func <TModel, TProperty> expression, string codeCategory, BindingOption bindingOption = null)
23 :{
24: bindingOption = bindingOption ?? New BindingOption ();
25: var listItems = GenerateListItems (codeCategory, bindingOption );
26: return htmlHelper. ListBoxFor <TModel, TProperty> (expression, listItems );
27 :}
28:
29: public static IEnumerable <SelectListItem> GenerateListItems (string codeCategory, BindingOption bindingOption)
30 :{
31: var items = new List <SelectListItem> ();
32: foreach (var code in CodeManager. GetCodes (codeCategory). getinclutivecodes ())
33 :{
34: var item = new SelectListItem
35 :{
36: Text = FormatTemplate (bindingOption. TextTemplate, code ),
37: Value = FormatTemplate (bindingOption. ValueTemplate, code)
38 :};
39: items. Add (item );
40 :}
41: return items;
42 :}
43:
44: private static string FormatTemplate (string template, CodeDescription code)
45 :{
46: return template. Replace ("{Id}", code. Id)
47:. Replace ("{Code}", code. Code)
48:. Replace ("{Description}", code. Description );
49 :}
50 :}

3. Use these extension methods
Now we create a simple ASP. net mvc application to demonstrate binding to DropDownList and ListBox. For this reason, we define the next Person type, whose Gender, MaritalStatus, and Country attributes correspond to the three groups of codes maintained by CodeManager respectively. In the created HomeController, we define the rendering of the initialized Person object in the Index operation.
1: public class Person
2 :{
3: public string Name {get; set ;}
4: public string Gender {get; set ;}
5: [Display (Name = "MaritalStatus")]
6: public string MaritalStatus {get; set ;}
7: public string Country {get; set ;}
8 :}
9:
10: public class HomeController: Controller
11 :{
12: public ActionResult Index ()
13 :{
14: return View (new Person
15 :{
16: Name = "Zhan San ",
17: Gender = "M ",
18: Country = "CN ",
19: MaritalStatus = "S"
20 :});
21 :}
22 :}
The extension method we define is used in the Index. cshtml view defined by the Index operation. The following is the definition of Index. cshtml:
1: @ model CodeBinding. Models. Person
2 :@{
3: ViewBag. Title = "Index ";
4 :}
5:
6: <table>
7: <tr>
8: <td> @ Html. LabelFor (m => m. Name) </td>
9: <td> @ Html. TextBoxFor (m => m. Name) </td>
10: </tr>
11: <tr>
12: <td> @ Html. LabelFor (m => m. Gender) </td>
13: <td> @ Html. DropDownListFor (m => m. Gender, "Gender", new BindingOption
14 :{
15: OptionalLabel = "Please select your gender ...",
16: TextTemplate = "{Code}-{Description }",
17: ValueTemplate = "{Code }"
18:}) </td>
19: </tr>
20: <tr>
21: <td> @ Html. LabelFor (m => m. MaritalStatus) </td>
22: <td> @ Html. DropDownListFor (m => m. MaritalStatus, "MaritalStatus", new BindingOption
23 :{
24: OptionalLabel = "Please select your marur status ...",
25: TextTemplate = "{Code}-{Description }",
26: ValueTemplate = "{Code }"
27:}) </td>
28: </tr>
29: <tr>
30: <td> @ Html. LabelFor (m => m. Country) </td>
31: <td> @ Html. ListBoxFor (m => m. Country, "Country") </td>
32: </tr>
33: </table>
Finally, let's take a look at the final effect:
 
 

Author: Artech
 
From

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.