I have been trying to find a solution to this online such as here and here. But they don't seem to help me as it appears that my GET is not updating my view model on page load, whereas those offer an explanation around the POST behaviour.
How are the original values still in the viewModel when the user has navigated completely off the page. I have also tried clearing the browser cache and the original values are still loading.
I would like a clean load every time the user lands on the page.
I am getting the users first name and last name from the Database in my controller.
My Controller Action:
public class CreateArticleController : Controller
{
private static readonly ApplicationDbContext _context = new();
public IActionResult CreateArticle()
{
ModelState.Clear();
CreateArticlePageLocSourceNames _locSourceCreateArticlePageNameReferenceLibrary = new CreateArticlePageLocSourceNames();
var viewModel = new CreateArticleViewModel
{
PageTabTitle = _locSourceCreateArticlePageNameReferenceLibrary.GetLocSourcePageTabTitleNameReferenceForCreateArticlePage(),
Title = _locSourceCreateArticlePageNameReferenceLibrary.GetLocSourceTitleNameReferenceForCreateArticlePage()
//Other viewModel values are also being populated here
};
var user = User.GetUserId<string>();
var userDetails = _context.Users.Find(user);
if (userDetails.FirstName != null)
{
viewModel.UserFirstName = userDetails.FirstName.ToString();
Debug.WriteLine("************* UserFirstName: " viewModel.UserFirstName);
} else
{
viewModel.UserFirstName = null;
Debug.WriteLine("************* UserFirstName IS NULL");
}
if (userDetails.LastName != null)
{
viewModel.UserLastName = userDetails.LastName.ToString();
Debug.WriteLine("************* UserLastName: " viewModel.UserLastName);
}
else
{
viewModel.UserLastName = null;
Debug.WriteLine("************* UserLastName IS NULL");
}
return View(viewModel);
}
}
Then I am checking in the view if the first and last names have values. If they do, I use them and if they do not, I show an error message.
@if (Model.UserFirstName == "" || Model.UserFirstName == null || Model.UserLastName == "" || Model.UserLastName == null)
{
<p id="CreateArticleCardAuthor">@_loc[Model.AddName]</p>
}
else
{
<p id="CreateArticleCardAuthor">@_loc[Model.Author]: @Model.UserFirstName @Model.UserLastName</p>
}
Expected Behaviour:
- Page loads and user does not have a first name in the database
viewModel.UserFirstName
is null- User sees
<p id="CreateArticleCardAuthor">@_loc[Model.AddName]</p>
error message - User navigates to a different settings page and adds their first name to the database
- User navigates back to original page
- On page load
viewModel.UserFirstName
is populated from the database <p id="CreateArticleCardAuthor">@_loc[Model.Author]: @Model.UserFirstName @Model.UserLastName</p>
is used- User no longer sees error
Actual Behaviour:
- Page loads and user does not have a first name in the database
viewModel.UserFirstName
is null- User sees
<p id="CreateArticleCardAuthor">@_loc[Model.AddName]</p>
error message - User navigates to a different settings page and adds their first name to the database
- User navigates back to original page
- On page load
viewModel.UserFirstName
is still null <p id="CreateArticleCardAuthor">@_loc[Model.AddName]</p>
is still used- User still sees the error
CodePudding user response:
private static readonly ApplicationDbContext _context = new();
Should not have the DBContect as a static object. Because it never picks up some of the changes unless you reload it. It will stay alive across http requests. Configure Dependency Injection to create a single ApplicationDbContext object when http request comes in.
In the Startup
class, in the ConfigureServices
method write:
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyProjectContext")));
Here the 'MyProjectContext' is the name of the connection string in your appsettings.json file.
Then in the controller class:
public class CreateArticleController : Controller
{
private ApplicationDbContext _context;
public CreateArticle(IApplicationDbContext context)
{
_context = context;
}
public IActionResult CreateArticle()
{
// Your codes ...
}
}
For the above code to work your ApplicationDbContext
needs to inherit an interface (can be empty) for DI to work. Like this:
public class ApplicationDbContext : DbContext, IApplicationDbContext
This question is not about DI (Dependency Injection) so I have not covered sample codes related to that. You can google and learn about DI and EF DBContext.
Update 22/12/2021:
The IApplicationDbContext
is an interface that you have to implement for the DI (which is an empty interface at the moment). Then you will get an object in your controller automatically. i.e. you do not have to create it with a new()
key word.