Не удалось обновить удостоверение AspNetUsers с помощью пользовательских свойств - PullRequest
0 голосов
/ 20 октября 2018

Я хочу обновить таблицу AspNetUsers с помощью пользовательских свойств.Я хочу, чтобы пользователи могли вставить адресную информацию после регистрации.С кодом я не получаю никаких ошибок, и он не обновляет таблицу.Модель и вид создаются с помощью бритвенных страниц.

Таблица (пустые значения, когда я пытаюсь обновить пользователя, и информация под ним при добавлении информации об адресе при регистрации)

Хотя, когда я разрешаю пользователям добавлять информацию об адресе при регистрации, она обновляет таблицу. Страница бритвы регистра создается Identity, и я создал элемент и добавил в него свои пользовательские свойства.

Address.cshtml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using bytme.Models;
using bytme.Data;
using Microsoft.EntityFrameworkCore;

namespace bytme.Areas.Identity.Pages.Account.Manage
{
    public class AddressModel : PageModel
    {
        private readonly UserManager<UserModel> _userManager;
        private readonly SignInManager<UserModel> _signInManager;
        private readonly ILogger<AddressModel> _logger;

        public AddressModel(
            UserManager<UserModel> userManager,
            SignInManager<UserModel> signInManager,
            ILogger<AddressModel> logger)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _logger = logger;
        }

        [BindProperty]
        public InputModel Input { get; set; }

        public string ReturnUrl { get; set; }

        [TempData]
        public string StatusMessage { get; set; }

        public class InputModel
        {
            [Required]
            [DataType(DataType.Text)]
            [Display(Name = "Name")]
            [StringLength(100, ErrorMessage = "Invalid input. Maximum is 100 characters.")]
            public string name { get; set; }

            [Required]
            [DataType(DataType.Text)]
            [Display(Name = "Surname")]
            [StringLength(100, ErrorMessage = "Invalid input. Maximum is 100 characters.")]
            public string surname { get; set; }

            [Required]
            [DataType(DataType.Text)]
            [Display(Name = "Street")]
            [StringLength(48, ErrorMessage = "The longest street name in the Netherlands is 48 characters.")]
            public string street { get; set; }

            [Required]
            [DataType(DataType.Text)]
            [Display(Name = "House Number")]
            [StringLength(5, ErrorMessage = "The longest house number in the Netherlands is 5 characters.")]
            public string streetnumber { get; set; }

            //[DataType(DataType.Text)]
            //[Display(Name = "House Number Addition", Description = "For example A or II")]
            //[StringLength(6, ErrorMessage = "
            //public string streetnumberadd { get; set; }

            [Required]
            [DataType(DataType.Text)]
            [Display(Name = "City")]
            [StringLength(28, ErrorMessage = "The longest place name in the Netherlands is 28 characters.")]
            public string city { get; set; }

            [Required]
            [DataType(DataType.PostalCode)]
            [Display(Name = "Postal Code")]
            [RegularExpression(@"^[1-9][0-9]{3}\s?[a-zA-Z]{2}$", ErrorMessage = "Invalid zip, for example: 1234AB")]
            public string zipcode { get; set; }
        }

        public void OnGet(string returnUrl = null)
        {
            ReturnUrl = returnUrl;
        }

        public async Task<IActionResult> OnPostAsync(InputModel model)
        {
            if (ModelState.IsValid)
            {

                // Get the current application user
                var user = await _userManager.GetUserAsync(User);

                //Update the details
                user.name = model.name;
                user.surname = model.surname;
                user.street = model.street;
                user.streetnumber = model.streetnumber;
                user.city = model.city;
                user.zipcode = model.zipcode;

                // Update user address
                var result = await _userManager.UpdateAsync(user);
            }

            _logger.LogInformation("User added their address information successfully.");
            StatusMessage = "Your address information has been added.";

            return RedirectToPage();
        }
    }
}

Address.cshtml

