locked
Addning nullable value type property to AppUser results null always (even if value set) RRS feed

  • Question

  • User1255309776 posted

    I have AppUser class which inherits IdentityUser. While some users will be assigned to relevant company, I've added Company and CompanyId properties to AppUser like below:

     public class AppUser:IdentityUser
        {
            public Company Company { get; set; }
            public int? CompanyId { get; set; }
        }

    As you can see, companyId is nullable, but when I register users which wil have their company, it again inserts NULL to the database. Here is the code:

    Account controller

     public class AccountController : Controller
        {
            private readonly UserManager<AppUser> _userManager;
            private readonly SignInManager<AppUser> _signInManager;
            private readonly OfferDbContext _offerDbContext;
            private readonly ILogger _logger;
    
            public AccountController(UserManager<AppUser> userManager, SignInManager<AppUser> signInManager, OfferDbContext offerDbContext, ILogger<AccountController> logger)
            {
                _userManager = userManager;
                _signInManager = signInManager;
                _offerDbContext = offerDbContext;
                _logger = logger;
            }
    

    Partner company register in account controller

            [HttpGet]
            [AllowAnonymous]
            public async Task<IActionResult> RegisterPartner(int Id)
            {
                RegisterModel pvModel = new RegisterModel();
                pvModel.Company = await _offerDbContext.Companies.SingleOrDefaultAsync(a => a.Id == Id);
                return View();
            }
    
            [HttpPost]
            [AllowAnonymous]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> RegisterPartner(RegisterModel registerModel, int Id)
            {
    
                if (ModelState.IsValid)
                {
                    RegisterModel pvModel = new RegisterModel();
                    pvModel.Company = await _offerDbContext.Companies.SingleOrDefaultAsync(a => a.Id == Id);
    
                    AppUser partnerUser = await _userManager.FindByEmailAsync(registerModel.Email);
    
                    if(partnerUser != null)
                    {
                        ModelState.AddModelError("", "This partner already exists");
                    }
                    else
                    {
                        partnerUser = new AppUser
                        {
                            UserName = registerModel.UserName,
                            Email = registerModel.Email,
                            CompanyId = Id
                        };
    
                        IdentityResult partnerResult = await _userManager.CreateAsync(partnerUser, registerModel.Password);
    
                        if (partnerResult.Succeeded)
                        {
                            IdentityResult result = await _userManager.AddToRoleAsync(partnerUser, RoleType.Partner.ToString());
    
                            if (result.Succeeded)
                            {
                                await _signInManager.SignInAsync(partnerUser, isPersistent: false);
                                 _offerDbContext.AppUsers.Add(partnerUser);
                                await _offerDbContext.SaveChangesAsync();
                                return RedirectToAction(nameof(AdminController.Admin), "Admin");
                            }
                        }
                        AddErrors(partnerResult);
                    }
                }
                return View(registerModel);
            }
    

    So, after clicking register from companylist view (it's not shown as there is no need) it takes relevant company Id in the "get" action, then creates AppUser for it and saves changes in database in the "post" action.

    Register View

    @model Foroffer.Models.ViewModels.RegisterModel
    
    <section class="posts">
        <div class="post-container">
            <div class="row">
                <div class="col-lg-4 col-md-4 col-sm-6 col-12">
    
                </div>
                <div class="col-lg-4 col-md-4 col-sm-6 col-12">
                    <div class="register">
                        <form method="post" asp-action="RegisterPartner" asp-controller="Account">
                            <div asp-validation-summary="ModelOnly"></div>
                            <h6>Qeydiyyat</h6>
                            <label asp-for="FullName" style="width: 80px" for="Username">Full Name*</label>
                            <input asp-for="FullName" class="loginput" type="text" value=""><br>
                            <label asp-for="UserName" style="width: 80px" for="Username">Username*</label>
                            <input asp-for="UserName" class="loginput" type="text" value=""><br>
                            <span asp-validation-for="UserName"></span>
                            <label asp-for="Email" style="width: 80px" for="Email">Email*</label>
                            <input asp-for="Email" class="loginput" type="email" value=""><br>
                            <span asp-validation-for="Email"></span>
                            <label asp-for="Password" style="width: 80px" for="Password">Password*</label>
                            <input asp-for="Password" class="loginput" type="text" value="">
                            <span asp-validation-for="Password"></span>
                            <button type="submit" class="enter">Göndər</button><br>
                            <p><b>Qeyd:</b> Full Name hissədə ad və soyadınızı, Username hissədə yalnız ingilis hərflərilə max 12 simvol, Password hissəsində isə max 14 simvol(tərkibində rəqəm və kiçik hərif mütləqdir) yazılmalıdır.</p>
                        </form>
                    </div>
                </div>
                <div class="col-lg-4 col-md-4 col-sm-6 col-12">
    
                </div>
    
            </div>
        </div>
    </section>

    Why it always adds NULL to the database for companyId property though method assigns companyId to the argument Id in the action?

    Wednesday, June 26, 2019 8:45 PM

All replies

  • User-854763662 posted

    Hi FaridGN ,

    Where did you put the id of Company that passed from companylist view in your register view ?

    Did you make the breakpoint at the "post" request of RegisterPartner action to check if the id is passed correctly from the register view ?

    Try to make the following changes in AccountController 

            [HttpGet]
            [AllowAnonymous]
            public async Task<IActionResult> RegisterPartner(int Id)
            {
                RegisterViewModel pvModel = new RegisterViewModel();
                pvModel.Company = await _dbcontext.Company.SingleOrDefaultAsync(a => a.Id == Id);
                return View(pvModel);
            }
    
            [HttpPost]
            [AllowAnonymous]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> RegisterPartner(RegisterViewModel registerModel, int Id)
            {
                if (ModelState.IsValid)
                {
                    RegisterViewModel pvModel = new RegisterViewModel();
                    pvModel.Company = await _dbcontext.Company.SingleOrDefaultAsync(a => a.Id == Id);
    
                    ApplicationUser partnerUser = await _userManager.FindByEmailAsync(registerModel.Email);
    
                    if (partnerUser != null)
                    {
                        ModelState.AddModelError("", "This partner already exists");
                    }
                    else
                    {
                        partnerUser = new ApplicationUser
                        {
                            UserName = registerModel.UserName,
    Email = registerModel.Email,
    CompanyId = registerModel.Company.Id }; IdentityResult partnerResult = await _userManager.CreateAsync(partnerUser, registerModel.Password); if (partnerResult.Succeeded) { IdentityResult result = await _userManager.AddToRoleAsync(partnerUser, RoleType.Partner.ToString());
    if (result.Succeeded)
    {
    await _signInManager.SignInAsync(partnerUser, isPersistent: false);
    _dbcontext.AppUsers.Add(partnerUser);
    await _dbcontext.SaveChangesAsync();
    return RedirectToAction(nameof(AdminController.Admin), "Admin");
    } } AddErrors(partnerResult); } } return View(registerModel); }

    Register View

    @model Foroffer.Models.ViewModels.RegisterModel
    
    <section class="posts">
        <div class="post-container">
            <div class="row">
                <div class="col-lg-4 col-md-4 col-sm-6 col-12">
    
                </div>
                <div class="col-lg-4 col-md-4 col-sm-6 col-12">
                    <div class="register">
                        <form method="post" asp-action="RegisterAdmin" asp-controller="Account">
                            <div asp-validation-summary="ModelOnly"></div>
                            <input type="hidden" asp-for="Company.Id" />
                            <h6>Qeydiyyat</h6>
                            <label asp-for="FullName" style="width: 80px" for="Username">Full Name*</label>
                            <input asp-for="FullName" class="loginput" type="text" value=""><br>
                            <label asp-for="UserName" style="width: 80px" for="Username">Username*</label>
                            <input asp-for="UserName" class="loginput" type="text" value=""><br>
                            <span asp-validation-for="UserName"></span>
                            <label asp-for="Email" style="width: 80px" for="Email">Email*</label>
                            <input asp-for="Email" class="loginput" type="email" value=""><br>
                            <span asp-validation-for="Email"></span>
                            <label asp-for="Password" style="width: 80px" for="Password">Password*</label>
                            <input asp-for="Password" class="loginput" type="text" value="">
                            <span asp-validation-for="Password"></span>
                            <button type="submit" class="enter">Göndər</button><br>
                            <p><b>Qeyd:</b> Full Name hissədə ad və soyadınızı, Username hissədə yalnız ingilis hərflərilə max 12 simvol, Password hissəsində isə max 14 simvol(tərkibində rəqəm və kiçik hərif mütləqdir) yazılmalıdır.</p>
                        </form>
                    </div>
                </div>
                <div class="col-lg-4 col-md-4 col-sm-6 col-12">
    
                </div>
    
            </div>
        </div>
    </section>

    Best Regards ,

    Sherry

    Thursday, June 27, 2019 8:57 AM
  • User1255309776 posted

    Registration starts from CompanyList view when Register link is clicked for particular company.

    @model Foroffer.Models.ViewModels.CompanyModel

    <section class="buttonpanel"> <button class="addnew"><a asp-action="Postadd" asp-controller="Post">Create Post</a></button> <button class="addnew"><a asp-action="CreateComp" asp-controller="Admin">Create Company</a></button> </section> <table style="width:500px"> <tr> <th class="mytab">Company</th> <th class="mytab">VOEN</th> <th class="mytab">Logo</th> <th class="mytab">Address</th> <th class="mytab">Edit</th> <th class="mytab">Delete</th> <th class="mytab">Register</th> </tr> @foreach (Company item in Model.Companies) { <tr> <td class="mytab">@item.Name</td> <td class="mytab">@item.VOEN</td> <td class="mytab"><img src="~/images/@item.LogoPath"></td> <td class="mytab">@item.Address</td> <td class="mytab"><a asp-action="EditComp" asp-controller="Admin" asp-route-id="@item.Id">Edit</a></td> <td class="mytab"><a asp-action="DeleteComp" asp-controller="Admin" asp-route-id="@item.Id">Delete</a></td> <td class="mytab"><a asp-action="RegisterPartner" asp-controller="Account" asp-route-id="@item.Id">Register</a></td> </tr> } </table>

    After clicking on "Register", it takes relevant company's Id in register view, then I need to create Appuser in the "post" action like showed above, and insert this Id to CompanyId column of Appuser in the Database.

    Your above shown corrections I did, but it didn't work again.  Any other help?

    Thursday, June 27, 2019 8:10 PM
  • User475983607 posted

    I would added the UserId to the Company table if this is a one-to-one or one-to-many relationship.

    https://docs.microsoft.com/en-us/ef/core/modeling/relationships

    Thursday, June 27, 2019 8:41 PM