20

Inside my controller's action I have the following code:

public ActionResult GridAction(string id)
{
    if (String.IsNullOrEmpty(id)) 
    {
        // add errors to the errors collection and then return the view saying that you cannot select the dropdownlist value with the "Please Select" option
    }

    return View(); 
}

UPDATE:

if (String.IsNullOrEmpty(id))
{
    // add error 
    ModelState.AddModelError("GridActionDropDownList", "Please select an option");
    return RedirectToAction("Orders"); 
}

UPDATE 2:

Here is my updated code:

@Html.DropDownListFor(x => x.SelectedGridAction, Model.GridActions,"Please Select") 
@Html.ValidationMessageFor(x => x.SelectedGridAction)  

The Model looks like the following:

public class MyInvoicesViewModel
{

    private List<SelectListItem> _gridActions;

    public int CurrentGridAction { get; set; }

    [Required(ErrorMessage = "Please select an option")]
    public string SelectedGridAction { get; set; }

    public List<SelectListItem> GridActions
    {
        get
        {
            _gridActions = new List<SelectListItem>();
            _gridActions.Add(new SelectListItem() { Text = "Export to Excel", Value = "1" });

            return _gridActions;
        }
    }
} 

And here is my controller action:

public ActionResult GridAction(string id)
{
    if (String.IsNullOrEmpty(id))
    {
        // add error 
        ModelState.AddModelError("SelectedGridAction", "Please select an option");
        return RedirectToAction("Orders"); 
    }

    return View(); 
}

Nothing happens! I am totally lost on this one!

UPDATE 3:

I am now using the following code but still the validation is not firing:

public ActionResult GridAction(string id)
{
    var myViewModel= new MyViewModel();
    myViewModel.SelectedGridAction = id; // id is passed as null           

    if (!ModelState.IsValid)
    {
        return View("Orders");
    }

UPDATE 4:

$("#linkGridAction").click(function () {
    alert('link grid action clicked'); 

    $.get('GridAction/', { SelectedGridAction: $("#SelectedGridAction").val() }, function (result) {
        alert('success');
    });
});

And the Controller looks like the following:

// OrderViewModel has a property called SelectedGridAction. 
public ActionResult GridAction(OrderViewModel orderViewModel)
{
    return View(); 
}

UPDATE 5: Validation is not firing:

public ActionResult GridAction(OrderViewModel orderViewModel)
{
    if (!ModelState.IsValid)
    {
        return View("Orders", orderViewModel); 
    }
    return View(); 
}

3 Answers 3

60

Use ModelState.AddModelError()

ModelState.AddModelError("MyDropDownListKey", "Please Select");

and output to the view like this:

<%= Html.ValidationMessage("MyDropDownListKey") %>
Sign up to request clarification or add additional context in comments.

3 Comments

+1 for direct & short answer "Use ModelState.AddModelError()".
Where do I get the Key from? I ahve the following: <span class="field"> @Html.EditorFor(model => model.ClientID, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ClientID,"", new { @class = "text-danger" }) </span> what would be the key?
If you know what property you're working with you can rely on DataAnnotations or try adding an error for "ClientID"
7

You could use a view model:

public class MyViewModel
{
    [Required]
    public string Id { get; set; }
}

and then:

public ActionResult GridAction(MyViewModel model)
{
    if (ModelState.IsValid)
    {
        // the model is valid, the user has selected an id => use it
        return RedirectToAction("Success");
    }
    return View();
}

UPDATE:

After the hundreds of comments on my answer I feel in the necessity to provide a full working example:

As usual start with a view model:

public class MyViewModel
{
    [Required]
    public string SelectedItemId { get; set; }

    public IEnumerable<SelectListItem> Items 
    {
        get
        {
            // Dummy data
            return new SelectList(Enumerable.Range(1, 10)
                .Select(i => new SelectListItem 
                {
                    Value = i.ToString(),
                    Text = "item " + i 
                }), 
            "Value", "Text");
        }
    }
}

Then a controller:

public class HomeController: Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            // The user didn't select any value => redisplay the form
            return View(model);
        }
        // TODO: do something with model.SelectedItemId
        return RedirectToAction("Success");
    }
}

and finally the view:

<% using (Html.BeginForm()) { %>
    <%= Html.DropDownListFor(
        x => x.SelectedItemId, 
        Model.Items, 
        "-- Select Item --"
    ) %>
    <%= Html.ValidationMessageFor(x => x.SelectedItemId) %>
    <input type="submit" value="OK" />
<% } %>

29 Comments

Unfortunately, there is a value when the user selects the "Please Select" option.
@johndoe, there shouldn't be. If you use the following helper method: <%= Html.DropDownListFor(x => x.Id, Model.Items, "-- please select --") %> to generate your dropdown no value will be sent and validation will automatically work. Also it makes more sense to send empty string when the user hasn't selected anything rather than some dummy value.
I should also add that the page is not being submitted (no submit button) but an action is invoked through a link and that is why the validation is not being fired!
@johndoe, from validation standpoint it doesn't matter how the request is sent. The important thing is to send an id parameter along the request. If this parameter is empty validation will fail => it is as if the user hasn't selected any value in the dropdown.
@johndoe, didn't you read my answer? I suggested you passing the model as action argument and not just id. So try: public ActionResult GridAction(MyInvoicesViewModel model) and inside this action you don't need to manually check whether the id is null or empty. This will be automatically handled by the model binder because your model has the SelectedGridAction property decorated with the Required attribute. Also in case of error you should not redirect, you should return the same view if you want validation errors to be shown: if (!ModelState.IsValid) return View();
|
0

Regarding your update #3, I suspect thats because you are actually assigning the value, its just an empty string (Required is checking for null).

You want to do have this:

[Required(AllowEmptyStrings = false)]

Your best bet though would be to perform custom validation (you will likely want to verify the key is in the list, etc)

Edit: fixed typo in the code - forgot closing ")"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.