【问题标题】:I am getting NullReferenceException on a post action in my SelectListItem [duplicate]我的 SelectListItem [重复] 中的发布操作收到 NullReferenceException
【发布时间】:2016-10-18 02:49:26
【问题描述】:

我在角色和订阅上得到一个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);
}

发布方式

[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);
}

【问题讨论】:

  • 也许模型绑定器无法将string SelectListItem.Value 绑定为 Guid?要对此进行测试,请将模型中的 SelectedUserRoleId 更改为 string
  • 我还注意到您在两个 DropDownLists 的 HtmlAttributes 中为 id 传递了相同的值。让 MVC 设置 ID,以便模型绑定器识别它。
  • 在您的发布方法中,您“返回 View();”没有模型。我不是专家,但在我看来这可能是个问题。

标签: asp.net-mvc forms http-post html.dropdownlistfor selectlistitem


【解决方案1】:

我想通了,错误是我对SelectListItems 属性进行了Required 验证检查。但是在帖子上,选择列表绑定到的值是唯一将按照 Chris 建议发布的内容。

如果我想保持相同的所需验证,我已将验证设置为 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; }

【讨论】:

    【解决方案2】:

    您的UserRolesSubscriptions 属性在发布后将为空,因为只有选定选项的 会发布选择列表,而不是选择列表本身。此外,根据发布或未发布的内容,您的视图模型上的 Business 和/或 User 属性也可能为空。如果至少发布了这些实例上的一个属性,则模型绑定器只会为这些属性新建一个实例。例如,如果有人将表单的整个“用户”部分留空,则User 将为空,并且尝试访问User 上的任何属性将导致NullReferenceException

    您要么需要确保BusinessUser 始终具有值(通过视图模型的构造函数或自定义getter 和setter),要么需要在访问它们的任何成员之前显式检查空值。

    【讨论】:

    • 嗨 Chris,感谢您的回复,除了 Subscriptions 和 UserRoles 之外,Business 和 User 中还有其他属性,这些属性具有值,并且 SelectedUserRoleId 和 SelectedSubscriptionId 也具有正确的 Guid 值。只是 SelectListItem 属性为空。我想我现在对你的问题是如何确保这不是 null ?我需要稍微改变一下用户界面吗?
    • 没有。您在 GET 操作中用来填充它们的方法也应该在 POST 操作中使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多