Solved

MVC client-side validation With multiple models

Posted on 2014-02-10
4
124 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Latency in .net app using DB in .net 21 34
Error on Add method 1 38
Split in Javascript 5 31
Javascript and Jquery not firing 9 42
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

867 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now