Skip to main content

Asp.net mvc using AutoMapper simplified.

Most of the time in the real world applications it is not possible to map the database model to your presentation view directly because of the fact you may need some additional fields in your view. Using view Data or Viewbag is not always the good idea as it may make things harder or less elegant which are much easier to do.

We are creating the User create view as an example here in which confirm password field is additional field in the view and it has nothing to do with the database model. So in this case you would create one model for the database fields as usual and one extra model for the view. The problem is that in the controller you have to map each property from your model for the database to the model for the view manually which shouldn't be done because it is not a good practice as there is a tool for that. The third party tool the Automapper solves this problem by automatically mapping your view model which you get from the view in the controller to the database model.


User Table

UserName varchar(50)
password varchar(50)

User Model or database model
    public class User
    {
        public string UserName
        {
            get;
            set;
        }

        public string Password
        {
            get;
            set;
        }
    }
UserView Model for the presentation view
    public class UserView
    {
        [Required(ErrorMessage = "UserName Required")]
        public string UserName
        {
            get;
            set;
        }

        [Required(ErrorMessage = "Password Required")]
        public string Password
        {
            get;
            set;
        }

        [Compare("Password")]
        public string ConfirmPassword
        {
            get;
            set;
        }
    }
The generated view in which the model specified is the Userview not the User.

@model MvcApplication22.Models.UserView
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>Creates</title>
</head>
<body>
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    @using (Html.BeginForm()) {
        @Html.ValidationSummary(true)
        <fieldset>
           
    
            <div class="editor-label">
                @Html.LabelFor(model => model.UserName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.UserName)
                @Html.ValidationMessageFor(model => model.UserName)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Password)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Password)
                @Html.ValidationMessageFor(model => model.Password)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.ConfirmPassword)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.ConfirmPassword)
                @Html.ValidationMessageFor(model => model.ConfirmPassword)
            </div>
    
            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>
    }
    
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>
</body>
</html>


Below is the code without Automapper which is not a good practise.Two fields are not the problem but imagine having 15 fields to map which will be quite a task, the number of line will increase also the possibility of an error.

    public ActionResult Creates()
    {
         UserView UserViewModel = new UserView();
         return View("Creates",UserViewModel);
    }

    [HttpPost]
    public ActionResult Creates(UserView UserView)
    {
        // Valdations

        if (ModelState.IsValid)
        {
          User User = new User();
          User.UserName = UserView.UserName;
          User.Password = UserView.Password;
                          
          // Create User code            
        }
        return View();
    }
Now finally automapper in action below.

In global.asax you have to create a map before using it in the controller.

global.asax.

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        Mapper.CreateMap<UserView, User>();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }


Controller.

    public ActionResult Creates()
    {
        UserView UserViewModel = new UserView();
        return View("Creates",UserViewModel);
    }

    [HttpPost]
    public ActionResult Creates(UserView UserView)
    {
        // Valdations
        if (ModelState.IsValid)
        {
           User User = new User();
           //  User.UserName = UserView.UserName;
           //  User.Password = UserView.Password;
           AutoMapper.Mapper.Map(UserView, User);
                          
           // Create User code            
         }
         return View();
     }    

Comments

Popular posts from this blog

Asp.net mvc razor render partial view using ajax helper

This is the extension to my blog in which I demonstrated rendering of the partial view using jquery Ajax . I want to demonstrate here yet another way by which partial view can be rendered without page refresh. Here is the implementation. Step 1: I will again be using DisplayData class in my demo. Here is it. public class DisplayData { public int ID { get; set; } public DisplayData(int ID) { this.ID = ID; } } Step 2: Create a PartialDemo page @model IEnumerable<MvcApplication5.Models.DisplayData> @{ ViewBag.Title = "PartialDemo"; } @Ajax.ActionLink("Click 1", "PartialDemo", "PartialDemo", new {Data= "1" }, new AjaxOptions { UpdateTargetId = "rsvpmsg" }) @Ajax.ActionLink("Click 2", "PartialDemo", "PartialDemo", new {Data= "2" }, new AjaxOptions { UpdateTargetId = "rsvpmsg" }) <div id="rsvpms

Asp.net mvc razor render partial view using jquery Ajax

I will going to demonstrate how we can render PartialViews using Jquery Ajax. I will be clicking an a href link ,then I will be calling the controller through jquery Ajax which will fill the partialview for a really nice user experience. Step 1: First of all we will be creating an DisplayData class for the use for this example in the model. public class DisplayData { public int ID { get; set; } public DisplayData(int ID) { this.ID = ID; } } Step 2: We will create a Clicks page and write the following code on it. Specially note empty here which will going to empty and then fill partialview with new records. $(document).ready(function () { $('.msg').click(function () { var id = this.id; $.ajax({ url: "/Category/Display", data: { data: id }, success: function (mydata) { $("#link").empty().appe

Asp.net mvc DataAnnotation ValidateAttribute two properties comparison.

Using Datannotion is great but there are scenarious in which the current attributes compare, range etc becomes inadequate especially for the comparisions. So we create here our own custom validation using ValidationAttribute class which is the base class for all the annotation attributes. So by deriving from it and overriding the Isvalid method we can create our custom attribute for the model. So here is the scenario in which I will be validating the Username against the password which should not be equal. Compare attribute cannot be used in this scenario so I have created a custom attribute for that. Here is the model with the attribute. User View Model [CompareUserPass("UserName", "Password", ErrorMessage = "UserName and password cannot be equal")] public class UserView { [Required(ErrorMessage = "UserName Required")] public string UserName { get; set; } [Required(