@page
@model AddressModel
@{
    ViewData["Title"] = "Add Address Information";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@Html.Partial("_StatusMessage", Model.StatusMessage)
<div>
    <h3>Change your account settings</h3>
    <hr />
    <div class="row">
        <div class="col-md-3">
            <partial name="_ManageNav" />
        </div>
        <div class="col-md-9">
            <div class="row">
                <div class="col-md-6">
                    <h4>@ViewData["Title"]</h4>
                    <form id="address-form" method="post">
                        <div asp-validation-summary="All" class="text-danger"></div>
                        <div class="form-group">
                            <label asp-for="Input.name"></label>
                            <input asp-for="Input.name" class="form-control" />
                            <span asp-validation-for="Input.name" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="Input.surname"></label>
                            <input asp-for="Input.surname" class="form-control" />
                            <span asp-validation-for="Input.surname" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="Input.street"></label>
                            <input asp-for="Input.street" class="form-control" />
                            <span asp-validation-for="Input.street" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="Input.streetnumber"></label>
                            <input asp-for="Input.streetnumber" class="form-control" />
                            <span asp-validation-for="Input.streetnumber" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="Input.city"></label>
                            <input asp-for="Input.city" class="form-control" />
                            <span asp-validation-for="Input.city" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="Input.zipcode"></label>
                            <input asp-for="Input.zipcode" class="form-control" />
                            <span asp-validation-for="Input.zipcode" class="text-danger"></span>
                        </div>
                        <button type="submit" class="btn btn-default" asp-page-handler="OnPostAsync">Submit</button>
                    </form>
                </div>
            </div>

        </div>
    </div>
</div>

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
}

Register.cshtml.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Net;
using System.Net.Mail;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using bytme.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace bytme.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class RegisterModel : PageModel
    {
        private readonly SignInManager<UserModel> _signInManager;
        private readonly UserManager<UserModel> _userManager;
        private readonly ILogger<RegisterModel> _logger;
        private readonly IEmailSender _emailSender;

        public RegisterModel(
            UserManager<UserModel> userManager,
            SignInManager<UserModel> signInManager,
            ILogger<RegisterModel> logger,
            IEmailSender emailSender)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _logger = logger;
            _emailSender = emailSender;
        }

        [BindProperty]
        public InputModel Input { get; set; }

        public string ReturnUrl { get; set; }

        public class InputModel
        {
            [Required]
            [EmailAddress]
            [Display(Name = "Email")]
            public string Email { get; set; }

            [Required]
            [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
            [DataType(DataType.Password)]
            [Display(Name = "Password")]
            public string Password { get; set; }

            [DataType(DataType.Password)]
            [Display(Name = "Confirm password")]
            [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
            public string ConfirmPassword { get; set; }

            [DataType(DataType.Text)]
            [Display(Name = "Name")]
            [StringLength(100, ErrorMessage = "Invalid input. Maximum is 100 characters.")]
            public string name { get; set; }

            [DataType(DataType.Text)]
            [Display(Name = "Surname")]
            [StringLength(100, ErrorMessage = "Invalid input. Maximum is 100 characters.")]
            public string surname { get; set; }

            [DataType(DataType.Text)]
            [Display(Name = "Street")]
            [StringLength(48, ErrorMessage = "The longest street name in the Netherlands is 48 characters.")]
            public string street { get; set; }

            [DataType(DataType.Text)]
            [Display(Name = "House Number")]
            [StringLength(5, ErrorMessage = "The longest house number in the Netherlands is 5 characters.")]
            public string streetnumber { get; set; }

            //[DataType(DataType.Text)]
            //[Display(Name = "House Number Addition", Description = "For example A or II")]
            //[StringLength(6, ErrorMessage = "
            //public string streetnumberadd { get; set; }

            [DataType(DataType.Text)]
            [Display(Name = "City")]
            [StringLength(28, ErrorMessage = "The longest place name in the Netherlands is 28 characters.")]
            public string city { get; set; }

            [DataType(DataType.PostalCode)]
            [Display(Name = "Postal Code")]
            [RegularExpression(@"^[1-9][0-9]{3}\s?[a-zA-Z]{2}$", ErrorMessage = "Invalid zip, for example: 1234AB")]
            public string zipcode { get; set; }
        }

        public void OnGet(string returnUrl = null)
        {
            ReturnUrl = returnUrl;
        }

        public async Task<IActionResult> OnPostAsync(string returnUrl = null)
        {
            returnUrl = returnUrl ?? Url.Content("~/");
            if (ModelState.IsValid)
            {

                var user = new UserModel
                {
                    UserName = Input.Email,
                    Email = Input.Email,
                    name = Input.name,
                    surname = Input.surname,
                    street = Input.street,
                    streetnumber = Input.streetnumber,
                    city = Input.city,
                    zipcode = Input.zipcode
                };

                var result = await _userManager.CreateAsync(user, Input.Password);
                if (result.Succeeded)
                {
                    _logger.LogInformation("User created a new account with password.");

                    // confirmation code + custom URL creation
                    var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                    var callbackUrl = Url.Page(
                        "/Account/ConfirmEmail",
                        pageHandler: null,
                        values: new { userId = user.Id, code = code },
                        protocol: Request.Scheme);

                    // mailmessage creation...
                    // ...
                    return LocalRedirect(returnUrl);
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError(string.Empty, error.Description);
                }
            }

            // If we got this far, something failed, redisplay form
            return Page();
        }


    }
}

