We have all encountered the situation where we want to show user information on a form. Most people have a FirstName and a LastName (unless you're Prince or Bono) so we would usually show that data in two separate fields or columns.
Here is a way to quickly and easily concatenate MVC ViewModel fields without having to use String.Format. Let MVC concatenate information you.
Firstly, let me set the scene with a simple "ViewModelUser" ViewModel.
- namespace MyApp.Web.Models
- {
- public partial class ViewModelUser
- {
- public int Id { get; set; }
- [Required("This is a required field")]
- [StringLength(50, ErrorMessageResourceName="ValidatedMaxLength", ErrorMessageResourceType=typeof(Generic))]
- [Display("UserName")]
- public string UserName { get; set; }
- [Required("This is a required field")]
- [StringLength(50, ErrorMessageResourceName="ValidatedMaxLength", ErrorMessageResourceType=typeof(Generic))]
- [Display("First Name")]
- public string FirstName { get; set; }
- [Required("This is a required field")]
- [StringLength(50, ErrorMessageResourceName="ValidatedMaxLength", ErrorMessageResourceType=typeof(Generic))]
- [Display("Surname")]
- public string LastName { get; set; }
- [Required("Email is a required field")]
- [StringLength(100, ErrorMessageResourceName="ValidatedMaxLength", ErrorMessageResourceType=typeof(Generic))]
- [Display("Email")]
- [RegularExpressEmailAttribute]
- [DataType(DataType.EmailAddress)]
- public string Email { get; set; }
- }
- }
So now we have a number of fields that "describe" the ViewModelUser class.
A common use case for this is when we want to implement a simple CRUD mechanism. We want to make all users in the system available to an administrator and the most common way to do that is show a list screen, which displays all the users in a tabular format. The administrator can click one of the users in the table and will be directed to an Edit screen. Alternatively, the administrator could click a button to delete the intended user.
List Table
Let's take this table as an example.
| UseName | First Name | Last Name | ||
| Daffy | Daffy | Duck | [email protected] | Edit Delete |
| Mickey | Mickey | Mouse | [email protected] | Edit Delete |
You can see from this table that we have separated the first and last names. This is because we have separate fields in the database, which have flowed through to the ViewModel.
Here is the MVC razor code that renders the table. Take note of the fields in the razor code and how they relate to the fields of the ViewModelUser ViewModel.
- @model IEnumerable
- <ViewModelUser>
- <table class="table table-bordered">
- <thead>
- <tr>
- <th>
- @Html.DisplayNameFor(model => model.UserName)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.FirstName)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.LastName)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.Email)
- </th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- @foreach (var item in Model)
- {
- <tr>
- <td>
- @Html.DisplayFor(modelItem => item.UserName)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.FirstName)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.LastName)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.Email)
- </td>
- <td>
- <input type="button" value="Edit" />
- <input type="button" value="Delete" />
- </td>
- </tr>
- }
- </tbody>
- </table>
Wouldn't it be better use of screen real estate if we combined the first and last name columns into one? That is quite to do.
Firstly, let's make a change to the ViewModel.
- public int Id
- {
- get;
- set;
- }
- [Required("This is a required field")]
- [StringLength(50, ErrorMessageResourceName = "ValidatedMaxLength", ErrorMessageResourceType = typeof(Generic))]
- [Display("UserName")]
- public string UserName
- {
- get;
- set;
- }
- [Required("This is a required field")]
- [StringLength(50, ErrorMessageResourceName = "ValidatedMaxLength", ErrorMessageResourceType = typeof(Generic))]
- [Display("First Name")]
- public string FirstName
- {
- get;
- set;
- }
- [Required("This is a required field")]
- [StringLength(50, ErrorMessageResourceName = "ValidatedMaxLength", ErrorMessageResourceType = typeof(Generic))]
- [Display("Surname")]
- public string LastName
- {
- get;
- set;
- }
- [Required("Email is a required field")]
- [StringLength(100, ErrorMessageResourceName = "ValidatedMaxLength", ErrorMessageResourceType = typeof(Generic))]
- [Display("Email")]
- [RegularExpressEmailAttribute]
- [DataType(DataType.EmailAddress)]
- public string Email
- {
- get;
- set;
- }
- [Display("Full Name")]
- public string FullName
- {
- get {
- return FirstName + " " + LastName;
- }
- }
Notice the property FullName. This is a simple concatenation of the FirstName and LastName fields. Now all we need to do it call that in our razor code. Here is the altered table code.
- @model IEnumerable
- <ViewModelUser>
- <table class="table table-bordered">
- <thead>
- <tr>
- <th>
- @Html.DisplayNameFor(model => model.UserName)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.FullName)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.Email)
- </th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- @foreach (var item in Model)
- {
- <tr>
- <td>
- @Html.DisplayFor(modelItem => item.UserName)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.FullName)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.Email)
- </td>
- <td>
- <input type="button" value="Edit" />
- <input type="button" value="Delete" />
- </td>
- </tr>
- }
- </tbody>
- </table>
And that's all you have to do. You can use this approach with most ViewModel fields to make your razor code much more succinct and easier to write.Till next time .

Gowtham RajamanickamPosted Apr 9, 2015, 4:29 AM
yes vijay
Gowtham RajamanickamPosted Apr 9, 2015, 4:29 AM
good
Afzaal Ahmad ZeeshanPosted Apr 8, 2015, 9:57 PM
Although you didn't get the point. Adding another company would give an extra enumeration for your model content. ;)
Steven WoolstonPosted Apr 8, 2015, 4:58 PM
Well done Afzaal for picking up the "Easter Egg" in that article. Daffy was moonlighting to Disney for the purposes of my article ;)
Vithal WadjePosted Apr 8, 2015, 2:51 PM
nice start keep it up
Santhakumar MunuswamyPosted Apr 8, 2015, 11:19 AM
Good work
NitinPosted Apr 8, 2015, 10:09 AM
Nice
Vijay SPosted Apr 8, 2015, 9:29 AM
Good show. and Likes for Afzaal Ahmad Zeeshan's Comment.you stole the show :)
Afzaal Ahmad ZeeshanPosted Apr 8, 2015, 6:37 AM
Just saying, Daffy Duck is not of Disney, it is of Warner Bros "Looney Tunes" and even Prince have names with First and Surname. Otherwise, the article is great. :)