在ASP.NET Core Razor Pages的第一个下拉列表中选择了一个值时,我无法更新第二个下拉列表。
我有以下型号:
public class OfferModel
{
[BindProperty]
public CreateOfferViewModel ViewModel { get; set; }
public List<SelectListItem> ServiceTypes { get; set; }
public List<SelectListItem> ServiceSubTypes { get; set; }
private readonly IOfferAppService _offerAppService;
public OfferModel(IOfferAppService service)
{
_offerAppService = service;
}
public virtual async Task OnGetAsync()
{
var serviceTypeLookup = await _offerAppService.GetServiceTypeLookupAsync();
ServiceTypes = serviceTypeLookup.Items
.Select(x => new SelectListItem(x.Name, x.Id.ToString()))
.ToList();
var serviceSubTypeLookup = await _offerAppService.GetServiceSubTypeLookupAsync();
ServiceSubTypes = serviceSubTypeLookup.Items
.Select(x => new SelectListItem(x.Name, x.Id.ToString()))
.ToList();
}
}
和CreateOfferViewModel:
public class CreateOfferViewModel
{
[SelectItems(nameof(ServiceTypes))]
public Guid ServiceTypeId { get; set; }
[SelectItems(nameof(ServiceSubTypes))]
public Guid ServiceSubTypeId { get; set; }
}
视图:
<select asp-for="ViewModel.ServiceSubTypeId" asp-items="Model.ServiceSubTypes"></select>
<select asp-for="ViewModel.ServiceTypeId" asp-items="Model.ServiceTypes" ></select>
我尝试创建另一个类似的方法:
public virtual async Task OnGetSelectServiceTypeAsync(Guid serviceTypeId)
{
var serviceSubTypeLookup = await _offerAppService.GetServiceSubTypeLookupAsync(serviceTypeId);
ServiceSubTypes = serviceSubTypeLookup.Items
.Select(x => new SelectListItem(x.Name, x.Id.ToString()))
.ToList();
}
并在视图中添加引用以使用jQuery进行调用:
<a asp-page-handler="SelectServiceType" asp-route-id="@Model.ViewModel.ServiceTypeId">Update</a>
但是我得到了NullReferenceException。
我该怎么办?正确的方法是什么?
答案 0 :(得分:1)
但是我得到了NullReferenceException。
这是因为您使用了asp-route-id="@Model.ViewModel.ServiceTypeId"
,但没有为其设置任何值。
有两种方法可以满足您的要求。
型号:
public class CreateOfferViewModel
{
public Guid ServiceTypeId { get; set; }
public Guid ServiceSubTypeId { get; set; }
}
public class ServiceSubTypes
{
public Guid Id { get; set; }
public string Name { get; set; }
[ForeignKey("ServiceTypes")]
public Guid ServiceTypeId { get; set; }
public ServiceTypes ServiceTypes { get; set; }
}
public class ServiceTypes
{
public Guid Id { get; set; }
public string Name { get; set; }
public List<ServiceSubTypes> ServiceSubTypes { get; set; }
}
第一种方法是使用Ajax:
Index.cshtml:
@page
@model IndexModel
<select asp-for="ViewModel.ServiceTypeId" asp-items="Model.ServiceTypes"></select>
<select asp-for="ViewModel.ServiceSubTypeId"></select>
@section Scripts
{
<script>
$(function () {
$("#ViewModel_ServiceTypeId").on("change", function () {
var ServiceTypeId = $(this).val();
$("#ViewModel_ServiceSubTypeId").empty();
$.getJSON(`?handler=SelectServiceType&serviceTypeId=${ServiceTypeId}`, (data) => {
$.each(data, function (i, item) {
console.log(data);
console.log(item);
$("#ViewModel_ServiceSubTypeId").append(`<option value="${item.id}">${item.name}</option>`);
});
});
});
});
</script>
}
Index.cshtml.cs:
public class IndexModel : PageModel
{
[BindProperty]
public CreateOfferViewModel ViewModel { get; set; }
public List<SelectListItem> ServiceTypes { get; set; }
public List<SelectListItem> ServiceSubTypes { get; set; }
private readonly IOfferAppService _offerAppService;
public IndexModel(IOfferAppService service)
{
_offerAppService = service;
}
public virtual async Task OnGetAsync()
{
var serviceTypeLookup = await _offerAppService.GetServiceTypeLookupAsync();
ServiceTypes = serviceTypeLookup
.Select(x => new SelectListItem(x.Name, x.Id.ToString()))
.ToList();
var serviceSubTypeLookup = await _offerAppService.GetServiceSubTypeLookupAsync();
ServiceSubTypes = serviceSubTypeLookup
.Select(x => new SelectListItem(x.Name, x.Id.ToString()))
.ToList();
}
public virtual async Task<JsonResult> OnGetSelectServiceTypeAsync(Guid serviceTypeId)
{
var serviceSubTypeLookup = await _offerAppService.GetServiceSubTypeLookupAsync(serviceTypeId);
return new JsonResult(serviceSubTypeLookup);
}
}
服务:
public interface IOfferAppService
{
Task<List<ServiceTypes>> GetServiceTypeLookupAsync();
Task<List<ServiceSubTypes>> GetServiceSubTypeLookupAsync();
Task<List<ServiceSubTypes>> GetServiceSubTypeLookupAsync(Guid id);
}
public class OfferApp : IOfferAppService
{
private readonly RazorProj3_1Context _context;
public OfferApp(RazorProj3_1Context context)
{
_context = context;
}
public async Task<List<ServiceSubTypes>> GetServiceSubTypeLookupAsync()
{
var model =await _context.ServiceSubTypes.ToListAsync();
return model;
}
public async Task<List<ServiceSubTypes>> GetServiceSubTypeLookupAsync(Guid id)
{
var model = await _context.ServiceSubTypes
.Where(a => a.ServiceTypeId == id).ToListAsync();
return model;
}
public async Task<List<ServiceTypes>> GetServiceTypeLookupAsync()
{
var model = await _context.ServiceTypes.ToListAsync();
return model;
}
}
第二种方法类似于您要使用jquery将值添加到url的方法,但是这种方法有一个缺点,它将在浏览器地址栏中显示URL:
Index.cshtml:
@page
@model IndexModel
<select asp-for="ViewModel.ServiceTypeId" asp-items="Model.ServiceTypes"></select>
<select asp-for="ViewModel.ServiceSubTypeId" asp-items="Model.ServiceSubTypes"></select>
<a href="">Update</a>
@section Scripts
{
<script>
$(function () {
$("#ViewModel_ServiceTypeId").on("change", function () {
var ServiceTypeId = $(this).val();
var url = $("a").attr("href", "?handler=SelectServiceType&serviceTypeId=" + ServiceTypeId);
});
});
</script>
}
Index.cshtml.cs:
public class IndexModel : PageModel
{
[BindProperty]
public CreateOfferViewModel ViewModel { get; set; }
public List<SelectListItem> ServiceTypes { get; set; }
public List<SelectListItem> ServiceSubTypes { get; set; }
private readonly IOfferAppService _offerAppService;
public IndexModel(IOfferAppService service)
{
_offerAppService = service;
}
public virtual async Task OnGetSelectServiceTypeAsync(Guid serviceTypeId)
{
var serviceTypeLookup = await _offerAppService.GetServiceTypeLookupAsync();
ServiceTypes = serviceTypeLookup
.Select(x => new SelectListItem(x.Name, x.Id.ToString()))
.ToList();
//obtain the first select item selected
var data = ServiceTypes.Where(a => a.Value == serviceTypeId.ToString()).FirstOrDefault();
data.Selected = true;
var serviceSubTypeLookup = await _offerAppService.GetServiceSubTypeLookupAsync(serviceTypeId);
ServiceSubTypes = serviceSubTypeLookup
.Select(x => new SelectListItem(x.Name, x.Id.ToString()))
.ToList();
}
}