我的 SelectListItem 中的 post 操作出现 NullReferenceException
I am getting NullReferenceException on a post action in my SelectListItem
我在角色和订阅上得到了 NullReferenceException
,我不确定为什么,我的 Model.State
检查是 false
,所以它是无效的。我已将与 get 方法相同的视图模型传递给 post 方法。
表格
<div class="form-group">
@Html.LabelFor(m => m.User.UserRoles)
@Html.DropDownListFor(m => m.User.SelectedUserRoleId, Model.User.UserRoles, "Role", new { id = "txtBusinessName", @class = "form-control", placeholder = "Business Name" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Business.Subscriptions)
@Html.DropDownListFor(m => m.Business.SelectedSubscriptionId, Model.Business.Subscriptions, "Subscription Type", new { id = "txtBusinessName", @class = "form-control", placeholder = "Business Name" })
</div>
型号
public class RegisterationViewModel
{
public BusinessViewModel Business { get; set; }
public UserViewModel User { get; set; }
}
UserViewModel 属性有错误
public Guid SelectedUserRoleId {get; set;}
[Display(Name = "Role")]
[Required]
public IEnumerable<SelectListItem> UserRoles { get; set; }
BusinessViewModel 属性有错误
public Guid SelectedSubscriptionId {get; set; }
[Display(Name = "Subscription Type")]
[Required]
public IEnumerable<SelectListItem> Subscriptions { get; set; }
获取方法
[HttpGet]
public ActionResult Register()
{
var businessSubscriptionViewModels = new List<BusinessSubscriptionViewModel>();
var userRoleViewModels = new List<UserRoleViewModel>();
var registrationViewModel = new RegisterationViewModel();
businessSubscriptionViewModels.AddRange(
_subscriptionServiceClient.GetBusinessSubscriptionContracts()
.Select(Mapper.Map<BusinessSubscriptionContract, BusinessSubscriptionViewModel>));
registrationViewModel.Business = new BusinessViewModel
{
Subscriptions = new SelectList(businessSubscriptionViewModels, "Id", "Name")
};
userRoleViewModels.AddRange(
_userRoleServiceClient.GetUserRoles().Select(Mapper.Map<UserRoleContract, UserRoleViewModel>));
registrationViewModel.User = new UserViewModel
{
UserRoles = new SelectList(userRoleViewModels, "Id", "Name")
};
return View(registrationViewModel);
}
Post方法
[HttpPost]
public ActionResult Register(RegisterationViewModel registerationViewModel)
{
if (!ModelState.IsValid)
{
return View();
}
var businessContract = Mapper.Map<BusinessViewModel, BusinessContract>(registerationViewModel.Business);
var registeredBusiness = _businessRegistrationServiceClient.CreateBusiness(businessContract);
var userContract = Mapper.Map<UserViewModel, UserContract>(registerationViewModel.User);
var registeredUser = _userServiceClient.CreateUser(businessContract.ID, userContract);
return View(registerationViewModel);
}
您的 UserRoles
和 Subscriptions
属性在发布后将为空,因为只有 selected 选项的 value select 列表将被发布,而不是 select 列表本身。此外,根据已发布或未发布的内容,视图模型上的 Business
and/or User
属性也可能为空。如果这些实例上至少有一个 属性 已发布,则模型绑定器只会为这些属性新建一个实例。例如,如果有人将表单的整个 "user" 部分留空,则 User
将为空,并且尝试访问 User
上的任何 属性 将导致 NullReferenceException
.
您需要确保 Business
和 User
始终具有一个值(通过视图模型的构造函数或自定义 getter 和 setter),或者您需要在之前显式检查空值访问他们的任何成员。
我弄明白了,错误是我对 SelectListItems
属性 进行了 Required
验证检查。但是在 post 上,select 列表绑定到的值是唯一会像 Chris 建议的那样被 posted 的东西。
如果我想保持相同的必需验证,我已将验证设置为 SelectListItem 绑定到的 Selected 属性。这样,由于 SelectListItem 为空,SelectedUserRoleId 或 SelectedBusinessSubscriptionId 将不会。
简单修复
[Required]
public Guid SelectedUserRoleId {get; set;}
[Display(Name = "Role")]
public IEnumerable<SelectListItem> UserRoles { get; set; }
[Required]
public Guid SelectedSubscriptionId {get; set; }
[Display(Name = "Subscription Type")]
public IEnumerable<SelectListItem> Subscriptions { get; set; }
我在角色和订阅上得到了 NullReferenceException
,我不确定为什么,我的 Model.State
检查是 false
,所以它是无效的。我已将与 get 方法相同的视图模型传递给 post 方法。
表格
<div class="form-group">
@Html.LabelFor(m => m.User.UserRoles)
@Html.DropDownListFor(m => m.User.SelectedUserRoleId, Model.User.UserRoles, "Role", new { id = "txtBusinessName", @class = "form-control", placeholder = "Business Name" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Business.Subscriptions)
@Html.DropDownListFor(m => m.Business.SelectedSubscriptionId, Model.Business.Subscriptions, "Subscription Type", new { id = "txtBusinessName", @class = "form-control", placeholder = "Business Name" })
</div>
型号
public class RegisterationViewModel
{
public BusinessViewModel Business { get; set; }
public UserViewModel User { get; set; }
}
UserViewModel 属性有错误
public Guid SelectedUserRoleId {get; set;}
[Display(Name = "Role")]
[Required]
public IEnumerable<SelectListItem> UserRoles { get; set; }
BusinessViewModel 属性有错误
public Guid SelectedSubscriptionId {get; set; }
[Display(Name = "Subscription Type")]
[Required]
public IEnumerable<SelectListItem> Subscriptions { get; set; }
获取方法
[HttpGet]
public ActionResult Register()
{
var businessSubscriptionViewModels = new List<BusinessSubscriptionViewModel>();
var userRoleViewModels = new List<UserRoleViewModel>();
var registrationViewModel = new RegisterationViewModel();
businessSubscriptionViewModels.AddRange(
_subscriptionServiceClient.GetBusinessSubscriptionContracts()
.Select(Mapper.Map<BusinessSubscriptionContract, BusinessSubscriptionViewModel>));
registrationViewModel.Business = new BusinessViewModel
{
Subscriptions = new SelectList(businessSubscriptionViewModels, "Id", "Name")
};
userRoleViewModels.AddRange(
_userRoleServiceClient.GetUserRoles().Select(Mapper.Map<UserRoleContract, UserRoleViewModel>));
registrationViewModel.User = new UserViewModel
{
UserRoles = new SelectList(userRoleViewModels, "Id", "Name")
};
return View(registrationViewModel);
}
Post方法
[HttpPost]
public ActionResult Register(RegisterationViewModel registerationViewModel)
{
if (!ModelState.IsValid)
{
return View();
}
var businessContract = Mapper.Map<BusinessViewModel, BusinessContract>(registerationViewModel.Business);
var registeredBusiness = _businessRegistrationServiceClient.CreateBusiness(businessContract);
var userContract = Mapper.Map<UserViewModel, UserContract>(registerationViewModel.User);
var registeredUser = _userServiceClient.CreateUser(businessContract.ID, userContract);
return View(registerationViewModel);
}
您的 UserRoles
和 Subscriptions
属性在发布后将为空,因为只有 selected 选项的 value select 列表将被发布,而不是 select 列表本身。此外,根据已发布或未发布的内容,视图模型上的 Business
and/or User
属性也可能为空。如果这些实例上至少有一个 属性 已发布,则模型绑定器只会为这些属性新建一个实例。例如,如果有人将表单的整个 "user" 部分留空,则 User
将为空,并且尝试访问 User
上的任何 属性 将导致 NullReferenceException
.
您需要确保 Business
和 User
始终具有一个值(通过视图模型的构造函数或自定义 getter 和 setter),或者您需要在之前显式检查空值访问他们的任何成员。
我弄明白了,错误是我对 SelectListItems
属性 进行了 Required
验证检查。但是在 post 上,select 列表绑定到的值是唯一会像 Chris 建议的那样被 posted 的东西。
如果我想保持相同的必需验证,我已将验证设置为 SelectListItem 绑定到的 Selected 属性。这样,由于 SelectListItem 为空,SelectedUserRoleId 或 SelectedBusinessSubscriptionId 将不会。
简单修复
[Required]
public Guid SelectedUserRoleId {get; set;}
[Display(Name = "Role")]
public IEnumerable<SelectListItem> UserRoles { get; set; }
[Required]
public Guid SelectedSubscriptionId {get; set; }
[Display(Name = "Subscription Type")]
public IEnumerable<SelectListItem> Subscriptions { get; set; }