Solved

MVC client-side validation With multiple models

Posted on 2014-02-10
4
140 Views
Last Modified: 2016-06-20
I have three models: VehicleType, VehicleModel, and VehicleManufacturer.

Both VehicleType and VehicleManufacturer point to VehicleModel in the model, like so:

namespace Dealership.Models
{
    public class VehicleModel
    {
        [Key]
        public int ModelId { get; set; }
        public int TypeId { get; set; }
        public int ManufacturerId { get; set; }
        public string ModelName { get; set; }

       
        public VehicleType VehicleType { get; set; }
        public VehicleManufacturer Manufacturer { get; set; }

    }
}

Open in new window


From there, VehicleModel points to the InventoryModel:

public class Inventory
    {
        [Key]
        public int InventoryId { get; set; }
        public int Price { get; set; }
        public int Mileage { get; set; }
        public int Year { get; set; }


        public int ModelId { get; set; }
        public VehicleModel VehicleModel { get; set; }
    }

Open in new window


My problem is when I try to get client-side validation working on all three dropdownlists (VehicleType, VehicleManufacturer, VehicleModel), it only works with VehicleModel. I believe this is because in the View, I am calling the Inventory Model(@model IEnumerable<Dealership.Models.Inventory>), and VehicleModel has a navigation property pointing to the Inventory model. But VehicleManufacturer and VehicleType point to the VehicleModel, so I don't see why all three models can't be validated.
What needs to be done to validate these two dropdownlists using these models?

Here is my controller (fyi)
// GET: /Inventory/Create
        public ActionResult Create()
        {
            ViewBag.TypeId = new SelectList(db.Types, "TypeId", "TypeName"); //(Object List, Value Field (usually Id), Column)
            ViewBag.ModelId = new SelectList(db.Models, "ModelId", "ModelName"); //(Object List, Value Field (usually Id), Column)
            ViewBag.ManufacturerId = new SelectList(db.Manufacturers, "ManufacturerId", "ManufacturerName"); //(Object List, Value Field (usually Id), Column)

            return View();
        }

        // POST: /Inventory/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Inventory inventory, VehicleManufacturer VehicleManufacturer, VehicleType VehicleType)
        {
            if (ModelState.IsValid)
            {
                db.Inventorys.Add(inventory);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewBag.TypeId = new SelectList(db.Types, "TypeId", "TypeName");
            ViewBag.ModelId = new SelectList(db.Models, "ModelId", "ModelName");
            ViewBag.ManufacturerId = new SelectList(db.Manufacturers, "ManufacturerId", "ManufacturerName");

            return View(inventory);
        }

Open in new window



And my View:



<div class="editor-label">
            @Html.LabelFor(model => model.VehicleModel.TypeId, "Some name for column")
        </div>
        <div class="editor-field">
            @Html.DropDownList("TypeId", String.Empty)

            @Html.ValidationMessageFor(model => model.VehicleModel.TypeId)
        </div>


        <div class="editor-label">
            @Html.LabelFor(model => model.ModelId, "Some name for column")
        </div>
        <div class="editor-field">
            @Html.DropDownList("ModelId", String.Empty)
            @Html.ValidationMessageFor(model => model.ModelId)
        </div>



        <div class="editor-label">
            @Html.LabelFor(model => model.VehicleModel.ManufacturerId, "Some name for column")
        </div>
        <div class="editor-field">
            @Html.DropDownList("ManufacturerId", String.Empty)
            @Html.ValidationMessageFor(model => model.VehicleModel.ManufacturerId)
        </div>

Open in new window



Thanks in advance!
0
Comment
Question by:DonHoddinott2
  • 2
4 Comments
 
LVL 11

Expert Comment

by:Mihai Stancescu
ID: 39849352
Hi,

Try decorating the properties with [Required] attribute. You can also implement in your model the interface "IValidatableObject" to provice custom validation.


Regards,
Mishu
0
 

Author Comment

by:DonHoddinott2
ID: 39856777
Hi Mishu,

I appreciate your answer, but I don't it is necessary to use IValidateObject in this instance. I want to understand why it isn't working, just as much as I want it resolved. Adding the [Required] attribute didn't work.
0
 
LVL 11

Accepted Solution

by:
Mihai Stancescu earned 500 total points
ID: 39858414
Hi again,

As I see it you have two options for achieving this:
1. In your form add or modify this line @Html.ValidationSummary(false) and call the method using false as parameter.
2. In your view change the dropdown definition from @Html.DropDownList("ModelId", String.Empty) to  @Html.DropDownListFor(model=>model.VehicleModel.TypeId,  (SelectList)ViewBag.ModelId,"-please select item-").

The first option will display all the validation messages where that line is placed.
The second option will add the in-line client side validation that you need.

Hope this helps,
Mishu
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

740 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question