I am having a problem converting a sample app that I found that works to one that fits my needs. I have not been able to figure out just what I am doing wrong. I am not even getting to the alert after returning from the JSon call in the converted app. First I will copy the model, controller, and view of the sample. And then I will copy the model, controller, and view of the converted app. I am hitting a breakpoint on the call to the Controller and it looks like the SelectList data is properly packed in the JSon object. But I must be doing something wrong. Any help understanding the problem would sure be appreciated.
---------------------------- Working Sample Model ------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace SimpleMVCJSONSample.Models
{
public class MyViewModel
{
public int? Year { get; set; }
public int? Month { get; set; }
public IEnumerable<SelectListItem> Years
{
get
{
return Enumerable.Range(2000, 12).Select(x => new SelectListItem
{
Value = x.ToString(),
Text = x.ToString()
});
}
}
}
}
-------------------------- Working Sample Controller ------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SimpleMVCJSONSample.Models;
namespace SimpleMVCJSONSample.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
public ActionResult Months(int year)
{
if (year == 2011)
{
var jsonRet1 = Json(
Enumerable.Range(1, 3).Select(x => new { value = x, text = x }),
JsonRequestBehavior.AllowGet
);
return jsonRet1;
}
var jsonRet2 = Json(
Enumerable.Range(1, 12).Select(x => new { value = x, text = x }),
JsonRequestBehavior.AllowGet
);
return jsonRet2;
}
}
}
-------------------------- Working Sample View -----------------
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
@model SimpleMVCJSONS开发者_StackOverflow中文版ample.Models.MyViewModel
@Html.DropDownListFor(
x => x.Year,
new SelectList(Model.Years, "Value", "Text"),
"-- select year --"
)
@Html.DropDownListFor(
x => x.Month,
Enumerable.Empty<SelectListItem>(),
"-- select month --"
)
<script type="text/javascript">
$('#Year').change(function () {
var selectedYear = $(this).val();
if (selectedYear != null && selectedYear != '') {
$.getJSON('@Url.Action("Months")', { year: selectedYear }, function (months) {
alert(months);
var monthsSelect = $('#Month');
monthsSelect.empty();
$.each(months, function (index, month) {
monthsSelect.append($('<option/>', {
value: month.value,
text: month.text
}));
});
});
}
});
</script>
---------------------------------END OF Working SAMPLE-----------------------
--------------------------My Converted Model ------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using ONSM.Common.Logging;
using VW40.Data.Model;
using VW40.Services;
namespace VW40.Web.Models
{
public class CompanyPeopleViewModel
{
private Log _log;
private ExceptionManager _exceptionManager;
private readonly ICompanyService _companyService;
private readonly IPersonService _personService;
public CompanyPeopleViewModel(Log log, ExceptionManager exceptionManager, ICompanyService companyService, IPersonService personService)
{
_companyService = companyService;
_personService = personService;
_log = log;
_exceptionManager = exceptionManager;
}
public int Company { get; set; }
public int Person { get; set; }
public IEnumerable<SelectListItem> CompanySelectList
{
get
{
return _companyService.GetCompanies().OrderBy(x => x.CompanyName).Select(x => new SelectListItem
{
Value = x.CompanyID.ToString(),
Text = x.CompanyName
});
}
}
}
}
--------------------------- My Converted Controller ----------------
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using ONSM.Common.Logging;
using VW40.Data.Model;
using VW40.MVC.Models;
using VW40.Services;
using VW40.Services.AccessControl;
using VW40.Web.Models;
using System.Web;
namespace VW40.MVC.Controllers
{
[Authorize(Roles = "Administrator")]
public class AccessControlController : MembershipAdministrationController_Base
{
private Log _log;
private ExceptionManager _exceptionManager;
private IAccessControlService _accessControlService;
private IPersonService _personControlService;
private ICompanyService _companyService;
public AccessControlController(
Log log,
ExceptionManager ExceptionManager,
IAccessControlService AccessControlService,
IPersonService PersonService,
ICompanyService CompanyService
)
{
_log = log;
_exceptionManager = ExceptionManager;
_accessControlService = AccessControlService;
_personControlService = PersonService;
_companyService = CompanyService;
}
public ActionResult Json_CompanyPeopleSelectList(int CompanyID)
{
var companyPersonsList = _personControlService.GetPersonsByCompanyId(CompanyID).OrderBy(x => x.Lastname + x.Firstname);
//IEnumerable<SelectListItem> myList = companyPersonsList.Select(x => new SelectListItem
// {
// Value = x.PersonID.ToString(),
// Text = x.Lastname
// }
//);
var jsonRet =
Json(
_personControlService.GetPersonsByCompanyId(CompanyID).OrderBy(x => x.Lastname + x.Firstname).Select
(x => new
{
value = x.PersonID.ToString(),
text = x.Lastname
}), JsonRequestBehavior.AllowGet);
return jsonRet;
}
--------------------------- My Converted View -----------------
@model VW40.Web.Models.CompanyPeopleViewModel
@{
Layout = "~/Views/Shared/SiteLayout.cshtml";
ViewBag.Title = "UserPermissions";
}
<h2>UserPermissions</h2>
@Html.DropDownListFor(
x => x.Company,
new SelectList(Model.CompanySelectList, "Value", "Text"),
"Select Company"
)
@Html.DropDownListFor(
x => x.Person,
Enumerable.Empty<SelectListItem>(),
"-- Select Person --"
)
<script type="text/javascript">
$('#Company').change(function () {
var selectedCompany = $(this).val();
if (selectedCompany != null && selectedCompany != '') {
$.getJSON('@Url.Action("Json_CompanyPeopleSelectList")', { CompanyID: selectedCompany }, function (listOfCompanyPeople) {
alert(listOfCompanyPeople);
var personSelect = $('#Person');
personSelect.empty();
$.each(listOfCompanyPeople, function (index, person) {
personSelect.append($('<option/>', {
value: person.value,
text: person.text
}));
});
});
}
});
</script>
------------------------------ end of Conversion ----------------
Could you directly call your controller by entering URL in the browser and see whether it returns correct JSON data. you do not have error handler function in the getJSON so you cannot see if JSON response is not correctly returned back from the server.
There is one similar example on the http://jquery-load-json.googlecode.com/svn/trunk/categories-ajax.html. in this example first category drop-down is loaded with one call and dependent drop-down is loaded using the secondary Ajax call. If you use this example just create controller that returns people list for the company and use loadJSON to populate the sub-category drop-down with returned values.
Jovan
精彩评论