Monday, October 29, 2012

How to Use ViewModel with ASP.NET MVC

How to Use ViewModel with ASP.NET MVC

What is a Model
  • Parts of the application that implement the domain logic.
  • also known as business logic.
  • Domain logic handles the data that is passed between the database and the UI.
  • As an example, in an inventory system, the model keeps track of the items in storage and the logic to determine whether an item is in stock.
  • In addition, the model would be the part of the application that updates the database,when an item is sold and shipped out of the warehouse.
  • Often, the model also stores and retrieves model state in a database.

What is a ViewModel
  • Allow you to shape multiple entities from one or more data models or sources into a single object.
  • Optimized for consumption and rendering by the view.

It shows below image


How to Use ViewModel with ASP.NET MVC


Why We Use ViewModel

1. If you need to pass more than one thing to a strongly-typed view (which is best practice),
    you will generally want to create a separate class to do so.

2. This allows you to validate your ViewModel differently than your domain model for
    attribute-based validation scenarios

3. Can be used to help shape and format data.
    e.g: need a date or money value formatted a particular way?
          ViewModel is the best place to do it.

4. The use of a ViewModel can make the interaction between model and view more simple

             ViewModel Interaction with Model and View

How to Use ViewModel with ASP.NET MVC


Where Should We Create ViewModel (physically)

1. In a folder called ViewModels that resides in the root of the project. (small applications)

How to Use ViewModel with ASP.NET MVC

2. As a .dll referenced from the MVC project (any size applications)

3. In a separate project(s) as a service layer, for large applications that generate
    view/content specific data. (enterprise applications)


Best Practices When Using ViewModels

1. Put only data that you'll render (use in View) in the ViewModel

2. The View should direct the properties of the ViewModel, this way it fits better for rendering
    and maintenance

3. Use a Mapper when ViewModels become Complex (i.e. How to Use ValueInjecter ? )


Let's Try with Simple Example
  • Asp.net MVC 5,C# and Visual Studio 2013 express has been used.
  • Please follow an In-line Comments on Code. 
  • This is a simple application with product category drop down list, product name text box and Save button.   

Sample Project's Solution Tree


How to Use ViewModel with ASP.NET MVC


Domain Models

Product.cs

  public class Product
    {
        public Product() { Id = Guid.NewGuid(); }
        public Guid Id { get; set; }
        public string ProductName { get; set; }

        public virtual ProductCategory ProductCategory { get; set; }

    }


ProductCategory.cs

    public class ProductCategory
    {
        public int Id { get; set; }
        public string CategoryName { get; set; }

        public virtual ICollection<Product> Products { get; set; }
    }


ViewModel

ProductViewModel.cs

 public class ProductViewModel
    {
        public Guid Id { get; set; }

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

        public int SelectedValue { get; set; }

        public virtual ProductCategory ProductCategory { get; set; }

        [DisplayName("Product Category")]
        public virtual ICollection<ProductCategory> ProductCategories { get; set; }
   }


Controller Action Methods

           /// <summary>
        /// to generate view with categories for entering product data
        /// </summary>
        [HttpGet]
        public ActionResult AddProduct()
        {
            //instantiate the product repository
            var productRepository = new ProductRepository();

            //for get product categories from database
            var prodcutCategories = productRepository.GetAllProductCategories();

            //for initialize viewmodel
            var productViewModel = new ProductViewModel();

            //assign values for viewmodel
            productViewModel.ProductCategories = prodcutCategories;

            //send viewmodel into UI (View)
            return View("AddProduct", productViewModel);
        }

         /// <summary>
     /// to save entered data
     /// </summary>
     [HttpPost]
     public ActionResult AddProduct(ProductViewModel productViewModel) //save entered data
     {
        //instantiate the product repository
        var productRepository = new ProductRepository();

//get product category for selected drop down list value
 var prodcutCategory=productRepository.GetProductCategory(productViewModel.SelectedValue);

        //for get all product categories
        var prodcutCategories = productRepository.GetAllProductCategories();

        //for fill the drop down list when validation fails
        productViewModel.ProductCategories = prodcutCategories;

        //for initialize Product domain model
        var productObj = new Product
          {
              ProductName = productViewModel.ProductName,
              ProductCategory = prodcutCategory,
          };

        if (ModelState.IsValid) //check for any validation errors
          {
             //code to save valid data into database
               
           return RedirectToAction("AddProduct");
          }
          else
          {
             //when validation failed return viewmodel back to UI (View)
             return View(productViewModel);
          }
    }


