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...

Dotnetnuke Inter-module communication (IMC) simplified on version 06.00.02 with c#

Few days ago I developed a module in which I used IMC which really interested me so I decided to write about it. I will try to explain in this post everything that is necessary to make IMC work in the modules. What is Inter Module Communication? As the name implies if you want to communicate or in other words send data from one module to another IMC is one way of doing it. I will be using module A and module B as the names in my post. An Observation: One thing I observed while playing around with it that if module A is on page 1 and module B is on page 2 then the data doesn't get passed. If both the modules are on the same page then only the data get passed. Example: The basic exercise that I will be performing is to take input from the textbox in Module A and display it in label in Module B. 1) You will be using IModuleCommunicator and IModuleListener interfaces to make this communication works. You will be implementing IModuleCommunicator in the class in the modul...