I’m hoping someone can help me with the below issue, which is likely very basic but I’m still learning MVC 3.0 (and coding in general).
I’m getting a Value cannot be null. Parameter name: String error within my controller when attempting to load data into my city DropDownList based on the value in the state DropDownList.
I’m hoping I’m just missing something basic. The int id = int.Parse(state_id) line within the JsonResult getCity call is throwing the error.
Here is my Controller:
public ActionResult Create()
{
ViewBag.sessionName = HttpContext.Session["SPCompanyName"].ToString();
var compID = HttpContext.Session["SPCompanyAccountID"].ToString();
ViewBag.companyID = compID;
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem { Text = "Select State", Value = "Default State" });
var states = (from c in simpleDB.simpleState select c).ToArray();
for (int i = 0; i < states.Length; i++)
{
list.Add(new SelectListItem { Text = states[i].stateFull, Value = states[i].Id.ToString() });
}
ViewData["states"] = list;//data for DropdownList State
List<SelectListItem> list1 = new List<SelectListItem>();
list1.Add(new SelectListItem { Text = "Select City", Value = "Default City" });
ViewData["cities"] = list1;//data for Dropdownlist City
return View();
}
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult getCity(string state_id)
{
int id = int.Parse(state_id);
var myData = (from m in simpleDB.simpleCity where m.simpleStateId == id select new { text = m.cityFull, value = m.Id });
return this.Json(myData, JsonRequestBehavior.AllowGet);
}
Here is the full code for my View:
@using (Html.BeginForm(FormMethod.Post))
{
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#StateId').change(function () {
var state_id = $(this).val(); //get State ID when select value change
$.getJSON("/SPServiceLocation/getCity/" + state_id, {},
function (myData) {
var options = '';
for (var i = 0; i < myData.length; i++) {
options += '<option value="' + myData[i].value + '">' + myData[i].text + '</option>';
}
$("#CityId").html();
$("#CityId").html(options);
});
});
});
</script>
@Html.ValidationSummary(true)
<fieldset>
<legend>Step 4: Service Areas</legend>
@Html.HiddenFor(model => model.SPCompanyAccountID, new { @Value = ViewBag.companyID })
<div class="editor-label">
@Html.LabelFor(model => model.state)
</div>
<div class="editor-field">
@Html.DropDownList("state", (IEnumerable<SelectListItem>)ViewData["states"], new { id = "StateId", @class = "chzn-select" })
@Html.ValidationMessageFor(model => model.state)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.city)
</div>
<div class="editor-field" id="SP_SelectCity">
@Html.DropDownList("city", (IEnumerable<SelectListItem>)ViewData["cities"], new { id = "CityId", @class = "chzn-select" })
@Html.ValidationMessageFor(model => model.city)
</div>
<p>
<input type="submit" value="Submit" />
</p>
</fieldset>
I’ve looked at this Controller and View code for a few hours now, and just don’t know what the issue might be. Thank you for your assistance.
I don’t know where to start. Looking at this code I really I don’t where to start. I could write libraries of books about how bad this code is. But for starters:
should be:
This should probably fix your error. Or maybe not. Who knows. Try.
Let me just enumerate a couple of things that strike me directly when I look at your code (and I just did a single glance at it):
@using (Html.BeginForm(FormMethod.Post))– Ermmm what did you mean with this? There’s no such overload. You are invoking this overload:public static MvcForm BeginForm(this HtmlHelper htmlHelper, object routeValues);. Probably you meant@using (Html.BeginForm())?return View();and yet seemingly using a strongly typed viewViewBag.XXXinstead of using a view modellist.Add(new SelectListItem { Text = "Select State", Value = "Default State" });instead of using the proper overload of the DropDownListFor helper allowing you to add a default value as third argument$.getJSON("/SPServiceLocation/getCity/" + state_idinstead of using Url helpersoptions += '<option value="' + myData[i].value + '">' + myData[i].text + '</option>';@Html.HiddenFor(model => model.SPCompanyAccountID, new { @Value = ViewBag.companyID })doesn’t do what you think it does. You cannot override the value attribute. This simply generates 2 value attributes on your hidden field: one with capitalVand one with lowercasev.$("#CityId").html();model => model.state. In .NET standard conventions dictate that property names should start with a capital letterYeah, basically I would start over from scratch. Here’s an alternative approach that I would recommend, using view models: https://stackoverflow.com/a/4459084/29407