View

How to Use ViewModel with ASP.NET MVC



AddProduct.cshtml

@model ASPViewModel.ViewModels.ProductViewModel  //set your ViewModel here

<div class="boxedForm">

    @using (Html.BeginForm())
    {
        Html.EnableClientValidation(true);

        <ul style="margin-top:50px;">
            <li style="width: 370px">
                @Html.LabelFor(m => m.ProductCategories)
                @Html.DropDownListFor(m => m.SelectedValue,
new SelectList(Model.ProductCategories, "Id","CategoryName"), "-Please select a category-")
                @Html.ValidationMessageFor(m => m.ProductCategory.Id)
            </li>
            <li style="width: 370px;margin-top:10px;">
                @Html.LabelFor(m => m.ProductName)
                @Html.EditorFor(m => m.ProductName)
                @Html.ValidationMessageFor(m => m.ProductName)
            </li>
        </ul>
        <div class="action">
            <button class="actionButton" type="submit">
                <span>Save</span>
            </button>
        </div>
    }

</div>

Repository Methods by using the Entity Framework

ProductRepository.cs

  public class ProductRepository
    {
        /// <summary>
        /// to get product category
        /// </summary>
        public ProductCategory GetProductCategory(int categoryId)
        {
            var productCategoryList = GetAllProductCategoriesMockDatas();

            return (from p in productCategoryList
                    where (p.Id == categoryId)
                    select p).FirstOrDefault();
        }

        /// <summary>
        /// to get all product categories
        /// </summary>
        /// <returns></returns>
        public List<ProductCategory> GetAllProductCategories()
        {
            var productCategoryList = GetAllProductCategoriesMockDatas();

            return (from p in productCategoryList
                    select p)
                    .OrderBy(p => p.CategoryName)
                    .ToList();
        }

        /// <summary>
        /// to Get All Product Categories mock datas
        /// </summary>
        private List<ProductCategory> GetAllProductCategoriesMockDatas()
        {
            var productCategoryList = new List<ProductCategory>();

            productCategoryList.Add(new ProductCategory
            {
                Id = 1,
                CategoryName = "Foods",
            });

            productCategoryList.Add(new ProductCategory
            {
                Id = 2,
                CategoryName = "Toys",
            });

            productCategoryList.Add(new ProductCategory
            {
                Id = 3,
                CategoryName = "Mobile Phones",
            });

            return productCategoryList;
        }


    }


Conclusion
  • ViewModels help you organize and manage data in MVC applications when you need to work with more complex data than the other objects allow.
  • Using ViewModels gives you the flexibility to use data as you see fit.
  • ViewModels are generally a more flexible way to access multiple data sources than domain models.
  • Even for simple scenarios always try to use ViewModel approach to maintain consistency in Your coding practices.

I hope this helps to You.Comments and feedback greatly appreciated.

If you feel it was a good article,Give me a +1.Thank You.




