I had tried to separate DAL and inject it to DI in Program.cs like below
services.AddScoped<IDataLoadServices, DataLoadServices>();
Then to get data from DB and put it into Model (maybe can call it ViewModel) I need to get these services from the constructor of Model class like below
class MyModel{
public IList Countries{get;set;}
public int SelectedCountryCode{get;set;
//default Ctor
//call When creating by Model Binding
public MyModel(){
}
//call when creating by Factory
[ActivatorUtilitiesConstructor]
public MyModel(IDataLoadServices ser){
Countries = ser.LoadMyListFromDB();
}
}
In Controller Action I can create a MyModel instance by using FactoryServices.(not shown here) after that passing to View successfully.
@model MyModel
<form method="post" asp-controller="MyController">
...
<select asp-for="SelectedCountryCode" asp-items="@(new SelectList(Model.Countries, "CountryCode", "CountryName"))">
</select>
<input type="hidden" asp-for="SelectedCountryCode" />
...
In Controller Action for post-Submit
[HttpsPost]
public IActionResult Submited(MyModel model){
//model.Countries == null
//model.SelectedCountryCode == 0 ????
}
The problem I think that is MyModel was created in Model Binding Stage with Default Contructor so that It cant get Countries list and somehow can't resolve SelectedCountryCode.
- Is that Right ?
- Any idea for bypassing this problem ?
CodePudding user response:
Most of the data your views display should be passed in from the controller. I would keep the model as bare as possible. Instead, inject the IDataLoadServices
into the controller.
public class WorldController : Controller
{
private readonly IDataLoadServices _service;
public WorldController(IDataLoadServices service)
{
_service = service
}
}
Check out the docs on this. Dependency injection into controllers in ASP.NET Core
CodePudding user response:
Is that Right ? --> It could be, but you could remove that default ctor from the model. Cause it will be created by default.
Any idea for bypassing this problem ? --> There are many ways to do this.
- You can load the list of Countries in the startup.cs class using Options pattern (say you have a class with country code and country name) and then use that class inside the model constructor. Option Pattern
- Inject the IDataLoadServices in the controller class constructor.