BTI420 notes – Wed Feb 5

Data annotations. AutoMapper.

.

Data annotations overview

Data annotations are descriptive text attributes that we add to properties in a class. A data annotation is located just before/above the property declaration.

Data annotations can help with:

  • property constraint and limits
  • input data validation
  • property display and formatting in views
  • communicating error messages to users

Some data annotations are intended only for design model classes, while others are for use with view model classes. And, some work with both.

Their overall benefit is to reduce the amount of code that has to be written to handle typical data management scenarios.

Please note that data annotations DO NOT replace the need to validate data against business rules and/or application logic. You still need to do that. Data annotations help most by improving the quality of input data, so that it can then be inspected for its integrity and appropriateness.

.

Data annotations for design model classes

In your design model classes source code file, add a ‘using’ directive for this namespace:

System.ComponentModel.DataAnnotations

Useful data annotations for design model classes include:

[Required] (implemented as ‘not null’ in the database)

[StringLength(n)] (implemented as a specific ‘varchar’ value in the database)

You can comma-separate multiple data annotations.

Value types (e.g. int, double) CANNOT use the [Required] attribute.

There are a few others that you may use occasionally; we may discuss them later in the course.

Do you need a ‘default value’ for a property? A data annotation will not help.

Instead, as you have learned, simply create a class constructor, and set the property’s default value there.

.

Data annotations for view model classes

The course textbook has good coverage in Chapter 6, “Data Annotations and Validation”. We will rely on its coverage, and adapt it to match the learning path that we’ve been following in the course.

In your view model classes source code files, add a ‘using’ directive for this namespace:

System.ComponentModel.DataAnnotations

Useful data annotations for view model classes include:

[Required]

[StringLength(n)] or [StringLength(n, MinimumLength = m)]

[Range(min, max)] (int or double types) 

[Display(Name=”Improved property display name”)]  

[DataType(DataType.Password)] (others include EmailAddress, Url, Currency, Date, Time, and MultilineText)

[RegularExpression(“regex“)] (a regular expression; omit the ^ and $ delimiters, because they’re assumed)

In a regular expression, sometimes you need the backslash character (e.g. \d). In a .NET Framework string, the backslash is a quote character. So, you either precede the entire string with an at sign (@), or use a double backslash (\\d).

As before, you can comma-separate multiple data annotations, and value types (e.g. int, double) CANNOT use the [Required] attribute (but the [Range(min, max)] attribute effectively solves that problem).

The System.Web.Mvc namespace adds some other useful data annotations. One that’s commonly used:

[Compare(“OtherProperty”)] (compares the property with “OtherProperty”; they must match) 

There are a few other data annotations, or parameters for them, that you may use occasionally; we may discuss them later in the course. They include ScaffoldColumn, DisplayFormat, ReadOnly, and HiddenInput.

.

Custom error messages

All attributes accept a parameter named “ErrorMessage”. The value is a custom error message for the user. For example:

[Range(2, 6, ErrorMessage=”Selected gizmos must range from 2 to 6″)]

.

Introduction to the ASP.NET MVC validation process

Validation happens client-side. The delivered HTML5 markup takes advantage of your browser’s capabilities.

Validation also happens server-side, when posted. The best thing you can do is to use ModelState.IsValid.

Validation problem?

Send the bad data back to the view (this is new; before we just returned to the index view). 

.

What is AutoMapper? What problem does it solve?

If you studied the code in the DataAnnotationsBasic web app code example, you saw many lines of code that simply mapped or assigned property values between objects. When mapping between objects that have many properties (20+ for example), you’ll have at least a line of code for every property.

That’s tedious. Boring. Error-prone. Ugly.  Awful.

Avoidable.

AutoMapper, by Jimmy Bogard, helps solve this problem. (Here’s his blog post that introduced AutoMapper.)

It is a convention-based mapper: When it maps between classes, it simply maps / assigns values if the property types and property names match. Easy. Non-matching properties are ignored. (There are many other features, and you will learn some of then later in this course.)

How do you add AutoMapper to your app?

Via NuGet: In Solution Explorer, right-click your project, and choose “Manage NuGet Packages”. A dialog appears. In the left-side navigator, click/select “Online”. In the upper-right “search” area, enter (and look for) “automapper”.

The search results appear in a list in the middle panel. Click/select the AutoMapper item, and click the “Install” button. This action will copy the AutoMapper library to your “packages” folder, and update your project’s “packages.config” source code file.

Now it’s ready to use anywhere, simply by adding a “using AutoMapper;” directive to any source code class file.

.

Configuring maps

The best practice way to configure and use AutoMapper is described next.

In your MvcApplication class (in the Global.asax.cs source code file), add statements that will “configure” maps. This action ensures that a map is available to any of your project’s classes. For example:

  • Mapper.CreateMap< source_type , destination_type >();

The CreateMap method defines a mapping relationship between two classes.

  • The first parameter is the “source” class.
  • The second parameter is the “destination” class.

automapper-define-map

.

Add these “configure” statements for every map that you think that you’ll need. Group them by design model class. You will need one or more:

  • Create maps “to” view model classes (from design model classes)
  • Create maps “from” view model classes (to design model classes)

For each use case and its view model class, create a map, from a design model class, to the custom-and-specific view model class that will service that use case.

Typically, you will have maps that “shape” the delivery of data to the view.

Also, you will have maps that enable a view to “add” or “update” items.

Occasionally, you can even map between view model classes, where both the source and destination is a view model class.

You will see that in the AutoMapperIntro web app code example, in the controller method that handles the creation of a new vehicle. There’s a mapping between a “VehicleAdd” class and a “VehicleAddForm” class. Very convenient.

.

Using maps

After the maps have been defined you can use the Mapper.Map<T>() method anywhere you need to (e.g. in a Manager class, or in a controller method). Sources and destinations can be an object, or a collection of objects. One statement replaces several. What a deal.

For example:

  • Mapper.Map< target_type >( source_type );

automapper-use-map

.

FYI – answers to Quiz 1 questions

Question 1 answer: 

Notes from January 8

Question 2 answer:

Notes from January 8

C# Programming Guide

Question 3 answer:

Notes from January 15

.

.

.

.

.

.

.

.

.

.

.

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: