Reputation: 449
In an ASP.NET MVC 5 web site, I am populating a drop down in a view and getting the value back in the POST action. However, ModelState.IsValid is always false. In investigating why, I found that there is an error for the IEnumerable<SelectListItem>
property, which contains the data for the drop down.
Here is the exception from the ModelState for the IEnumerable<SelectListItem>
property:
The parameter conversion from type 'System.String' to type 'System.Web.Mvc.SelectListItem' failed because no type converter can convert between these types.
From what I've read, it looks like I am using the view model correctly and setting up the drop down correctly.
This is inconvenient because ModelState.IsValid is checked elsewhere for error handling, but in the POST action AvailableStates is irrelevant. Any ideas as to why the IEnumerable<SelectListItem>
property always has this error?
I made a simple web site that replicates the issue.
View Model
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace SandboxAspNet.Models
{
public class HomeViewModel
{
[Required(ErrorMessage = "Please select a state.")]
[Display(Name = "State")]
public string SelectedState { get; set; }
public IEnumerable<SelectListItem> AvailableStates { get; set; }
}
}
Controller
using System.Collections.Generic;
using System.Web.Mvc;
using SandboxAspNet.Models;
namespace SandboxAspNet.Controllers
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
var model = new HomeViewModel()
{
AvailableStates = GetAvailableStates()
};
return View(model);
}
[HttpPost]
public ActionResult Submit(HomeViewModel model)
{
if (!ModelState.IsValid)
{
model.AvailableStates = GetAvailableStates();
return View("Index", model);
}
return View("Success");
}
// Generate some dummy data for the drop down
private static IEnumerable<SelectListItem> GetAvailableStates()
{
return new List<SelectListItem>()
{
new SelectListItem()
{
Text = "Alabama",
Value = "AL"
},
new SelectListItem()
{
Text = "Alaska",
Value = "AK",
},
new SelectListItem()
{
Text = "Arizona",
Value = "AZ",
},
new SelectListItem()
{
Text = "Arkanasas",
Value = "AR"
}
};
}
}
}
View
@model SandboxAspNet.Models.HomeViewModel
@{
ViewBag.Title = "Home Page";
}
@using (Ajax.BeginForm("Submit", "Home", Model, null))
{
@Html.ValidationSummary()
<div>
<strong>@Html.LabelFor(model => model.SelectedState)</strong>
@Html.DropDownListFor(model => model.SelectedState, Model.AvailableStates, "--Select a State---", new { @type = "text", @style = "width:100%;", @class = "form-control" })
@Html.ValidationMessageFor(model => model.SelectedState)
</div>
<div>
<button type="submit">Submit</button>
</div>
}
Upvotes: 0
Views: 382
Reputation: 3540
Your third parameter to Ajax.BeginForm()
is wrong. That parameter is for routeValues.
public static MvcForm BeginForm(
this AjaxHelper ajaxHelper,
string actionName,
string controllerName,
object routeValues,
AjaxOptions ajaxOptions
)
You can possibly just make the third and four parameter null
if you don't need to do anything more advanced.
@using (Ajax.BeginForm("Submit", "Home", Model, null))
Upvotes: 1