Register.cshtml

@page
@model RegisterModel
@{
    ViewData["Title"] = "Register";
}

<h2>@ViewData["Title"]</h2>

<div class="row">
    <div class="col-md-4">
        <form asp-route-returnUrl="@Model.ReturnUrl" method="post">
            <h4>Create a new account.</h4>
            <hr />
            <div asp-validation-summary="All" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Input.Email"></label>
                <input asp-for="Input.Email" class="form-control" />
                <span asp-validation-for="Input.Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.Password"></label>
                <input asp-for="Input.Password" class="form-control" />
                <span asp-validation-for="Input.Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.ConfirmPassword"></label>
                <input asp-for="Input.ConfirmPassword" class="form-control" />
                <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.name"></label>
                <input asp-for="Input.name" class="form-control" />
                <span asp-validation-for="Input.name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.surname"></label>
                <input asp-for="Input.surname" class="form-control" />
                <span asp-validation-for="Input.surname" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.street"></label>
                <input asp-for="Input.street" class="form-control" />
                <span asp-validation-for="Input.street" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.streetnumber"></label>
                <input asp-for="Input.streetnumber" class="form-control" />
                <span asp-validation-for="Input.streetnumber" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.city"></label>
                <input asp-for="Input.city" class="form-control" />
                <span asp-validation-for="Input.city" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.zipcode"></label>
                <input asp-for="Input.zipcode" class="form-control" />
                <span asp-validation-for="Input.zipcode" class="text-danger"></span>
            </div>
            <button type="submit" class="btn btn-default">Register</button>
        </form>
    </div>
</div>

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
}

UserModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;

namespace bytme.Models
{
    public class UserModel : IdentityUser
    {
        public override string Id { get; set; }
        public override string Email { get; set; }
        public override string UserName { get; set; }
        public override string PasswordHash { get; set; }
        public string zipcode { get; set; }
        public string city { get; set; }
        public string street { get; set; }
        public string streetnumber { get; set; }
        public string name { get; set; }
        public string surname { get; set; }
    }
}

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

Я воссоздал вашу проблему и обнаружил следующее.Причина, по которой в вашей таблице отображаются нулевые значения, заключается в том, что параметр model в вашем методе всегда равен нулю.

public async Task<IActionResult> OnPostAsync(InputModel model)

Таким образом, вы обновляете свои свойства над user сущностью в пределах нулевых значений.Связывание должно следовать некоторому соглашению.Здесь у вас есть два варианта:

Поскольку вы связываете свое свойство Input с атрибутом [BindProperty], где ваше представление использует тег asp-for="Input.name", ... для каждого типа ввода, вы можете получить доступ напрямую через свойство binded.

//get rid of parameter model, access directly in method body
    public async Task<IActionResult> OnPostAsync()
    {

      user = await _userManager.GetUserAsync(User);

      user.name = Input.name;
      user.surname = Input.surname;
      user.street = Input.street;
      user.streetnumber = Input.streetnumber;
      user.city = Input.city;
      user.zipcode = Input.zipcode;

      var result = await _userManager.UpdateAsync(user);

      return RedirectToPage();

    }

или второй вариант - вы можете использовать параметр в своем методе, но он должен следовать соглашению об именах.Если вы используете для каждого input в вашем представлении имя, например, Input.name, Input.surname, etc., параметр at method также должен быть назван Input.

public async Task<IActionResult> OnPostAsync(InputModel input)

Теперь вы можете получить доступ к связанным значениям через параметр (можно использовать маленькую букву в начале имени параметра) Для получения дополнительной информации о привязке см. Эту ссылку

Если я все сделал, см. Выше, я могу корректно обновить модель (без нулевых значений)

0 голосов
/ 20 октября 2018

Вы включили миграцию для обновления базы данных?Возможно, обмен журналом может предоставить некоторую информацию.Обычно я сначала не работаю с кодом, но Identity Framework создает некоторые триггеры и другие элементы, которые могут мешать свойствам, которые вы намереваетесь добавить.Попробуйте добавить «nullable» в свойствах UserModel.cs, вероятно, таблица ожидает значение, а при регистрации не получает его.У меня была похожая проблема, но, позволив инфраструктуре идентификации создавать все эти вещи в моей базе данных, я решил проблему.Обратите внимание, что мой подход был сначала базой данных!

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