locked
write extra fields to db RRS feed

  • Question

  • User1280950372 posted

    I have a .Net Core application in which I've created PhoneNumber and Email tables separate from the AspNetUser table for normalization sake (in other words, I anticipate having other types of users with phone and e-mail). In registering users, I want to their capture PhoneNumberId and EmailId from those tables and write them to AspNetUsers as foreign keys. However, I just can't wrap my head around how to write the phone and e-mail fields captured in the registration process to those other tables, and bring back the resulting IDs. Following is the relevant code so far in my Register method. Any ideas? Would Include statements be appropriate here? Thanks in advance.

    //
    		// GET: /Account/Register
    		[HttpGet]
    		[AllowAnonymous]
    		public IActionResult Register(string returnUrl = null)
    		{
    			ViewData["ReturnUrl"] = returnUrl;
    			return View();
    		}
    
    		//
    		// POST: /Account/Register
    		[HttpPost]
    		[AllowAnonymous]
    		[ValidateAntiForgeryToken]
    		public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
    		{
    			ViewData["ReturnUrl"] = returnUrl;
    			if (ModelState.IsValid)
    			{
    
    // write the phone and e-mail values to those tables
    
    					var user = new AppUser
    				{
    					UserName = model.Email,
    					FirstName = model.FirstName,
    					LastName = model.LastName,
    				};
    				var result = await _userManager.CreateAsync(user, model.Password);
    
    				if (result.Succeeded)
    				{
    					// For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=532713
    					// Send an email with this link
    					var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
    					var callbackUrl = Url.Action(nameof(ConfirmEmail), "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
    					//await _emailSender.SendEmailAsync(model.Email, "Confirm your account", $"Please confirm your account by clicking this link: <a href='{callbackUrl}'>link</a>");
    					await _signInManager.SignInAsync(user, isPersistent: false);
    					_logger.LogInformation(3, "User created a new account with password.");
    					return RedirectToLocal(returnUrl);
    				}
    				AddErrors(result);
    			}
    
    			// If we got this far, something failed, redisplay form
    			return View(model);
    		}

    Friday, August 11, 2017 11:18 PM

Answers

  • User1771544211 posted

    Hi muybn,

    I searched my project and found that I don't use "db,"

    The db should be an instance of the DbContext, you declare it according to your code like the following.

    YourDbContext db = new YourDbContext();

    in terms of the equivalent of "NewRecord" and "db" in my project?

    The NewRecord should be replaced with the Model in your project that maps the other tables. So you can use YourEmaiModel instead of NewRecord.

    Since I don't know your detail code, so I just show the general steps of doing it, you should modify the code based on your actual code.

    Best Regards,

    Jean

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 17, 2017 2:44 AM

All replies

  • User1120430333 posted

    I want to their capture PhoneNumberId and EmailId from those tables and write them to AspNetUsers as foreign keys. However, I just can't wrap my head around how to write the phone and e-mail fields captured in the registration process to those other tables, and bring back the resulting IDs

    If you don't have access and control of the source code for data persistence and you are calling DLL(s), then you have no control over it, putting it simply. You would have to roll/write your own persistence logic in order to do it and capture the ID(s).

    Saturday, August 12, 2017 12:53 AM
  • User1771544211 posted

    Hi muybn,

    However, I just can't wrap my head around how to write the phone and e-mail fields captured in the registration process to those other tables, and bring back the resulting IDs.

    You can first add these fields into the database and then query the database based on these fields value to get the id of the record.

    Since I don't know the details about your requirement, here is the main code:

    [HttpPost]
    		[AllowAnonymous]
    		[ValidateAntiForgeryToken]
    		public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
    		{
    			ViewData["ReturnUrl"] = returnUrl;
    			if (ModelState.IsValid)
    			{
    
                                   // write the phone and e-mail values to those tables
     
                                   //Create the newrecord based on the model's property
                                   var newrecord = new Record
                                   {
                                       Email = model.Email,
                                       ...
                                   };
    //check if the record is already added into the database
    if(db.NewRecord.Where(n=>n.Email == newrecord.Email && n.xxx == newrecord.xxx).Count() == 0)
    { //Insert the new record into database db.NewRecord.Add(newrecord); db.SaveChanges();
    } //get the id of the new record int id = db.NewRecord.Where(n=>n.Email == newrecord.Email && n.xxx == newrecord.xxx).FirstOrDefault().ID; //Then you can assign the id to the related field in the ASPUser model var user = new AppUser { UserName = model.Email, FirstName = model.FirstName, LastName = model.LastName, }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=532713 // Send an email with this link var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); var callbackUrl = Url.Action(nameof(ConfirmEmail), "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme); //await _emailSender.SendEmailAsync(model.Email, "Confirm your account", $"Please confirm your account by clicking this link: <a href='{callbackUrl}'>link</a>"); await _signInManager.SignInAsync(user, isPersistent: false); _logger.LogInformation(3, "User created a new account with password."); return RedirectToLocal(returnUrl); } AddErrors(result); } // If we got this far, something failed, redisplay form return View(model); }

    Best Regards,

    Jean

    Monday, August 14, 2017 6:38 AM
  • User1280950372 posted

    You can first add these fields into the database and then query the database based on these fields value to get the id of the record.

    Since I don't know the details about your requirement, here is the main code:

    [HttpPost]
    		[AllowAnonymous]
    		[ValidateAntiForgeryToken]
    		public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
    		{
    			ViewData["ReturnUrl"] = returnUrl;
    			if (ModelState.IsValid)
    			{
    
                                   // write the phone and e-mail values to those tables
     
                                   //Create the newrecord based on the model's property
                                   var newrecord = new Record
                                   {
                                       Email = model.Email,
                                       ...
                                   };
                                   //check if the record is already added into the database
                                   if(db.NewRecord.Where(n=>n.Email == newrecord.Email && n.xxx == newrecord.xxx).Count() == 0)
                                   {
                                       //Insert the new record into database
                                       db.NewRecord.Add(newrecord);
                                       db.SaveChanges();
                                    }
                                            
                                   //get the id of the new record
                                   int id = db.NewRecord.Where(n=>n.Email == newrecord.Email && n.xxx == newrecord.xxx).FirstOrDefault().ID;
    
                                   //Then you can assign the id to the related field in the ASPUser model                                
    
    				var user = new AppUser
    				{
    					UserName = model.Email,
    					FirstName = model.FirstName,
    					LastName = model.LastName,
    				};
    				var result = await _userManager.CreateAsync(user, model.Password);
    
    				if (result.Succeeded)
    				{
                                                                                      
    					// For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=532713
    					// Send an email with this link
    					var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
    					var callbackUrl = Url.Action(nameof(ConfirmEmail), "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
    					//await _emailSender.SendEmailAsync(model.Email, "Confirm your account", $"Please confirm your account by clicking this link: <a href='{callbackUrl}'>link</a>");
    					await _signInManager.SignInAsync(user, isPersistent: false);
    					_logger.LogInformation(3, "User created a new account with password.");
    					return RedirectToLocal(returnUrl);
    				}
    				AddErrors(result);
    			}
    
    			// If we got this far, something failed, redisplay form
    			return View(model);
    		}

    Is your example above intending to write to the e-mail and phone tables? I'm not sure what "new Record" and "NewRecord" refer to or how they are supposed to access the e-mail and phone tables.

    Monday, August 14, 2017 4:09 PM
  • User1771544211 posted

    Hi muybn,

    Is your example above intending to write to the e-mail and phone tables? I'm not sure what "new Record" and "NewRecord" refer to or how they are supposed to access the e-mail and phone tables.

    The NewRecord is the model of the data that you want to write into the datatable.

    The above code use Entity Framework to insert data into database. The following link shows an overview of Entity Framework, please take it as reference.

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

    Best Regards,

    Jean

    Tuesday, August 15, 2017 6:41 AM
  • User1280950372 posted

    Thanks for your time, Jean. I am using EF and do fine with the standard stuff for the User table (UserName, FirstName, LastName), but the extra items to go to the other tables (Email and PhoneNumber) are giving me fits. I get errors on "NewRecord" and "db" as written, so obviously I am missing something and possibly need to give you more information on what I have established previously.  (I searched my project and found that I don't use "db," so if I am using the same concept elsewhere, it has a different name.) What else do you need to know, in terms of the equivalent of "NewRecord" and "db" in my project? Just trying to figure out where I would get those items...

    Wednesday, August 16, 2017 8:57 PM
  • User1771544211 posted

    Hi muybn,

    I searched my project and found that I don't use "db,"

    The db should be an instance of the DbContext, you declare it according to your code like the following.

    YourDbContext db = new YourDbContext();

    in terms of the equivalent of "NewRecord" and "db" in my project?

    The NewRecord should be replaced with the Model in your project that maps the other tables. So you can use YourEmaiModel instead of NewRecord.

    Since I don't know your detail code, so I just show the general steps of doing it, you should modify the code based on your actual code.

    Best Regards,

    Jean

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 17, 2017 2:44 AM
  • User1280950372 posted

    OK thanks. I'm kind of thick and too literal sometimes. I actually use a context factory. I'll try to incorporate what you've said and let you know how it works out.

    Would ".include" statements be applicable or work here? This is something that intrigues me and which I've never used yet.

    Thursday, August 17, 2017 4:34 PM
  • User1771544211 posted

    Hi muybn,

    Would ".include" statements be applicable or work here? This is something that intrigues me and which I've never used yet.

    The "include" statements is used to load related data in EF, you can use the include statements wherever you need.

    Best Regards,

    Jean

    Friday, August 18, 2017 5:48 AM
  • User1280950372 posted

    Your suggestion works with some tweaking, so I will mark it as the answer. However, I've decided to not have separate e-mail and phone tables since Identity requires those elements and it would be too complicated to change from the standard Identity configuration.

    Tuesday, August 29, 2017 10:47 PM
  • User1280950372 posted

    [deleted]

    Tuesday, August 29, 2017 10:56 PM