簡體   English   中英

在POST上將模型綁定到單選按鈕

[英]Bind Model to Radio Buttons on POST

我正在嘗試擴展使用EF6和MVC生成的用戶注冊表單,我希望能夠顯示以單選按鈕顯示的用戶角色列表,我相信我已經做到了。 但是,我遇到的麻煩是當我將表單發布回控制器時,它沒有將所選選項綁定回視圖模型。 我究竟做錯了什么?

我的視圖模型:

public class RegisterViewModel
{
    [Required]
    [Display(ResourceType = typeof(ResourceStrings), Name = "Username")]
    [StringLength(50, ErrorMessageResourceType = typeof(ResourceStrings), ErrorMessageResourceName = "MinLengthValidation", MinimumLength = 4)]
    public string Username { get; set; }

    [Required]
    [Display(ResourceType = typeof(ResourceStrings), Name = "FirstName")]
    [StringLength(50, ErrorMessageResourceType = typeof(ResourceStrings), ErrorMessageResourceName = "MinLengthValidation", MinimumLength = 2)]
    public string FirstName { get; set; }

    [Required]
    [Display(ResourceType = typeof(ResourceStrings), Name = "Surname")]
    [StringLength(50, ErrorMessageResourceType = typeof(ResourceStrings), ErrorMessageResourceName = "MinLengthValidation", MinimumLength = 2)]
    public string Surname { get; set; }

    //Other fields removed to save space

    [Required]
    [Display(Name = "Roles")]
    public IEnumerable<IdentityRole> UserRoles { get; set; }
}

我有一個要傳遞給視圖的身份角色列表,如下所示:

// GET: /Account/Register
    [AllowAnonymous]
    public ActionResult Register()
    {
        var model = new RegisterViewModel();
        model.UserRoles =  new RoleManager<IdentityRole>(new RoleStore<IdentityRole>()).Roles.ToList();

        return View(model);
    }

在視圖上,我顯示如下角色:

     <div class="panel-body">
            @foreach (var item in Model.UserRoles)
            {
                <div class="col-md-8">
                    <div>
                        @Html.RadioButtonFor(m => m.UserRoles, item.Name)
                        @Html.DisplayFor(m => item.Name, new { @class = "col-md-3 control-label" })
                    </div>
                </div>
            }
            @Html.ValidationMessageFor(m => m.UserRoles, "", new { @class = "text-danger" })
        </div>

但是,將表單提交回時,該模型永遠無效,因為該角色從未綁定。 (或者至少是我所相信的)任何想法?

您不想將單選按鈕綁定到值列表,需要將模型更改為角色列表和所選角色,如下所示

//Other fields removed to save space

[Required]
[Display(Name = "Role")]
public IdentityRole UserRole { get; set; }

[Display(Name = "Roles")]
public IEnumerable<IdentityRole> UserRoles { get; set; }

然后像這樣創建單選按鈕

@Html.RadioButtonFor(m => m.UserRole, item.Name)

然后,這會將選定的值回發到UserRole屬性。

注意:我認為您還需要使用單選按鈕的值來使它填充回UserRole,因為我認為item.Name不起作用。 您可能需要將其發布回具有名稱的字符串字段,然后在控制器的post方法中查找適當的角色。

我對此進行了調查(因為我有一個可用的方法,甚至對理論進行了檢驗),這是不可能的。 您可以將所選對象的任何子屬性綁定到您的視圖模型,但不能將其整體綁定。

這是我來自堆棧溢出的參考

HTML控件(輸入,文本區域,選擇)回傳它們的名稱/值對。 在您的情況下,與單選按鈕關聯的表單數據將為UserRoles: someValue

假設您的POST方法是public ActionResult Register(RegisterViewModel model) ,則DefaultModelBinder首先初始化RegisterViewModel的實例,然后找到匹配的表單數據名稱/值對,並嘗試將UserRoles屬性的值設置為字符串"someValue" ,這當然會失敗因為UserRoles是一個復雜的對象,而UserRoles變為null

除非創建自定義ModelBinder和/或ValueProviders ,否則您無法將html控件綁定到復雜的對象,即使那樣,它也只會設置模型的一個屬性,因為您只回發了一個值。

例如,您需要創建一個視圖模型,該模型的屬性表示要在視圖中顯示/編輯的內容(假設IdentityRole type具有屬性int ID

public class RegisterViewModel
{
  [Required]
  [Display(ResourceType = typeof(ResourceStrings), Name = "Username")]
  [StringLength(50, ErrorMessageResourceType = typeof(ResourceStrings), ErrorMessageResourceName = "MinLengthValidation", MinimumLength = 4)]
  public string Username { get; set; }
  ....

  // For binding the selected roles
  [Required(ErrorMessage = "Please select a role")]
  public int ID SelectedRole { set; set; }

  // For displaying the available roles 
  [Display(Name = "Roles")]
  public IEnumerable<IdentityRole> UserRoles { get; set; }
}

然后在視圖中

@model yourAssembly.RegisterViewModel
@using (Html.BeginForm())
{
  ....
  foreach(var role in Model.UserRoles)
  {
    @Html.RadioButtonFor(m => m.SelectedRole, role.ID, new { id = role.Name })
    <label for="@role.Name">@role.Name</label>
  }
  @Html.ValidationMessageFor(m => m.SelectedRole)
  ....
}

回發后,您可以從模型SelectedRole屬性中獲取所選角色的ID。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM