MattR
MattR

Reputation: 641

MVC4 Validate Item Selected In DropDownList

I have a page to create objects, and in this I have a DropDownList. If I select an item from the list my page will save correctly, however if I don't select an item it looks like it fails on a postback as the objects will be null.

What I want is to try and validate whether the user has selected an item (default is "Please Select...").

I have code that will check and see in the controller if the item is null, but it's how do I then display a message? Keeping all other details if they exist.

public ActionResult Create(int objectId = 0)
{
var resultModel = new MyObjectModel();
resultModel.AllObjects = new SelectList(_system.GetAllObjects(objectId)); 
// GetAllObjects juts returns a list of items for the drop down.
return View(resultModel);
}

[HttpPost]
public ActionResult Create(int? objectId, FormCollection collection)
{
try
{
int objectIdNotNull = 0;
if (objectId > 1)
{
objectIdNotNull = (int) objectId;
}
string objectName = collection["Name"];
int objectTypeSelectedResult = 1;
int.TryParse(collection["dllList"], out objectTypeSelectedResult);
if (!Convert.ToBoolean(objectTypeSelectedResult))
{
// So here I have discovered nothing has been selected, and I want to alert the user
    return RedirectToAction("Create",
        new {ObjectId = objectIdNotNull, error = "Please select an Object Type"});
}
....

return RedirectToAction(...)

}
catch
{
return View();
}
}

The above code just goes to the Create page but doesn't display an error. In my View for Create I have the following line which I assumed would display any errors: @ViewData["error"]

Additional code Model:

using System.Collections.Generic;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;

namespace MyNameSpace
{
public class MyObjectModel
{
[Required(ErrorMessage = "Please select an Object Type")]
public SelectList AllObjects { get; set; }  // I populate the drop down with this list
}
}

View:

@model MyNameSpace.MyObjectModel

@{
ViewBag.Title = "Create";
}

<h2>Create </h2>

<p class="text-error">@ViewData["Message"]</p>

<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.MyObject.Name)
</div>
<div class="editor-field">
@Html.TextBoxFor(model=>model.MyObjectType.Name, new {style="width: 750px"})
@Html.ValidationMessageFor(model => model.MyObjectType.Name)
</div>

<div>
<label for="ddlList">Choose Type</label>
@if (@Model != null)
{  
@Html.DropDownList("ddlList", Model.AllObjects, "Please Select...")
@Html.ValidationMessageFor(model => model.AllObjects, "An object must be selected", new { @class = "redText"})
}
</div>

<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}

Upvotes: 0

Views: 7894

Answers (1)

meda
meda

Reputation: 45490

You are validating the SelectList which is wrong

[Required(ErrorMessage = "An object must be selected")]
public SelectList AllObjects { get; set; }

Your Model should be

[Required(ErrorMessage = "Please select an Object Type")]
public int ObjectId { get; set; }
public string ObjectName { get; set; }

Your Controller(no need for form collection thats the whole point of MVC)

public ActionResult Create(int Id = 0)
{
    MyObjectModel resultModel = new MyObjectModel();

    var ObjectResultList = _system.GetAllObjects(Id);
    var ObjectSelectList = new SelectList(ObjectResultList, "id", "Name");
    ViewBag.ObjectList = ObjectSelectList;

    return View(resultModel);
}

Your Post controller:

[HttpPost]
public ActionResult Create(MyObjectModel o)
{
    try
    {
            if (ModelState.IsValid)
            {
                            //It's valid , your code here!

                return RedirectToAction("ObjectCreated", new { id = o.objectId });
            }
            else
            {
                var errors = ModelState
                    .Where(x => x.Value.Errors.Count > 0)
                    .Select(x => new { x.Key, x.Value.Errors })
                    .ToArray();
            }
        }
    }
    catch (Exception ex)
    {
        Response.Write(ex.InnerException.Message);
    }
    //If we get here it means the model is not valid, We're in trouble
    //then redisplay the view repopulate the dropdown
    var ObjectResultList = _system.GetAllObjects(objectId);
    var ObjectSelectList = new SelectList(ObjectResultList, "id", "value");
    ViewBag.ObjectList = ObjectSelectList;


    return View(o);
}

Your View should be strongly Typed

<div class="editor-label">
    @Html.LabelFor(model => model.ObjectId)
</div>
<div class="editor-field">
    @Html.DropDownListFor(model => model.ObjectId,
       (IEnumerable<SelectListItem>)ViewBag.ObjectList, "-- Select One Object --")
    @Html.ValidationMessageFor(model => model.ObjectId)
</div>

Upvotes: 3

Related Questions