76 comments:

  1. Good info!

    - Aleksandr Golovatuy -

    ReplyDelete
    Replies
    1. Hi Aleksandr,

      Thanks for your quick response.
      Do Keep in Touch.

      Delete
  2. Replies
    1. Hi Danilo,

      Thanks for your response.
      Do Keep in Touch.

      Delete
  3. Maybe you can recommend some good books about ASP.NET MVC

    - Aleksandr Golovatuy -

    ReplyDelete
    Replies
    1. Hi Aleksandr,

      Yes.If you can follow "ASP.NET MVC in Action" books from "MANNING" Publications.Its really fine.
      Latest book is "ASP.NET MVC 4 in Action".
      Good Luck.

      Delete
  4. Nice , superb clean explanation with guide .
    Keep up the great job !
    Cheers.

    ReplyDelete
    Replies
    1. Hi Hasitha,

      Thanks for your appreciation.
      Do Keep in Touch.

      Delete
  5. Thanks Sampath.

    Already we are working in a MVC Razor project.

    -Aref Samad-

    ReplyDelete
    Replies
    1. Hi Aref,

      Nice to hear you.If you having any problem let me know.
      Do Keep in Touch.

      Delete
  6. likes this.

    - Akila De Alwis -

    ReplyDelete
    Replies
    1. Hi Akila,

      Thanks for your response.
      Do Keep in Touch.

      Delete
  7. Very good article on ViewModel.

    -Visharad Dhavle-

    ReplyDelete
    Replies
    1. Hi Visharad,

      Thanks for your appreciation.
      Do Keep in Touch.

      Delete
  8. likes this.

    -shyam chawda-

    ReplyDelete
    Replies
    1. Hi shyam,

      Thanks for your response.
      Do Keep in Touch.

      Delete
  9. like this.

    -Andrea Calvario-

    ReplyDelete
    Replies
    1. Hi Andrea,

      Thanks for your response.
      Do Keep in Touch.

      Delete
  10. Nice. Congratulations!

    ReplyDelete
    Replies
    1. Hi ,

      Thanks for your response.
      Do Keep in Touch.

      Delete
  11. like this.

    -Esta Tsutsa-

    ReplyDelete
    Replies
    1. Hi Esta,

      Thanks for your response.
      Do Keep in Touch.

      Delete
  12. good article sampath

    -Buddhi Weragoda-

    ReplyDelete
    Replies
    1. Hi Buddhi,

      Thanks for your appreciation.
      Do Keep in Touch.

      Delete
  13. Good stuff. Very clean explanation.

    -Luís Barbosa-

    ReplyDelete
    Replies
    1. Hi Luís,

      Thanks for your feedback.
      Do Keep in Touch.

      Delete
  14. Clear, Short and direct to the issue.

    Great!!

    -Emilio Plaza García-

    ReplyDelete
    Replies
    1. Hi Emilio,

      Thanks for your appreciation.
      Do Keep in Touch.

      Delete
  15. like this.

    -Kalpani Hettige-

    ReplyDelete
    Replies
    1. Hi Kalpani,

      Thanks for your feedback.
      Do Keep in Touch.

      Delete
  16. like this.

    -Maria Manenti-

    ReplyDelete
    Replies
    1. Hi Maria,

      Thanks for your response.
      Do Keep in Touch.

      Delete
  17. Hi,

    Nice article.
    In my current project also we used view models. which is more useful when we want to bind more than one model in our view means..

    I am having some queries related to this article please clarify.

    1. what is Html.BeginAbsoluteRouteForm? instead of using this we can use Html.Beginform ?
    2. @Html.CompleteEditorFor is this your custom html extension method right? If yes means please share the code it will give more clarity to understand the purpose of this control.
    3.
    //when validation failed return viewmodel back to UI (View)
    return View(productViewModel);
    In post method directly you are returning the model what you are getting while doing like this we will get exception in this line in view page
    @Html.DropDownListFor(m => m.SelectedValue,new SelectList(Model.ProductCategories, "Id","CategoryName"),"-Please select a category -")

    Because Model.ProductCategories will vanished. Before returning the model values again we have to re populate the items otherwise we have to use ViewBag.

    Please excuse if above mentioned informations anything wrong means.

    Thanks in advance.

    Regards,
    Mukesh Selvaraj

    ReplyDelete
    Replies
    1. Hi Mukesh,

      Thanks for your feedback.

      A 1 :

      Yes. Actually @Html.BeginAbsoluteRouteForm is a html helper extension method which we have written. It’s not coming with default html helper methods of MVC.
      You can find @Html.BeginRouteForm() instead of that which is coming with MVC.
      If you need to look sample of above extension method. It’s like below.

      public static MvcForm BeginAbsoluteRouteForm(this HtmlHelper htmlHelper, string routeName, object routeValues, FormMethod method, object htmlAttributes)
      {
      return htmlHelper.BeginAbsoluteRouteForm(routeName, new RouteValueDictionary(routeValues), method,
      new RouteValueDictionary(htmlAttributes));

      }


      A 2:

      Yes. Your right. It’s an extension method for custom template. Sample code as below.

      public static MvcHtmlString CompleteEditorFor(this HtmlHelper html, Expression> expression, string labelOverride = null, object[] labelParameters = null)

      {
      var components = new MvcHtmlString[] {
      html.LabelFor(expression, labelParameters, labelOverride),
      html.EditorFor(expression),
      html.ValidationMessageFor(expression)
      };

      var outputs = components.Where(item => item != null).Select(item => item.ToString()).ToArray();
      return MvcHtmlString.Create(string.Join("", outputs));

      }

      A 3 : Yes your right.I have missed some code there and updated it on original article.Please check that.

      One Important thing I have to mentioned here.That is never use ViewBag or ViewData with your View.It's really ugly and difficult to maintain.Always try to use ViewModel as best practices(even for simple scenarios).

      Good luck.

      Delete
    2. Hi Sampath,

      Thanks for your reply. Please see my comments below.

      A1: Will check and let you know.
      A2: Will check and let you know.
      A3: I am having little bit deviation here.
      In my project i have one page it contains more than 20 drop downs.
      For that i used ViewBags only. I agree with you it is some what goosy, It will slow down view page performance. But I think we can't fully avoid this ViewBag.
      Do you have any good article about pros and cons and Best practices about ViewBag.

      Thanks in advance.

      Regards,
      Mukesh Selvaraj

      Delete
    3. Hi Mukesh,

      A3 :

      Yes you can fully avoid ViewBag and you must to.

      These are some reasons for that

      # The problem comes in from the fact that ViewBag is a dynamic object

      # There are no compile time type checks

      # If you misspell something you won't be notified from the compiler

      Please check below link for more details

      http://completedevelopment.blogspot.com/2011/12/stop-using-viewbag-in-most-places.html

      For Your performance issue:

      You can use output cache or data cache method for boost your page performance heavily.

      Delete
    4. Hello Sampath,

      Thanks for your reply. Surely I will taken care in my upcoming development tasks.

      Delete
  18. Replies
    1. Hi eshan,

      Thanks for your feedback.
      Do Keep in Touch.

      Delete
  19. Great post...!!!

    But I have some problems with view models.

    Can we move the logic inside the controller to the view model? (so that we can keep the controller thin; model fat and view dumb)

    Ex: Let's add the logic inside the constructor of the ProductViewModel

    public class ProductViewModel
    {
    public ProductViewModel()
    {
    this.ProductCategories = Repository.GetAllProductCategories();
    }

    [DisplayName("Product Category")]
    public virtual ICollection ProductCategories { get; set; }

    //Add other properties
    }

    Now the controller

    [HttpGet]
    public ActionResult AddProduct()
    {
    var productViewModel = new ProductViewModel();
    return View("AddProduct", productViewModel);
    }

    OK. Let's concern how to handle the POST action

    [HttpPost]
    public ActionResult AddProduct(ProductViewModel productViewModel)
    {
    if (ModelState.IsValid)
    {
    productViewModel.Add();
    return RedirectToAction("AddProduct");
    }

    return View(productViewModel);
    }

    Now let's implement the Add method in ProductViewModel

    public class ProductViewModel
    {
    public void Add()
    {
    this.ProductCategory = Repository.GetProductCategory(this.SelectedValue);
    Repository.AddProduct(this);
    }
    }

    ReplyDelete
    Replies
    1. Hi Haritha,

      Thanks for your feedback.

      About Your question:

      You're totally wrong here when we're considering the MVC architectural pattern (separation of concerns).You must never call repository methods inside the ViewModel or Model.That thing must handle inside the Controller.

      ViewModel only interacts with Models and View.Not with Repository.

      If you need to slim the controller,then you can have number of ways to do that.Some of them are as below.

      1.You can remove business related logic into separate service layer.

      2.You can reduce lots of mapping related code inside the controller by using "ValueInjecter Mapper".
      Check here for more info : http://sampathloku.blogspot.com/2012/11/how-to-use-valueinjecter-with-aspnet.html

      I hope you got the point which I told.If you're still having issues about this I would like to here it from you.

      Delete
  20. Great article, finally a complete example. However, I have a newbie question that I'm hoping you can clarify that has nothing to do with View Models. How do these work:

    GetProductCategory...
    GetAllProductCategories()

    It's like you're calling something that doesn't exist (in the code) at least not in your example. Or does it? Microsoft magic? Can you just add "Get" and "GetAll" to the front like that to retrieve the ProductCategory and ProductCategories? Does it only work with Repository(ies)? Do you have a link maybe outlining the details of that? Hopefully this makes sense what I'm asking and I appreciate any help. I tried googling it with no luck. Thanks!

    ReplyDelete
    Replies
    1. Hi sumnone,

      Yes.You're right.Here I have used repositories for call above methods.Those are specific methods for my App.I didn't put those repository methods on my code above.B'cos my idea was just explain how to use ViewModel with MVC.But anyway for your reference I have put those methods are as below.If you need more help Plz let me know.

      --- GetProductCategory() ---

      //for get product category
      public ProductCategory GetProductCategory(int categoryId)
      {
      return (from productCategory in Catalog.ProductCategories
      where (productCategory.Id == categoryId)
      select productCategory).FirstOrDefault();
      }

      ---GetAllProductCategories()---

      //for get all product categories
      public List GetAllProductCategories()
      {
      return (from productCategory in Catalog.ProductCategories
      select productCategory)
      .OrderBy(p => p.CategoryName)
      .ToList();
      }

      Delete
    2. Excellent, I'm at the stage right now where if I don't see every piece of the puzzle, I'm left wondering. Anyway, I thought I might be missing out on a cool trick or something, but it makes perfect sense now. Thanks so much for your reply and as well, the article. Regards.

      Delete
  21. hi i can update data from database using Mvc,
    This is my insert update code

    At the time of inserting insert data successfully but at the time of Update not updateing the data Please See my code below

    [HttpPost]

    public ActionResult Create(HttpPostedFileBase imageFile, Actor model, string cmd)
    {
    try
    {
    if (imageFile != null && imageFile.ContentLength > 0)
    {
    var fileName = Path.GetFileName(imageFile.FileName);
    if (cmd == "Create")
    {
    model.Image = fileName;
    db.Actors.Add(model);
    db.SaveChanges();
    }
    else
    {
    var actor = db.Actors.Where(m => m.ActorID == model.ActorID).FirstOrDefault();
    if (actor != null)
    {
    actor.Image = fileName;
    db.SaveChanges();
    }
    }

    var path = Path.Combine(Server.MapPath("~/Content/Actors/"), model.ActorID.ToString());
    if (!Directory.Exists(path))
    Directory.CreateDirectory(path);
    imageFile.SaveAs(path + "/" + fileName);
    }
    }
    catch { }

    return RedirectToAction("Index");
    }

    UPDATE:


    [HttpGet]
    public ActionResult Edit(int id)
    {
    var actor = db.Actors.Where(m => m.ActorID == id).FirstOrDefault();
    ViewBag.IsUpdate = true;
    return PartialView("_Actor", actor);
    }

    [HttpPost]
    public ActionResult Edit(HttpPostedFileBase imageFile, Actor model, string cmd)
    {
    if(ModelState.IsValid)
    {
    try
    {
    if (imageFile != null && imageFile.ContentLength > 0)
    {
    var fileName = Path.GetFileName(imageFile.FileName);
    if (cmd == "Update")
    {
    model.Image = fileName;
    db.Actors.Add(model);
    db.SaveChanges();
    }
    else
    {
    var actor = db.Actors.Where(m => m.ActorID == model.ActorID).FirstOrDefault();
    if (actor != null)
    {
    actor.Image = fileName;
    db.SaveChanges();
    }
    }

    var path = Path.Combine(Server.MapPath("~/Content/Actors/"), model.ActorID.ToString());
    if (!Directory.Exists(path))
    Directory.CreateDirectory(path);
    imageFile.SaveAs(path + "/" + fileName);
    }
    }
    }
    catch { }
    return RedirectToAction("Index");
    }

    ReplyDelete
    Replies
    1. Hi ANIL,

      Your UPDATE code is wrong.

      Wrong Code :

      if (cmd == "Update")
      {
      model.Image = fileName;
      db.Actors.Add(model);
      db.SaveChanges();
      }

      Correct Code :

      if (cmd == "Update")
      {
      model.Image = fileName;
      db.SaveChanges();
      }

      Check this Article : http://www.integralwebsolutions.co.za/Blog/EntryId/895/Entity-Framework-5-CRUD-Operations.aspx

      If you would like you can join with us on linkedin MVC 4 Community.Check this :http://www.linkedin.com/groups?home=&gid=5019062&trk=anet_ug_hm

      I hope this will help to you.

      Delete
  22. thanks for replying,
    modefying your code also not working,
    Please correct my below code
    I am new to mvc
    [HttpPost]
    public ActionResult Edit(HttpPostedFileBase imageFile, Actor model, string cmd)
    {
    if (ModelState.IsValid)
    {
    try
    {
    if (imageFile != null && imageFile.ContentLength > 0)
    {
    var fileName = Path.GetFileName(imageFile.FileName);
    if (cmd == "Update")
    {
    model.Image = fileName;
    db.SaveChanges();
    }
    else
    {
    var actor = db.Actors.Where(m => m.ActorID == model.ActorID).FirstOrDefault();
    if (actor != null)
    {
    actor.Name = model.Name;
    actor.Description = model.Description;

    actor.Image = fileName;
    db.SaveChanges();
    }
    }

    var path = Path.Combine(Server.MapPath("~/Content/Actors/"), model.ActorID.ToString());
    if (!Directory.Exists(path))
    Directory.CreateDirectory(path);
    imageFile.SaveAs(path + "/" + fileName);
    }
    }

    catch { }
    }
    return RedirectToAction("Index");
    }

    ReplyDelete
    Replies
    1. Hi ANIL,

      if (cmd == "Update")
      {
      model.Image = fileName;
      db.SaveChanges();
      }

      Try below scenarios :

      1. put a brake point inside the above method and check whether is it fire

      2. If so then remove "model.Image = fileName;" line and put "model.Description="ANIL";" and then check whether your db gets updated.

      3. If db updated then your problem is with image file

      check that.

      Delete
  23. Thank you,
    model.Description="ANIL";" Not udated in database,
    I am putting breake point Edit not fired At the update also fired "Create Control" is fired

    ReplyDelete
    Replies
    1. Hi ANIL,

      I am not clear what you're telling.Put more information about your findings.

      When you click Update button, isn't come (or fire) "public ActionResult Edit(HttpPostedFileBase imageFile, Actor model, string cmd)" post Action method ? If so then your problem may be with routing ? You have to put your forms html code with related to this for check whether is there any issue. Plz provide better explanation about your findings.

      Delete
  24. Thanks for the post. I have been searching for this.....

    ReplyDelete
    Replies
    1. Hi Marvin,

      Thanks, I’m glad you enjoyed it :)

      Delete
  25. one user post a detail information in a asp.net mvc4...
    How to make secure this form ...other user cannot see,edit and delete the post the details of frst user

    ReplyDelete
    Replies
    1. Hi Santosh,

      If you use ASP.net Membership provider for user management then according to the "User Role" of the user where you can enable or disable the Buttons which can use for edit or delete.

      http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-7

      Delete
  26. Thanks for your great post.

    I have problem with drodownlist
    In Create.cshtml file how can i get category using dropdownlistfor
    Like this:
    @Html.DropDownListFor(model => model.SelectedValue , new SelectList(Model.ProductCategories , "Value", "Text"))

    or this:
    @Html.DropDownListFor(model => model.ProductCategory, new SelectList(Model.ProductCategories , "Value", "Text"))

    ReplyDelete
    Replies
    1. Hi Enes,

      You're warmly welcome.

      About your question : It depends the way you declare your VM. So if you follow the way which I showed above,you can use it as below (with default value).

      @Html.DropDownListFor(m => m.SelectedValue,new SelectList(Model.ProductCategories, "Id",
      "CategoryName"),"-Please select a category -")

      If you need more information,Please let me know.

      Delete
    2. I'm grateful for your help. thanks

      Delete
  27. Please explain this given in Controller..
    Repository.GetAllProductCategories(); // where that came

    ReplyDelete
    Replies
    1. Hi Rahul,

      Those are repository methods which I used for retrieve data.I have updated my post above for those details under 'Repository Methods'.Plz check that.

      Delete
  28. Great article,
    I do have question on the Model. If I am applying this ViewModel and use entity framework.
    1. Should the product class has the ProductCategoryId?
    2. In the product view model, can I use "public Product Product {get;set;} " instead of individual fields?
    Thanks

    ReplyDelete
    Replies
    1. Hi Andy,

      Thanks :)

      A 1: It depends on according to the table structure of your app.In my case it has 1:M relationship with the Product and ProductCategory tables.So I maintained the ProductCategory as a Traversal property on above example.

      A 2: Yes you can.But the problem is then you unable to validate Product fields by using Field validate attributes (such as Required).B'cos the ViewModel is the best place to do those kind of Field validations.

      Delete
  29. Replies
    1. Hi Thiru,

      Thanks, I’m glad you enjoyed it! :)

      Delete
  30. Nice post. When you return RedirectToAction, it goes to get method where it creates a new viewmodel object. What if I want to use attributes/properties set to Viewmodel in post method and pass that viewmodel to get method?
    I mean, If I say [HttpGet] public ActionResult Index(XYZViewmodel xyzViewModel) { .... } and
    [HttpPost] public ActionResult Index(XYZViewmodel xyzViewModel) { xyzViewModel.property1 = someValue; return RedirectToAction("Index", xyzViewModel); }
    Will I get the same property coming back to get method? I tried doing in that way, but the property contents have been changed.
    In the above example, I set property1 to someValue in post method. When I redirect to get method, the property has been changed to some other value other than someValue. Can you please let me know the solution of my problem. Sorry if I am not clear.

    ReplyDelete
    Replies
    1. Hi Sanksk,

      Thanks. :)

      Answer For Your Question :

      Hence you're redirecting to the Action method,You can use "TempData" with it.Please read this article for more info. http://sampathloku.blogspot.com/2012/09/how-to-use-aspnet-mvc-tempdata-properly.html

      Delete
  31. This is really nice. Thanks for sharing this article
    Dot net training Chennai

    ReplyDelete
    Replies
    1. Hi John,

      Thanks, I’m glad you enjoyed it ! :)

      Delete
  32. Hi I have a problem with DropDownListFor on the Edit view.

    Basically I'm using a partial view which contains my form and in my Edit and Create view I call this partial view.

    I have around 5 similiar DropdownlistFor and these work well on create action but in edit doesn't, mainly i'm not getting (unable) to set the selected value.

    In my Edit Action (GET), I fill my property ViewModel if the true object has the property filled.

    if(icb.BAOfficer != null)
    editICB.BAOfficer = icb.BAOfficer;


    List staffs = _fireService.GetAllStaffs().ToList();
    staffs.Insert(0, new Staff { StaffId = -1, Name = "" });
    editICB.BAOfficers = staffs;

    return View(editICB);
    This is how I'm filling my drop down and how I'm trying to set the selected value.

    @Html.DropDownListFor(model => model.BAOfficerSelected, new SelectList(Model.BAOfficers, "StaffId", "Name", (Model.BAOfficer!= null ? Model.BAOfficer.StaffId:-1)), new { @class = "rounded indent" })
    @Html.ValidationMessageFor(model => model.BAOfficer.StaffId)

    ReplyDelete
  33. Very useful article!
    Thank you and God bless!

    ReplyDelete
    Replies
    1. Hi Rommel,

      Thanks, I’m glad you found it useful ! :)

      Delete
  34. Thanks for sharing this useful information..Its really very informative.

    Dot Net Course in Chennai

    ReplyDelete
  35. Really impressive..for your information...we are providing Dotnet online training

    ReplyDelete
  36. Really have good to know this information .Thanks for sharing.Keep posting...


    .Net training in Lucknow

    ReplyDelete

Thanks for your Feedback.