Automatic Marking of Required Fields with EditorEntryFor

Using an EditorEntryFor helper makes the code DRYer and opens new possibilities, such as automatic indication of required fields. A small addition in one helper method will mark all required fields in entire MVC web application.

Required Fields MarkedIt’s more or less standard to indicate required fields in a form with a red * next to the label. Entering them one by one in the markup is tedious. Adding them to the description text is outright wrong and will look bad if the description is used in other places, such as validation messages.

They shouldn’t need to be handled at all, since the metadata already contains a property indicating if the field is required or not. If all form entries are created in the same way as I showed in the DRYing MVC Forms with an EditorEntryFor Helper post it’s easy to automatically add a required marker whenever a form field is required.

Instead of calling LabelFor directly, I’ve created an own helper method that checks the IsRequired flag on the metadata.

DRYing MVC Forms with an EditorEntryFor Helper

When creating forms in ASP.NET MVC I use a small helper to keep the code DRY (Don’t Repeat Yourself). The EditorEntryFor helper creates everything needed for a form field – the label, the input and the validation.

When creating line of business applications, a huge part of the coding is often to create forms. Each form can consist of a huge number of fields and each field requires some common formatting. It’s usually quite straightforward with a few divs surrounding a label and the input field. Running the default MVC scaffolding tooling, that’s exactly what’s generated:

<div class="editor-label">
    @Html.LabelFor(model => model.TopSpeed)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.TopSpeed)
    @Html.ValidationMessageFor(model => model.TopSpeed)
</div>

In my opinion that code has two severe problems:

  • It’s too verbose.
  • It’s repeating itself for each form field, making the class name and div structure a pain to modify.

In my projects I usually create a small helper, so the above lines of code can be replaced with one single statement:

@Html.EditorEntryFor(model => model.TopSpeed)

Calling Non Public Setters

Properties with non public setters sometimes make sense – until a unit test requires an object to be set up in a specific state. I don’t want to make the setter public just because of the tests, so I wrote a small helper function that can call non public setters.

The helper returns the object itself, to allow a fluent syntax inside member initialization expressions and uses a lambda to select the member (I do like compile time checking whenever it’s possible).

This is actual code I wrote last week using the helper. It’s part of a set up of an object collection used for unit tests.

Orders = new List<order>
{
  new Order
  {
    OrderId = 983427,
  }.CallNonPublicSetter(o => o.StatusId, OrderStatus.Confirmed),
  new Order
  {
    OrderId = 18956,
  }.CallNonPublicSetter(o => o.StatusId, OrderStatus.Delivered)
};
</order>

The helper is implemented using reflection to access the property to bypass the protection level of the setter.

Merging Expression Trees to Reuse in Linq Queries

Reusing parts of LINQ queries is easily done by chaining methods returning IQueryable. Unfortunately that doesn’t cover some senarios like reusing member initialization lists. To handle such a situation I wrote a Merge extension method for select expressions.

For this post we’ll load the data required for a list of cars and a detail view for one car. When loading the details, more fields are required than when just loading the list. With the merging helper method we can reuse the query for the basic list and just extend it with the added properties.

The basic info for the list view is held in a CarBasicInfo DTO class. The data for the detail view is held in a CarExtendedInfo class which is derived from the CarBasicInfo class. A helper method contains the Select() call to map Car entities to the basic DTO. Now the Merge extension method can be used to merge an expression with the initialization of the additional fields for the extended DTO with the existing helper method for the basic fields.

private Expression<Func<Car, CarBasicInfo>> basicSelect =
    c => new CarBasicInfo
    {
        CarId = c.CarId,
        RegistrationNumber = c.RegistrationNumber
    };
 
var car = ctx.Cars.Select(basicSelect.Merge(c => new CarExtendedInfo
{
    Color = c.Color,
    BrandName = c.Brand.Name
})).Single(c => c.RegistrationNumber == "ABC123");

The RegistrationNumber field is not mentioned in the init list – it is populated by the basic select in the SelectBasicInfo helper method. To accomplish this some (non trivial) rewriting of expression trees is in the Merge method.

Updating EntitySets with LINQ2SQL

This post is written by guest blogger Albin Sunnanbo. He’s a great friend and source of inspiration and also one of the best developers I know. It was Albin that first introduced me to LINQ, EF Migrations and jQuery that I now use daily.

I often find myself in situations where I need to update a collection property on some object in LINQ2SQL to match another collection property. Usually I get those collections to my data layer either from an import or from a complex update in the UI (via my business layer).

The most straight forward way to solve this is to clear all old items in the collection in the database and generate new items. Sometimes this is not possible when you have foreign key constrains and rows in other tables referring your collection items.

Many times I have written code where I try to figure out what items that are new, deleted or just updated and process them accordingly.

Today I finally wrote an extension method that encapsulates this pattern.

Software Development is a Job – Coding is a Passion

I'm Anders Abel, a systems architect and developer working for Kentor in Stockholm, Sweden.

profile for Anders Abel at Stack Overflow, Q&A for professional and enthusiast programmers

The complete code for all posts is available on GitHub.

Popular Posts

Archives

Series

Powered by WordPress with the Passion for Coding theme.