Опубликовать новую запись в AspNetUsers с другого контроллера (Web API) - PullRequest
0 голосов
/ 04 апреля 2019

Я хочу отправить нового пользователя в AspNetUsers с помощью webApi Вот что я пытаюсь сделать: [HttpPost]

        public async Task<IHttpActionResult> POST([FromBody]ICollection<ApplicationUser> employees)
        {

        employees.First().PasswordHash = HashPassword(employees.First().PasswordHash);

        if (!ModelState.IsValid)
            {

                return BadRequest(ModelState);
            }


        foreach (var item in employees)
        {
            db.Users.Add(item);
        }
        try
        {
            await db.SaveChangesAsync();
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            Exception raise = dbEx;
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                    // raise a new exception nesting
                    // the current instance as InnerException
                    raise = new InvalidOperationException(message, raise);
                }
            }
            throw raise;
        }
        var manager = new UserManager<ApplicationUser, int>
        (new CustomUserStore(new ApplicationDbContext()));

        var roleManager = new RoleManager<CustomRole, int>
            (new CustomRoleStore(new ApplicationDbContext()));
        manager.AddToRoles(employees.First().Id, "User");

        return CreatedAtRoute("DefaultApi", new { id = employees.First().Id  }, employees);
    }
    public static string HashPassword(string password)
    {
        if (password == null)
        {
            throw new ArgumentNullException("password");
        }


        byte[] salt;
        byte[] subkey;
        using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount))
        {
            salt = deriveBytes.Salt;
            subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
        }

        var outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength];
        Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
        Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, PBKDF2SubkeyLength);
        return Convert.ToBase64String(outputBytes);
    }

Я попытался проверить это с помощью Почтальона, и вот что я получаю:

**** [ArgumentNullException]: значение не может быть нулевым. Имя параметра: значение в System.Security.Claims.Claim..ctor (строковый тип, строковое значение, строковое значениеType, строковый эмитент, строковый originalIssuer, субъект ClaimsIdentity, строковое propertyKey, строковое propertyValue) в System.Security.Claims.Claim..ctor (тип String, значение String) в Microsoft.AspNet.Identity.ClaimsIdentityFactory 2.<CreateAsync>d__19.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter 1.GetResult () в DataInGrid.Models.ApplicationUser.d__0.MoveNext () в C: \ DataInGrid \ DataInGrid \ Models \ IdentityModels.cs: строка 18 --- Конец стека трассировки от предыдущего местоположения, где было сгенерировано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Задача) at System.Runtime.CompilerServices.TaskAwaiter 1.GetResult() at DataInGrid.Providers.ApplicationOAuthProvider.<GrantResourceOwnerCredentials>d__2.MoveNext() in C:\DataInGrid\DataInGrid\Providers\ApplicationOAuthProvider.cs:line 42 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerHandler.<InvokeTokenEndpointResourceOwnerPasswordCredentialsGrantAsync>d__3f.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerHandler.<InvokeTokenEndpointAsync>d__22.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerHandler.<InvokeAsync>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware 1.d__0.MoveNext () --- Конец стека трассировки от предыдущего местоположения, где было сгенерировано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Задача) в Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware 1.<Invoke>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware 1.d__0.MoveNext () --- Конец стека трассировки от предыдущего местоположения, где было сгенерировано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Задача) в Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware 2.<Invoke>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware 2.d__5.MoveNext () --- Конец стека трассировки от предыдущего местоположения, где было сгенерировано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Задача) в Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage.d__5.MoveNext () --- Конец стека трассировки от предыдущего местоположения, где было сгенерировано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Задача) в Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.d__2.MoveNext () --- Конец стека трассировки от предыдущего местоположения, где было сгенерировано исключение --- в Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End (IAsyncResult ar) в Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork (IAsyncResult ar) в System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () в System.Web.HttpApplication.ExecuteStepImpl (шаг IExecutionStep) в System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, логический и завершен синхронно) -> ****

1 Ответ

0 голосов
/ 04 апреля 2019

Ваш код - горячий беспорядок. Я не уверен, что в мире ты делаешь. Во-первых, UserManager и RoleManager являются услугами. Вы никогда не обновляете их; вместо этого вы вводите их в свой класс:

[ApiController]
public UserApiController : ControllerBase
{
    private readonly UserManager<ApplicationUser> _userManager;

    public UserApiController(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    ...
}

Затем, чтобы создать нового пользователя, вы должны использовать:

await _userManager.CreateAsync(user, password);

Это позаботится о хешировании пароля для вас, а также о других необходимых задачах, таких как нормализация имени пользователя, адреса электронной почты и т. Д.

Далее, вы не должны связывать сообщение с ApplicationUser. Это ваша сущность, и она не подходит для чего-то вроде запроса на создание пользователя. А именно, у него нет свойства Password для хранения желаемого пароля пользователя, предварительно хешированного. Вместо этого вы должны создать модель представления / класс DTO только с теми свойствами, которые вы хотите иметь возможность отправлять. Это может быть всего лишь адрес электронной почты и пароль.

Затем вы отображаете опубликованные данные на экземпляр вашей ApplicationUser сущности:

var user = new ApplicationUser
{
    Email = model.Email
    // etc.
};

Тогда:

await _userManager.CreateAsync(user, model.Password);

Поскольку вы публикуете список пользователей для создания, вы просто повторяете его и делаете то же самое для каждого из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...