{"id":1913,"date":"2014-12-02T00:00:00","date_gmt":"2014-12-01T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/extending-editor-templates-for-asp-net-mvc\/"},"modified":"2021-05-17T18:34:50","modified_gmt":"2021-05-17T18:34:50","slug":"extending-editor-templates-for-asp-net-mvc","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/extending-editor-templates-for-asp-net-mvc\/","title":{"rendered":"Extending Editor Templates for ASP.NET MVC"},"content":{"rendered":"<div id=\"pretty\">\n<p class=\"start\">Editor Templates are one of the hidden gems in ASP.NET MVC.&#160;&#160; They greatly simplify the process of generating the Views by extending the separation between content and format.&#160;&#160;&#160; We can simply state that we want an Editor without having to stipulate exactly what form that editor should take.&#160;&#160; It&#8217;s a lot simpler to state that you want an Editor without having to say that you want a radio button or a drop  down, or a plain text box.&#160;&#160; We may have a wide range of possibilities  for an appropriate Editor.&#160;&#160; It is nice to hand that over to the  framework to keep track of.<\/p>\n<p class=\"MsoNormal\">In this article, we will step through several examples. We will start with the  built-in editor using a check box for a Boolean value, before trying a slightly more complex drop-down for a NULLable  Boolean.&#160;&#160;&#160; We will then look at creating our own editor for dates  before pushing the boundaries out a bit by creating a reusable editor for a complex type such as an Address model.&#160;&#160;&#160; Along the way, we also explore ways of using jQuery and JavaScript to add functionality to editors so as to  improve usability for our sites.<\/p>\n<h1>A Simple Model<\/h1>\n<p class=\"MsoNormal\">Throughout this article we will reference and build on a simple <code>AddressModel.<\/code> <\/p>\n<pre class=\"lang:c# theme:vs2012\">\tpublic class AddressModel\n\t{\n\tpublic string Line1 { get; set; }\n\tpublic string Line2 { get; set; }\n\tpublic string City { get; set; }\n\tpublic string State { get; set; }\n\tpublic string Zip { get; set; }\n\tpublic bool IsVerified { get; set; }\n\tpublic DateTime DateLastVerified { get; set; }\n\tpublic bool? IsPrimary{get; set; }\n\t}\n<\/pre>\n<p class=\"MsoNormal\">A simple View for such a model may look like this, with some pieces excluded for  brevity:<\/p>\n<pre class=\"lang:xhtml theme:github mark:1,2,3,9,12,13,17,20,21,27,30,31,36,39,40\">\t@using (Html.BeginForm()) {\n\t@Html.AntiForgeryToken()\n\t@Html.ValidationSummary(true)\n\t\n\t&lt;fieldset&gt;\n\t&lt;legend&gt;Address&lt;\/legend&gt;\n\t\n\t&lt;div class=\"editor-label\"&gt;\n\t@Html.LabelFor(model =&gt; model.Line1)\n\t&lt;\/div&gt;\n\t&lt;div class=\"editor-field\"&gt;\n\t@Html.EditorFor(model =&gt; model.Line1)\n\t@Html.ValidationMessageFor(model =&gt; model.Line1)\n\t&lt;\/div&gt;\n\t\n\t&lt;div class=\"editor-label\"&gt;\n\t@Html.LabelFor(model =&gt; model.Line2)\n\t&lt;\/div&gt;\n\t&lt;div class=\"editor-field\"&gt;\n\t@Html.EditorFor(model =&gt; model.Line2)\n\t@Html.ValidationMessageFor(model =&gt; model.Line2)\n\t&lt;\/div&gt;\n\t\n\t...\n\t\n\t&lt;div class=\"editor-label\"&gt;\n\t@Html.LabelFor(model =&gt;model.DateLastVerified)\n\t&lt;\/div&gt;\n\t&lt;div class=\"editor-field\"&gt;\n\t@Html.EditorFor(model =&gt;model.DateLastVerified)\n\t@Html.ValidationMessageFor(model =&gt;\n\tmodel.DateLastVerified)\n\t&lt;\/div&gt;\n\t\n\t&lt;div class=\"editor-label\"&gt;\n\t@Html.LabelFor(model =&gt;model.IsPrimary)\n\t&lt;\/div&gt;\n\t&lt;div class=\"editor-field\"&gt;\n\t@Html.EditorFor(model =&gt;model.IsPrimary)\n\t@Html.ValidationMessageFor(model =&gt;model.IsPrimary)\n\t&lt;\/div&gt;\n\t\n\t&lt;p&gt;\n\t&lt;inputtype=\"submit\"value=\"Save\"\/&gt;\n\t&lt;\/p&gt;\n\t&lt;\/fieldset&gt;\n\t}\n<\/pre>\n<p class=\"MsoNormal\">You will notice that we use the same markup for each property.&#160;&#160; We output a label, an editor directive, and a Validation message; but look what happens when we display the View  <\/p>\n<p class=\"MsoNormal\">\n<p class=\"MsoNormal\">Because <code>IsVerified<\/code> is a Boolean property, MVC selected a check box for the editor and we get a drop-down with values  of <code>true,false<\/code> , and <code>not set<\/code> for <code>IsPrimary<\/code> because it is a NULLable Boolean.&#160;&#160;&#160; These are two built-in editors that are native to MVC which we get without any extra effort.<\/p>\n<h1>Adding a Date Picker<\/h1>\n<p class=\"MsoNormal\">We can make other data types such as <code> DateTime<\/code> get their own custom editor, just by placing a partial View in the <code> EditorTemplates<\/code> folder under the Sharedfolder &#160;and naming it after the target  data type.&#160;&#160; You will need to create this folder yourself since it is  not automatically added to the project.<\/p>\n<p class=\"MsoNormal\">&#160;A <code> DateTime.cshtml<\/code> might look like this &#8230;<\/p>\n<pre class=\"lang:c# theme:vs2012 mark:1,3\">\t@model DateTime?\n\t\n\t@Html.TextBox(\"\", (Model.HasValue ? Model.Value.ToShortDateString() : \n\tstring.Empty),new { @class = \"datePicker\" , \n\t@readonly = \"readonly\"})\n<\/pre>\n<p class=\"MsoNormal\"> &#8230; along with a snippet of jQuery code like this to associate the jQuery UI date picker to the class <code>datePicker<\/code> .<\/p>\n<pre class=\"lang:c# theme:vs2012\">\t\t&lt;script&gt;\n\t&#160;&#160;&#160;&#160; $(function () {\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; $(\".datePicker\").datepicker({\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; showOn: \"button\",\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; buttonImage: \"\/images\/calendar-icon.png\",\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; buttonImageOnly: true,\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; buttonText: \"Select date\"\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });\n\t&#160;&#160;&#160;&#160; });\n\t&lt;\/script&gt;\n<\/pre>\n<p class=\"MsoNormal\">Now when we render our View, we get a nice date picker control for the <code>DateLastVerified<\/code> property &#8230;<\/p>\n<p class=\"illustration\"> <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2102-img51.jpg\" height=\"367\" width=\"337\" alt=\"2102-img51.jpg\" \/><\/p>\n<p class=\"MsoNormal\">&#8230; and when we click on the calendar icon we see the calendar.<\/p>\n<p class=\"MsoNormal\"> \t<img loading=\"lazy\" decoding=\"async\" height=\"224\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2102-img55.jpg\" width=\"327\" alt=\"2102-img55.jpg\" \/><\/p>\n<h2>Some More Interesting Editors<\/h2>\n<p class=\"MsoNormal\">As we just saw, Visual Studio will use our date picker editor based on the data  type.&#160;&#160; The framework matches the name of the data type to the name of  the editor.&#160;&#160;&#160; Fortunately this is not the only matching that the  framework does.&#160;&#160; Matching by data type alone would be too restrictive.&#160;&#160; Looking back at our model, we have a couple of &#160;properties of type <code>string<\/code> that could use a custom editor.&#160;&#160; We would like to have an editor for Zip Codes and one for specifying the State.&#160; A Zip Code editor would limit input to digits and limit it to only 5 digits.&#160;&#160; A State editor would be a drop-down that lists out the valid states that the user could select.<\/p>\n<p class=\"MsoNormal\">You can add an attribute to any property so as to give the framework a hint to  point it in the direction of the correct editor.&#160;&#160; To find the right  template name, it can not only base its match on the data type, the framework can also match on the value of the UIHint  attribute that you add to a property.<\/p>\n<p class=\"MsoNormal\">We now want to extend our Model to include UIHints to specify better editors or  these properties:<\/p>\n<pre class=\"lang:c# theme:vs2012\">\tpublicclassAddressModel\n\t{\n\t&#160;&#160; public string Line1 { get; set; }\n\t&#160;&#160; public string Line2 { get; set; }\n\t&#160;&#160; public string City { get; set; }\n\t&#160;&#160; [UIHint(\"State\")]\n\t&#160;&#160; public string State { get; set; }\n\t&#160;&#160; [UIHint(\"ZipCode\")]\n\t&#160;&#160; public string Zip { get; set; }\n\t&#160;&#160; public bool IsVerified { get; set; }\n\t&#160;&#160; public DateTime DateLastVerified { get; set; }\n\t&#160;&#160; public bool? IsPrimary{get; set; }\n\t}\n\t\n<\/pre>\n<p class=\"MsoNormal\">A<code>ZipCode.cshtml<\/code> might look like this:<\/p>\n<pre class=\"lang:c# theme:vs2012 mark:1,3\">\t@model string\n\t\n\t@Html.TextBox(\"\", (Model),\n\tnew { @class = \"zipCode\" , maxlength=\"5\"})\n<\/pre>\n<p class=\"MsoNormal\">We set the <code>maxLength<\/code> attribute to limit it to 5 characters.&#160;&#160; If you  support a zip plus 4, I recommend two text boxes; one with a max length of 5, and one with a max length of 4.&#160;&#160; We also specify the class to attach the JavaScript later.<\/p>\n<p class=\"MsoNormal\">We can add supporting JavaScript to limit input to only numbers and some  navigational characters. We do it like this:<\/p>\n<pre>\t$(document).ready(function() {\n\t&#160;&#160;&#160; $(\".zipCode\").keydown(function (e) {\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/ Allow: backspace, delete, tab, escape, enter\n\t&#160;&#160;&#160;&#160;&#160; &#160; if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110]) !== -1 ||\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/ Allow: Ctrl+A\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (e.keyCode == 65 &amp;&amp;e.ctrlKey === true) || \n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/ Allow: navigation keys\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (e.keyCode&gt;= 35 &amp;&amp;e.keyCode&lt;= 39)) {\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/ let these keys through\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return;\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160; \n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/ Stop anything not a number\n\t&#160;&#160;&#160;&#160;&#160;&#160; if ((e.shiftKey || (e.keyCode&lt; 48 || e.keyCode&gt; 57)) \n\t&#160;&#160;&#160;&#160;&#160;&#160; &amp;&amp; (e.keyCode&lt; 96 || e.keyCode&gt; 105)) {\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.preventDefault();\n\t&#160;&#160;&#160;&#160;&#160;&#160; }\n\t});\n\t\n<\/pre>\n<p class=\"MsoNormal\"><code>State.cshtml<\/code>   may look like this with no supporting JavaScript required.<\/p>\n<pre class=\"lang:c# theme:vs2012 mark:1,3,7,9\">\t@model&#160;string\n\t&#160;\n\t@{&#160;ViewData [\"states\"] =&#160;new&#160;SelectList(new[]\n\t&#160;&#160; {\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160;\" \",&#160;&#160;\"GA\",&#160;\"NC\",&#160;\"SC\",&#160;\"VA\"\n\t&#160;&#160; }.Select(x =&gt;&#160;new&#160;{value = x, text = x}),&#160;\"value\",&#160;\"text\", @Model);\n\t}\n\t&#160;\n\t@Html.DropDownList(\"states\")\n<\/pre>\n<p class=\"MsoNormal\">With these editors in place our View looks a little different, but it will  behave quite a bit differently.<\/p>\n<p class=\"MsoNormal\">\n<p class=\"MsoNormal\">The state is now a drop down with the values listed in the Editor template.&#160;&#160; This is the most obvious change.&#160;&#160; The changes to the Zip are not  visible, but based on the template, we are now capped at 5 characters and only the navigation keys and numeric keys will  be accepted.<\/p>\n<p class=\"MsoNormal\">The key thing to note with the Zip Editor is that we can easily attach whatever  JavaScript we need to support the editing scenarios that we want.&#160;&#160;&#160; We can easily wire up blur and focus event handlers as well as the key-down event that you saw here.&#160;&#160; Had this been a currency field, we might want to wire up a blur event handler to format the inputted value as  currency and a focus event handler to remove the formatting to make it easier to edit.&#160;&#160; You may also want to modify the key-down event handler to allow a decimal point as well as only 2 digits after  the decimal.&#160;&#160;&#160; You have lots of possibilities.<\/p>\n<p class=\"MsoNormal\">Also with the State editor, you probably would not want to hard-code the values  in the Editor.&#160;&#160;&#160; You would most likely retrieve them from the  database.&#160;&#160;&#160; You may also want to make this data-access logic  asynchronous.&#160;&#160;&#160; This is easily done by having the Editor add the  script to make an AJAX call that will retrieve the list of valid values after the initial page load.&#160;&#160;&#160; This is a great way to handle all types of drop down lists.<\/p>\n<p class=\"MsoNormal\">Regardless of how simple or complex, you make your Editor, the View itself stays  the same with a simple call to <code>EditorFor().<\/code> <\/p>\n<h1>Editors for Models<\/h1>\n<p class=\"MsoNormal\">As we saw earlier, Visual Studio will use our date-picker editor simply because  the name of the editor matches the data type of the property.&#160;&#160;&#160;  The same can happen if the editor&#8217;s name matches a more complex name like <code> AddressModel<\/code> .<\/p>\n<p class=\"MsoNormal\">We don&#8217;t need to change anything in the markup for our View.&#160; We simply need to move most of it to the <code>EditorTemplate<\/code> folder and  rename it to <code>AddressModel.cshtml<\/code> <\/p>\n<p class=\"MsoNormal\">\n<p class=\"MsoNormal\">Now our View can be simplified to this.&#160;&#160; Everything else is in the Editor Template<\/p>\n<pre class=\"lang:c# theme:vs2012 mark:1,2,3,4\">\t@using (Html.BeginForm()) {\n\t@Html.AntiForgeryToken()\n\t@Html.ValidationSummary(true)\n\t@Html.EditorFor(m =&gt; m)\n\t&lt;p&gt;\n\t&#160;&#160; &lt;inputtype=\"submit\"value=\"Save\"\/&gt;\n\t&lt;\/p&gt;\n\t}\n\t\n<\/pre>\n<p class=\"MsoNormal\">&#8230; or if we have a more complex Model using <code> AddressModel<\/code> as one of the properties, it now fits right at home.<\/p>\n<p class=\"MsoNormal\">Consider a simple <code>EmployeeModel<\/code> that includes the <code>AddressModel<\/code> that we have been  using.<\/p>\n<pre class=\"lang:c# theme:vs2012\">\tpublicclassEmployeeModel\n\t{\n\tpublic stringFirstName { get; set; }\n\tpublic stringLastName { get; set; }\n\tpublicAddressModel Address { get; set; }\n\tpublicDateTimeHireDate { get; set; }\n\t}\n<\/pre>\n<p class=\"MsoNormal\">\n<p class=\"MsoNormal\">Following the pattern we have used so far, our View will naturally flow:<\/p>\n<pre class=\"lang:xhtml theme:github mark:3,4,5,11,14,15,19,22,23,26,29,32,33\">\t&lt;h2&gt;Employee&lt;\/h2&gt;\n\t\n\t@using (Html.BeginForm()) {\n\t@Html.AntiForgeryToken()\n\t@Html.ValidationSummary(true)\n\t\n\t&lt;fieldset&gt;\n\t&lt;legend&gt;EmployeeModel&lt;\/legend&gt;\n\t\n\t&lt;div class=\"editor-label\"&gt;\n\t@Html.LabelFor(model =&gt;model.FirstName)\n\t&lt;\/div&gt;\n\t&lt;div class=\"editor-field\"&gt;\n\t@Html.EditorFor(model =&gt;model.FirstName)\n\t@Html.ValidationMessageFor(model =&gt;model.FirstName)\n\t&lt;\/div&gt;\n\t\n\t&lt;div class=\"editor-label\"&gt;\n\t@Html.LabelFor(model =&gt;model.LastName)\n\t&lt;\/div&gt;\n\t&lt;div class=\"editor-field\"&gt;\n\t@Html.EditorFor(model =&gt;model.LastName)\n\t@Html.ValidationMessageFor(model =&gt;model.LastName)\n\t&lt;\/div&gt;\n\t&lt;div class=\"editor-field\"&gt;\n\t@Html.EditorFor(model =&gt;model.Address)\n\t&lt;\/div&gt;\n\t&lt;div class=\"editor-label\"&gt;\n\t@Html.LabelFor(model =&gt;model.HireDate)\n\t&lt;\/div&gt;\n\t&lt;div class=\"editor-field\"&gt;\n\t@Html.EditorFor(model =&gt;model.HireDate)\n\t@Html.ValidationMessageFor(model =&gt;model.HireDate)\n\t&lt;\/div&gt;\n\t\n\t&lt;p&gt;\n\t&lt;inputtype=\"submit\"value=\"Save\"\/&gt;\n\t&lt;\/p&gt;\n\t&lt;\/fieldset&gt;\n\t}\n<\/pre>\n<p class=\"MsoNormal\">and we get a nice looking View:<\/p>\n<p class=\"MsoNormal\">\n<p class=\"MsoNormal\">\n<p class=\"MsoNormal\">The evaluation of our editor templates happens recursively.&#160;&#160; Even though the <code>AddressModel.cshtml<\/code> was already in the <code>EditorTemplates<\/code> folder, it gets evaluated for more editor templates.<\/p>\n<p class=\"MsoNormal\">\n<h1>Display Templates<\/h1>\n<p class=\"MsoNormal\">Display Templates are similar to Editor Templates.&#160;&#160;&#160; Display Templates are intended just to display the value with no edit capabilities.&#160;&#160; Often this will take the form of a disabled control or a regular html label.<\/p>\n<p class=\"MsoNormal\">Switching the <code>EditorFor<\/code> to <code>DisplayFor<\/code> in our earlier View, you can see that we  get a mix of disabled controls and labels.<\/p>\n<p class=\"MsoNormal\"> <img loading=\"lazy\" decoding=\"async\" height=\"263\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2102-img5F.jpg\" width=\"304\" alt=\"2102-img5F.jpg\" \/><\/p>\n<p class=\"MsoNormal\">My personal preference is to forego the disabled controls.&#160; We will also apply some additional formatting on the date fields.<\/p>\n<p class=\"MsoNormal\">Let&#8217;s start with a Boolean Display Template.&#160;&#160;&#160;&#160; We will need to handle both NULLable and regular Boolean values in our template.&#160;&#160; So our <code>Boolean.cshtml<\/code> might look like this:<\/p>\n<pre class=\"lang:c# theme:vs2012 mark:1,3,20\">\t@model bool?\n\t\n\t@{\n\tif (!Model.HasValue)\n\t&#160;&#160;&#160; {\n\t&lt;imgsrc=\"\/Images\/question-icon.png\"\/&gt;\n\t&#160;&#160;&#160; }\n\telse\n\t&#160;&#160;&#160; {\n\t\n\tif (Model.Value)\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160; {\n\t&lt;imgsrc=\"\/Images\/true-icon.png\"\/&gt;\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160; }\n\tif (Model.Value == false)\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160; {\n\t&lt;imgsrc=\"\/Images\/false-icon.png\"\/&gt;\n\t&#160;&#160;&#160;&#160;&#160;&#160;&#160; }\n\t&#160;&#160;&#160; }\n\t}\n<\/pre>\n<p class=\"MsoNormal\">Here we explicitly test the three possible states for the NULLable Boolean which  will also cover the two possible states for the regular Boolean.&#160;&#160; Note  that whether it is a NULLable or non NULLable value, it matches the filename <code> Boolean<\/code> .&#160;&#160; This works out well because none of the special  characters used to specify a NULLable data type are valid for file names.<\/p>\n<p class=\"MsoNormal\">Now let&#8217;s turn our attention to the <code> DateTime<\/code> Display Template.&#160;&#160; Quite often we don&#8217;t really care about  the time part of the date time.&#160;&#160; Even in cases where we do care, we  still may want to format it a bit differently then we see by default.&#160;&#160;&#160;&#160; We also may want to draw attention to missing dates.<\/p>\n<p class=\"MsoNormal\">So our Display Template might look like this:<\/p>\n<pre class=\"lang:c# theme:vs2012 mark:1,3,5\">\t@model DateTime?\n\t\n\t@if (Model.HasValue)\n\t{\n\t&lt;span&gt;@Model.Value.ToString(\" MM \/ dd \/ yyyy\")&lt;\/span&gt;\n\t}\n\telse\n\t{\n\t&lt;span&gt;No date entered!&lt;\/span&gt;\n\t}\n<\/pre>\n<p class=\"MsoNormal\">\n<p class=\"MsoNormal\">Here we are only displaying the date part.&#160;&#160; We have spread it out a bit so that it doesn&#8217;t look so squished, and we explicitly draw attention to missing  dates.&#160;&#160;&#160; If we needed to show the time as well, we might instead  opt for something like this:<\/p>\n<pre class=\"lang:c# theme:vs2012 mark:1\">\t&lt;span&gt;@Model.Value.ToString(\" MM \/ dd \/ yyyy&#160; @ hh : mm tt\")&lt;\/span&gt;\n<\/pre>\n<p class=\"MsoNormal\">You may want to do something similar to format currency fields or percentages.&#160;&#160;&#160; You may chose to store phone numbers as just the numbers but want to include the formatting characters when you  display them.&#160;&#160;&#160;&#160; You may want to explicitly strip out key  pieces of personal identifiable information.&#160;&#160;&#160;&#160; There are  many uses for being able to specify an alternate template for displaying values.<\/p>\n<p class=\"MsoNormal\"> \t<img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/2102-img60.jpg\" alt=\"2102-img60.jpg\" \/><\/p>\n<h1>Conclusion <\/h1>\n<p class=\"MsoNormal\">Editor Templates make it easy to add more functionality to our pages, thereby  enhancing usability.&#160;&#160; At the same time, they make it easier to build up  our Views.&#160;&#160; We merely specify that we want an Editor without having to  get bogged down in the details of what form that Editor should take.&#160;&#160;&#160; Also, once in place, they help to make the web application look and behave more consistently.&#160;&#160;&#160; Because we are only specifying that we want an Editor and allowing the framework to fill in the rest, we have  fewer places where inconsistencies can be introduced.<\/p>\n<p class=\"MsoNormal\">At the other end of the spectrum, we have <code> Display<\/code> templates to simplify displaying data with no edit capabilities.&#160;&#160; <code>Display<\/code> templates and <code>Editor<\/code> Templates follow the same matching rules for finding templates.&#160;&#160;Together they complement each other to bring consistency to both editing and displaying data in your web  application.<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>If you find yourself doing routine work repeatedly in ASP.NET MVC, it is worth exploring the possibilities that come from modifying or creating Editor Templates in Visual Studio. Templates can save you a lot of time when creating views or other  default content. Nick Harrison explains.&hellip;<\/p>\n","protected":false},"author":221853,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[4143,4156,4157,4178,5166],"coauthors":[],"class_list":["post-1913","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","tag-net","tag-asp","tag-asp-net","tag-bi","tag-mvc"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1913","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221853"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=1913"}],"version-history":[{"count":7,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1913\/revisions"}],"predecessor-version":[{"id":91052,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1913\/revisions\/91052"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=1913"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=1913"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=1913"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=1913"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}