Chcę tworzyć role z odpowiednimi roszczeniami w asp.net core 2+, więc tworzę widok taki jak:

@page
@model Security.Dto.Models.ApplicationRoleModel

<form asp-controller="security" asp-action="CreateRole" method="post">

    <h4>Create new Role</h4>
    <hr />
    <div asp-validation-summary="All" class="text-danger"></div>
    <div class="form-group" id="item-list">
        <label>Role Name</label>
        <input asp-for="RoleClaimList[0].Role.Name" class="form-control roles" />
    </div>
    <a href="#" id="add">Add another</a>


    <div class="form-group" id="claim-list">
        <label>Claim Type</label>
        <input asp-for="RoleClaimList[0].ClaimList[0].Type" class="form-control " />
        <label>Claim Value</label>
        <input asp-for="RoleClaimList[0].ClaimList[0].Value" class="form-control claims" />
    </div>
    <br />
    <button type="submit" class="btn btn-default">Create</button>

</form>

@section Scripts {
    <script>
        $(function () {
            $("#add").click(function (e) {
                e.preventDefault();
                var i = ($(".roles").length);
                var n = '<label>Role Name</label><input class="form-control roles" name="RoleClaimList[' + i + '].Role.Name" />'
                $("#item-list").append(n);
            });

        });
    </script>
}

Kontroler:

public async Task<IActionResult> CreateRole(ApplicationRoleModel model)
        {
            try
            {
                foreach (var item in model.RoleClaimList)
                {
                    var roleExists = await _roleManager.RoleExistsAsync(item.Role.Name);
                    if (roleExists) continue;
                    var createRole = _roleManager.CreateAsync(item.Role);
                    foreach (var claim in item.ClaimList)
                    {
                        await _roleManager.AddClaimAsync(item.Role, claim);
                    }
                }
                return Ok();
            }
            catch (Exception e)
            {
                return BadRequest();
            }
        }

Model roli aplikacji:

public class ApplicationRoleModel 
    {
        public List<RoleClaimModel> RoleClaimList { get; set; }
      
    }

Model roszczenia roli:

 public class ClaimsToRoleModel
    {
        public List<RoleClaimModel> RoleClaimList { get; set; }
    }

    public class RoleClaimModel
    {
        public ApplicationRole Role { get; set; }
        public List<Claim> ClaimList { get; set; }
    }

Więc kiedy uruchamiam i debuguję, Role przychodzi poprawnie, ale ClaimList zawsze liczy 0 lub jest pusty

enter image description here

Ktoś patrzy, co robię źle? Jak poprawnie zmapować model właściwości ClaimList z widoku?

Pozdrowienia

1
Jonathan 9 listopad 2018, 22:16

1 odpowiedź

Najlepsza odpowiedź

Twój problem jest spowodowany tym, że klasa Claim nie ma konstruktor, który przyjmuje 0 parametrów, więc gdy framework próbuje utworzyć nowy, nie może, więc kończysz z pustym lub pustym obiektem.

Aby rozwiązać ten problem, musisz użyć własnej niestandardowej klasy w swojej hierarchii:

public class CustomClaim
{
    public string Type { get; set; }
    public string Value { get; set; }
}

public class RoleClaimModel
{
    public ApplicationRole Role { get; set; }
    public List<CustomClaim> ClaimList { get; set; }
}

Teraz framework może utworzyć CustomClaim i zserializować go do Twojego interfejsu API. W swoim kontrolerze możesz przetłumaczyć CustomClaim na .NET Claim i przekazać to do _roleManager:

public async Task<IActionResult> CreateRole(ApplicationRoleModel model)
{
    try
    {
        foreach (var item in model.RoleClaimList)
        {
            var roleExists = await _roleManager.RoleExistsAsync(item.Role.Name);
            if (roleExists) continue;
            var createRole = _roleManager.CreateAsync(item.Role);
            foreach (var claim in item.ClaimList)
            {
                var c = new System.Security.Claims.Claim(claim.Type, claim.Value);

                await _roleManager.AddClaimAsync(item.Role, c);
            }
        }
        return Ok();
    }
    catch (Exception e)
    {
        return BadRequest();
    }
}
1
Simply Ged 10 listopad 2018, 04:58