I have this class
public class Contact
{
public int Id { get; set; }
public string ContaSurname { get; set; }
public string ContaFirstname { get; set; }
// and other properties...
}
And I want to create a form that allo me to edit all those fields. So I used this code
<h2>Contact Record</h2>
@Html.EditorFor(c => Model.Contact)
This works fine, but I want to customize how the elements are displayed. For instance I want each field to be displayed in the same line as its label. Because now, the generated html is like this :
<div class="editor-label">
<label for="Contact_ContaId">ContaId</label>
</div>
<div class="editor-field">
<input id="Contact_ContaId" class="text-box single-line" type="text" value="108" name="Contact.ContaId">
</div>
Create a partial view called
Contact.cshtml
with your custom markup inViews/Shared/EditorTemplates
. This will override the default editor.As noted by @smartcavemen, see Brad Wilson's blog for an introduction to templates.
I agree to the solution of jrummell above: When you use the
EditorFor
-Extension, you have to write a custom editor template to describe the visual components.In some cases, I think it is a bit stiff to use an editor template for several model properties with the same datatype. In my case, I want to use decimal currency values in my model which should be displayed as a formatted string. I want to style these properties using corresponding CSS classes in my views.
I have seen other implementations, where the HTML-Parameters have been appended to the properties using annotations in the Model. This is bad in my opinion, because view information, like CSS definitions should be set in the view and not in a data model.
Therefore I'm working on another solution:
My model contains a
decimal?
property, which I want to use as a currency field. The Problem is, that I want to use the datatypedecimal?
in the model, but display the decimal value in the view as formatted string using a format mask (e.g. "42,13 €").Here is my model definition:
Format mask
0:C2
formats thedecimal
with 2 decimal places. TheApplyFormatInEditMode
is important, if you want to use this property to fill a editable textfield in the view. So I set it totrue
, because in my case I want to put it into a textfield.Normally you have to use the
EditorFor
-Extension in the view like this:The Problem:
I cannot append CSS classes here, as I can do it using
Html.TextBoxFor
for example.To provide own CSS classes (or other HTML attributes, like
tabindex
, orreadonly
) with theEditorFor
-Extension is to write an custom HTML-Helper, likeHtml.CurrencyEditorFor
. Here is the implementation:The idea is to use the original
EditorFor
-Extension to produce the HTML-Code and to parse this HTML output string to replace the created CSS Html-Attribute with our own CSS classes and append other additional HTML attributes. For the HTML parsing, I use the HtmlAgilityPack (use google).In the View you can use this helper like this (don't forget to put the corresponding namespace into the
web.config
in your view-directory!):Using this helper, your currency value should be displayed well in the view.
If you want to post your view (form), then normally all model properties will be sent to your controller's action method. In our case a string formatted decimal value will be submitted, which will be processed by the ASP.NET MVC internal model binding class.
Because this model binder expects a
decimal?
-value, but gets a string formatted value, an exception will be thrown. So we have to convert the formatted string back to it'sdecimal?
- representation. Therefore an ownModelBinder
-Implementation is necessary, which converts currency decimal values back to default decimal values ("42,13 €" => "42.13").Here is an implementation of such a model binder:
The binder has to be registered in the
global.asax
file of your application:Maybe the solution will help someone.