Reputation: 25
So I'm trying to create a register razor page in my index page using a modal. Most of the form code that I imported into the modal is from the existing external register page. When I start up the mvc app, though, I receive a Object reference not set to an instance of an object
error. Any help would be appreciated. Thanks!
Console:
System.NullReferenceException: Object reference not set to an instance of an object.at AspNetCore.Views_Home_Index.ExecuteAsync() in C:\Users\SalvadorSolis\source\repos\AWSCognitoMVC\AWSCognitoMVC\Views\Home\Index.cshtml:line 4
HTML:
@page
@model AWSCognitoMVC.Views.Home.IndexModel
@{
ViewData["Title"] = "Index";//line 4
}
<h2>@ViewData["Title"]</h2>
Model:
namespace AWSCognitoMVC.Views.Home
{
[AllowAnonymous]
public class IndexModel : PageModel
{
private readonly SignInManager<CognitoUser> _signInManager;
private readonly CognitoUserManager<CognitoUser> _userManager;
private readonly ILogger<IndexModel> _logger;
private readonly CognitoUserPool _pool;
public IndexModel(
UserManager<CognitoUser> userManager,
SignInManager<CognitoUser> signInManager,
ILogger<IndexModel> logger,
CognitoUserPool pool)
{
_userManager = userManager as CognitoUserManager<CognitoUser>;
_signInManager = signInManager;
_logger = logger;
_pool = pool;
}
[BindProperty]
public InputModel Input { get; set; }
public class InputModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(15, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 10)]
[Phone]
[Display(Name = "Phone Number")]
public string PhoneNumber { get; set; }
[Required]
[Display(Name = "User Name")]
public string UserName { 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; }
}
public void OnGet()
{
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
//Added because users don't usually add in a + in their phone number
if (!(Input.PhoneNumber.First() == '+'))
{
Input.PhoneNumber = "+" + Input.PhoneNumber;
}
//Added because users don't usually add in a + in their phone number
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid)
{
var user = _pool.GetUser(Input.UserName);
user.Attributes.Add(CognitoAttributesConstants.Email, Input.Email);
user.Attributes.Add(CognitoAttributesConstants.PreferredUsername, Input.UserName);
user.Attributes.Add(CognitoAttributesConstants.PhoneNumber, Input.PhoneNumber);
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToPage("./ConfirmAccount");
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
return Page();
}
}
}
HomeController:
namespace AWSCognitoMVC.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
Note: The original Register Model did not have the "Title" defined and somehow worked fine.
Upvotes: 1
Views: 10022
Reputation: 9642
You are trying to mix controller & view approach with razor pages. Just don't do it. If you want to use razor pages create Pages
folder in the root of the project and create your razor pages there. If you want to display razor page's view by /home/index
url create Home
folder in Pages
folder and add your IndexModel
there.
Pages\Home\Index.cshtml
Read more in the docs.
Upvotes: 9
Reputation: 28310
ViewData is a container to pass data from the PageModel to the content page.
So I guess it makes sense to set data on the PageModel side this way:
public class IndexModel : PageModel
{
[ViewData]
public string Title{ get; set; }
public void OnGet()
{
Title = "Index";
}
// ...
}
And then just get it this way:
<h2>@ViewData["Title"]</h2>
Upvotes: 1