You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core Identity:如何在控制器获取Claims复选框选中值

How to Get Selected Claim Values (True/False) in Controller

Alright, let's break down the issues with your current code and fix it so you can properly capture which claims are selected in your controller.

The Core Problems

  1. Your Claim class (from System.Security.Claims) doesn't have a property to track whether it's selected—you need a custom view model to add this state.
  2. Using foreach with EditorFor won't generate the correct model binding names that ASP.NET MVC needs to map form data back to your collection.

Step 1: Update Your View Models

First, create a custom view model for individual claims to include an IsSelected property. Then update your RoleClaimsViewModel to use this new model instead of the raw Claim type:

// New view model for individual claims
public class ClaimViewModel
{
    public string Type { get; set; }
    public string Value { get; set; } // Include if you need the claim's value
    public bool IsSelected { get; set; } // Tracks if the claim is checked
}

// Updated role claims view model
public class RoleClaimsViewModel
{
    public string RoleName { get; set; }
    public List<ClaimViewModel> Claims { get; set; }
}

Step 2: Fix the Razor View for Proper Model Binding

Replace your foreach loops with for loops—this ensures MVC generates form field names with indexes (like [0].Claims[0].IsSelected) that the model binder can recognize. Wrap everything in a form so you can submit the data:

@model List<IRSProject.Model.UserService.RoleClaimsViewModel>

@using (Html.BeginForm("SaveSelectedClaims", "YourController", FormMethod.Post))
{
    @for (int roleIdx = 0; roleIdx < Model.Count; roleIdx++)
    {
        <div class="col-md-4 col-role">
            <!-- Hidden field to preserve the role name on submit -->
            @Html.HiddenFor(m => m[roleIdx].RoleName)
            
            <input type="checkbox" id="Role_@roleIdx" />
            <span>@Model[roleIdx].RoleName</span>
            
            <ul style="margin-left:1em">
                @for (int claimIdx = 0; claimIdx < Model[roleIdx].Claims.Count; claimIdx++)
                {
                    <li>
                        <!-- Hidden field to keep the claim type -->
                        @Html.HiddenFor(m => m[roleIdx].Claims[claimIdx].Type)
                        <!-- Checkbox bound to the IsSelected property -->
                        @Html.CheckBoxFor(m => m[roleIdx].Claims[claimIdx].IsSelected)
                        <!-- Label for the checkbox -->
                        @Html.LabelFor(m => m[roleIdx].Claims[claimIdx].IsSelected, Model[roleIdx].Claims[claimIdx].Type)
                    </li>
                }
            </ul>
        </div>
    }
    
    <button type="submit" class="btn btn-primary">Save Selected Claims</button>
}

Alternative: Use an Editor Template (Cleaner Views)

If you prefer cleaner markup, create an Editor Template for ClaimViewModel:

  1. Create a folder Views/Shared/EditorTemplates
  2. Add a file ClaimViewModel.cshtml with this content:
@model IRSProject.Model.UserService.ClaimViewModel

@Html.HiddenFor(m => m.Type)
@Html.CheckBoxFor(m => m.IsSelected)
@Html.LabelFor(m => m.IsSelected, Model.Type)

Then update your view to use EditorFor for the claims collection (still use a for loop for roles to preserve indexing):

@for (int roleIdx = 0; roleIdx < Model.Count; roleIdx++)
{
    <div class="col-md-4 col-role">
        @Html.HiddenFor(m => m[roleIdx].RoleName)
        <input type="checkbox" id="Role_@roleIdx" />
        <span>@Model[roleIdx].RoleName</span>
        <ul style="margin-left:1em">
            @Html.EditorFor(m => m[roleIdx].Claims)
        </ul>
    </div>
}

Step 3: Capture the Selected Values in the Controller

Add a HttpPost action method that accepts your list of RoleClaimsViewModel. The model binder will automatically map the submitted form data to this model:

[HttpPost]
public ActionResult SaveSelectedClaims(List<RoleClaimsViewModel> model)
{
    if (ModelState.IsValid)
    {
        // Iterate through each role and its claims
        foreach (var roleClaims in model)
        {
            string roleName = roleClaims.RoleName;
            
            foreach (var claim in roleClaims.Claims)
            {
                bool isSelected = claim.IsSelected;
                string claimType = claim.Type;
                
                // Handle your business logic here:
                if (isSelected)
                {
                    // This claim was checked—add it to the role, save to DB, etc.
                }
                else
                {
                    // This claim was unchecked—remove it from the role, etc.
                }
            }
        }
        
        return RedirectToAction("YourSuccessAction");
    }
    
    // Return to the view if validation fails
    return View(model);
}

Key Takeaways

  • Always use a custom view model when you need to track UI state (like IsSelected) that isn't part of your domain model.
  • Use for loops (instead of foreach) for collections in forms to ensure MVC generates correct model binding names.
  • Hidden fields preserve values like RoleName and Claim.Type that you need to identify items after submission.

内容的提问来源于stack exchange,提问作者MrJahanbin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 11:27:57