Let's suppose I have 2 repositories:
first is responsible for creating job and return jobId
second is responsible for creating log and take jobId as argument
My goal is to:
save Job and Log simultaneously
prevent situation when in case of error only Job would be saved without Log
What is the most recommended way to get desired result?
I prepared 3 cases which came to my mind but if you see better alternative please share it.
option 1 (getting result and save changes in controller)
public class JobRepository : IJobRepository
{
private readonly Context _context;
public JobRepository(Context context)
{
_context = context;
}
public Guid CreateJob()
{
var job = new Job { Id = Guid.NewGuid() };
_context.Jobs.Add(job);
return job.Id;
}
}
// ...
public class LogRepository : ILogRepository
{
private readonly Context _context;
public LogRepository(Context context)
{
_context = context;
}
public void CreateLog(Guid id)
{
var log = new Log { Jobid = id };
_context.Logs.Add(log);
}
}
// ...
public class JobsController : Controller
{
private readonly Context _context;
private readonly IJobRepository _jobRepository;
private readonly ILogRepository _logRepository;
public JobsController(Context context, JobRepository jobRepository, ILogRepository logRepository)
{
_context = context;
_jobRepository = jobRepository;
_logRepository = logRepository
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create()
{
var id = _jobRepository.CreateJob();
_logRepository.CreateLog(id);
_context.SaveChanges();
return RedirectToAction("Index");
}
}
option 2 (inject one repository into another)
public class JobRepository : IJobRepository
{
private readonly Context _context;
private readonly ILogRepository _logRepository;
public JobRepository(Context context, ILogRepository logRepository)
{
_context = context;
}
public void CreateJob()
{
var job = new Job { Id = Guid.NewGuid() };
_context.Jobs.Add(job);
_logRepository.CreateLog(job.Id);
_context.SaveChanges();
}
}
// ...
public class LogRepository : ILogRepository
{
private readonly Context _context;
public LogRepository(Context context)
{
_context = context;
}
public void CreateLog(Guid id)
{
var log = new Log { Jobid = id };
_context.Logs.Add(log);
}
}
// ...
public class JobsController : Controller
{
private readonly IJobRepository _jobRepository;
public JobsController(JobRepository jobRepository)
{
_jobRepository = jobRepository;
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create()
{
_jobRepository.CreateJob();
return RedirectToAction("Index");
}
}
option 3 (do not use context in controller but declare Save method in each repo)
public class JobRepository : IJobRepository
{
private readonly Context _context;
public JobRepository(Context context)
{
_context = context;
}
public Guid CreateJob()
{
var job = new Job { Id = Guid.NewGuid() };
_context.Jobs.Add(job);
return job.Id;
}
public void Save()
{
_context.SaveChanges();
}
}
// ...
public class LogRepository : ILogRepository
{
private readonly Context _context;
public LogRepository(Context context)
{
_context = context;
}
public void CreateLog(Guid id)
{
var log = new Log { Jobid = id };
_context.Logs.Add(log);
}
public void Save()
{
_context.SaveChanges();
}
}
// ...
public class JobsController : Controller
{
private readonly IJobRepository _jobRepository;
private readonly ILogRepository _logRepository;
public JobsController(JobRepository jobRepository, ILogRepository logRepository)
{
_jobRepository = jobRepository;
_logRepository = logRepository
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create()
{
var id = _jobRepository.CreateJob();
_logRepository.CreateLog(id);
return RedirectToAction("Index");
}
}
As the use case suggests that the operations (saving and logging) should happen as a single unit of work.
I would suggest an approach similar to the third one. But instead of directly injecting both the repositories into the controller. We could create a service that would then make use of the repositories.
Here we can create a service as follows :
public class JobService : IJobService
{
private readonly IJobRepository _jobRepo;
private readonly ILogRepository _logRepo;
public JobRepository(IJobRepository jobRepo, ILogRepository logRepo)
{
_jobRepo = jobRepo;
_logRepo = logRepo;
}
public void CreateJob()
{
var id = _jobRepo.CreateJob();
_logRepo.CreateLog(id);
}
}
public class JobsController : Controller
{
private readonly IJobService _jobService;
public JobsController(IJobService jobService)
{
_jobService = jobService;
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create()
{
_jobService.CreateJob();
return RedirectToAction("Index");
}
}
Additional Reading : The Repository-Service pattern
Related
I would like to cache date from one table, and return it when user do request to this table. I created class like this:
public interface ICategoryCache
{
IEnumerable<Category> GetCategories();
}
public class CategoryCache : ICategoryCache
{
private IEnumerable<Category> _categories;
public CategoryCache(ItBuildsDbContext context)
{
_categories = context.Category.ToList();
}
public IEnumerable<Category> GetCategories()
{
return _categories;
}
}
I wanted to add dependency injection as Singleton, but class which have to use this object is Scoped (and it throw error: Cannot consume scoped service). How should I do it properly? I am not able to change Scoped class to Singleton.
Should I for example create Factory which will create my Singleton object CategoryCache?
My solution for this problem which work:
public class CategoryCache
{
private readonly IEnumerable<Category> _categories;
private static CategoryCache? _categoryCache;
private CategoryCache(ItBuildsDbContext context)
{
_categories = context.Category.ToList();
}
public static CategoryCache Create(ItBuildsDbContext context)
{
if(_categoryCache == null)
{
_categoryCache = new CategoryCache(context);
}
return _categoryCache;
}
public IEnumerable<Category> GetCategories()
{
return _categories!;
}
}
public interface IFactoryCategoryCache
{
CategoryCache Create();
}
public class FactoryCategoryCache : IFactoryCategoryCache
{
private readonly ItBuildsDbContext _context;
public FactoryCategoryCache(ItBuildsDbContext context)
{
_context = context;
}
public CategoryCache Create()
{
return CategoryCache.Create(_context);
}
}
service.AddScoped<IFactoryCategoryCache, FactoryCategoryCache>();
But is there a better solution here?
You are maybe doing something wrong, because it is possible to inject a singleton in a scoped service.
Example:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ICategoryCache>(new CategoryCache(new List<string> { "Category 1", "Category 2", "Category 3" }));
builder.Services.AddScoped<ScopedTestService>();
var app = builder.Build();
public interface ICategoryCache
{
IEnumerable<string> GetCategories();
}
public class CategoryCache : ICategoryCache
{
private IEnumerable<string> _categories;
public CategoryCache(IEnumerable<string> context)
{
_categories = context;
}
public IEnumerable<string> GetCategories()
{
return _categories;
}
}
public class ScopedTestService
{
private readonly ICategoryCache _categoryCache;
public ScopedTestService(ICategoryCache categoryCache)
{
_categoryCache = categoryCache;
}
public IEnumerable<string> GetCategories()
{
return _categoryCache.GetCategories();
}
}
You are getting the error because the default lifetime of the dbcontext is Scoped,and you injected it to the Singleton Service
If you just cache date from one table and don't modify the data at any time,you could set as below:
services.AddDbContext<ServicelifetimeContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString(".....")), ServiceLifetime.Singleton);
Update:
You may try with DbContextFactory for your requirement
in startup:
services.AddDbContextFactory<ServicelifetimeContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ServicelifetimeContext")));
in different services:
public CategoryCache(IDbContextFactory<ServicelifetimeContext> contextFactory)
{
_mymodels = contextFactory.CreateDbContext().Mymodel.ToList();
}
I tried in a MVC project:
public MymodelsController(IDbContextFactory<ServicelifetimeContext> contextFactory, ICategoryCache categoryCache)
{
_context = contextFactory.CreateDbContext();
_categoryCache = categoryCache;
}
// GET: Mymodels
public IActionResult Index()
{
return View(_categoryCache.GetMymodels());
}
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var mymodel = await _context.Mymodel.FindAsync(id);
if (mymodel == null)
{
return NotFound();
}
return View(mymodel);
}
Result:
Now you could get the context with different lifetime
In ASP.NET Core-6 application, I am implementing Recurring Job using HangFire.
I have a 3rd party api (JSON) to be consumed and inserted into the database 2am daily.
API:
"https://api.thirdpartycompany.com:2233/api/BranchDetail"
In appsettings.json I have:
"Endpoints": {
"branchUrl": "https://api.thirdpartycompany.com:2233/api/BranchDetail"
}
API:
{
"Branches": [
{
"BranchName": "Accra",
"BranchNumber": 1,
"Country": "Ghana"
},
{
"BranchName": "Kumasi",
"BranchNumber": 2,
"Country": "Ghana"
},
...
}
The core is as shown below:
Entity:
public class Branch
{
public int Id { get; set; }
public string BranchName { get; set; }
public int BranchNumber { get; set; }
}
DTO:
public class BranchCreateUpdateDto
{
public string BranchName { get; set; }
public int BranchNumber { get; set; }
}
public class BranchResponse
{
public List<BranchCreateUpdateDto> Branches
{
get;
set;
}
}
BaseResponse:
public class BaseResponse
{
public bool Success { get; set; } = true;
public string Message { get; set; }
}
Mapping:
public class AdminMapperProfile: Profile
{
public AdminMapperProfile()
{
CreateMap<BranchCreateUpdateDto, Branch>().ReverseMap();
}
}
Repository:
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private readonly ApplicationDbContext _dbContext;
private readonly DbSet<T> _dbSet;
public GenericRepository(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
_dbSet = _dbContext.Set<T>();
}
public async Task InsertAsync(T entity)
{
await _dbSet.AddAsync(entity);
}
public T GetById(string id)
{
return _dbSet.Find(id);
}
public void Update(T entity)
{
_dbContext.Set<T>().Update(entity);
}
}
Interface:
public interface IAdminBranchRepository : IGenericRepository<Branch>
{
}
Implementation:
public class AdminBranchRepository : GenericRepository<Branch>, IAdminBranchRepository
{
private readonly ApplicationDbContext _dbContext;
private readonly DbSet<Branch> _branches;
public AdminBranchRepository(ApplicationDbContext dbContext) : base(dbContext)
{
_dbContext = dbContext;
_branches = _dbContext.Set<Branch>();
}
}
IUnitOfWork:
public interface IUnitOfWork : IDisposable
{
IAdminBranchRepository Branches { get; }
Task Save();
}
UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
private readonly ApplicationDbContext _dbContext;
private IAdminBranchRepository _branches;
public UnitOfWork(
ApplicationDbContext dbContext,
)
{
_dbContext = dbContext;
}
public IAdminBranchRepository Branches => _branches ??= new AdminBranchRepository(_dbContext);
public async Task Save()
{
await _dbContext.SaveChangesAsync();
}
}
Service:
Interface:
Task<BaseResponse> CreateBranchAsync();
Implementation:
public class AdminBranchService : IAdminBranchService
{
private readonly ApplicationDbContext _dbContext;
private readonly IMapper _mapper;
private readonly IUnitOfWork _unitOfWork;
private readonly ILogger _logger;
private readonly IConfiguration _config;
private readonly HttpClient _myClient;
public AdminBranchService(
ApplicationDbContext dbContext,
IUnitOfWork unitOfWork,
ILogger logger,
IMapper mapper,
IConfiguration config,
HttpClient myClient
)
{
_dbContext = dbContext;
_mapper = mapper;
_unitOfWork = unitOfWork;
_logger = logger;
_config = config;
_myClient = myClient;
}
public async Task<BaseResponse> CreateBranchAsync()
{
var branchResponse = new BaseResponse();
var branches = new List<Branch>();
try
{
string branchUrl = _config.GetSection("Endpoints").GetValue<string>("branchUrl");
_myClient.DefaultRequestHeaders.Accept.Clear();
_myClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = _myClient.GetAsync(branchUrl).Result;
var stringResult = response.Content.ReadAsStringAsync().Result;
BranchResponse list = JsonConvert.DeserializeObject<BranchResponse>(stringResult);
foreach (var singleBranch in list.Branches)
{
Branch res = new Branch();
if (_dbContext.Branches.Any(x => x.BranchName == singleBranch.BranchName))
{
res.BranchNumber = singleBranch.BranchNumber;
_unitOfWork.Branches.Update(res);
}
else
{
//set all fields here
res.BranchName = singleBranch.BranchName;
res.BranchNumber = singleBranch.BranchNumber;
await _unitOfWork.Branches.InsertAsync(res);
}
await _unitOfWork.Save();
}
_logger.Information("Branches Added Successfully");
}
catch (Exception ex)
{
_logger.Error("An Error occured " + ex.ToString());
}
return branchResponse;
}
}
ConnectionConfiguration:
public static class ConnectionConfiguration
{
public static void AddDbContextAndConfigurations(this IServiceCollection services, IWebHostEnvironment env, IConfiguration config)
{
services.AddDbContextPool<ApplicationDbContext>(options =>
{
string connStr;
connStr = config.GetConnectionString("DefaultConnection");
options.UseSqlServer(connStr);
});
}
}
HangFireServiceExtension:
public static class HangFireServiceExtension
{
public static void AddHangFireConfigurations(this IServiceCollection services, IConfiguration config)
{
string connStr;
connStr = config.GetConnectionString("DefaultConnection");
services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(connStr, new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true
}));
services.AddHangfireServer();
}
}
Program.cs:
builder.Services.ConfigureAutoMappers();
// Db Injection
builder.Services.AddDbContextAndConfigurations(environment, configuration);
// HangFire
builder.Services.AddHangFireConfigurations(configuration);
app.UseHangfireDashboard();
RecurringJob.AddOrUpdate<IAdminBranchService>("Post_All_Branches", service => service.CreateBranchAsync(),
Cron.Daily(2, 0), TimeZoneInfo.Local);
What I want to achieve is that by every 2am daily the recurring job should run. It should insert fresh records and update existing ones.
However, on the third day of deployment, no record is found in the database. The HangFire RecurringJob is not running.
Where have I missed it, and how do I correct this?
Thank you
I have Home / Index where show list of Current Tasks, Completed Tasks and form for creating new task.
I created HomeIndexViewModel for pass models (Completed tasks, Current Tasks and TaskCreateViewModel for form) to Index View and there call (#Model.CompletedTasks, #Model.CurrentTasks and #Model.FormCreate)
But in CreatedTaskViewModel I want to get information about validation errors and render them in View. I init in Controller HomeIndexViewModel and get access from Index(Action) and Create(Action).
Approach worked, but I am not sure what it's good idea.
public class HomeIndexViewModel
{
public List<TaskModel> CompletedTasks { get; set; } = new List<TaskModel>();
public List<TaskModel> CurrentTasks { get; set; } = new List<TaskModel>();
public CreateTaskViewModel FormCreate { get; set; } = new CreateTaskViewModel();
}
public class HomeController : Controller
{
private readonly ITaskRepository _taskRepository;
private HomeIndexViewModel homeIndexViewModel;
public HomeController(IConfiguration configuration)
{
_taskRepository = new TaskRepository(configuration.GetConnectionString("AppDB"));
homeIndexViewModel = new HomeIndexViewModel()
{
CompletedTasks = _taskRepository.GetList("completed");
CurrentTasks = _taskRepository.GetList("current");
};
public ActionResult Index()
{
return View(homeIndexViewModel);
}
public ActionResult Create(CreateTaskViewModel task)
{
if (ModelState.IsValid)
{
_taskRepository.Create(task);
}
return View(nameof(Index), homeIndexViewModel);
}
I think you could write a service and inject it to your controller:
public interface ISomeService
{
public HomeIndexViewModel GetHomeIndexViewModel(IConfiguration configuration, ITaskRepository taskRepository)
{
//some codes
HomeIndexViewModel homeIndexView = new HomeIndexViewModel()
{
//some codes
};
return homeIndexView;
}
}
public class SomeService : ISomeService
{
public HomeIndexViewModel GetHomeIndexViewModel(IConfiguration configuration, ITaskRepository taskRepository)
{
//some codes
HomeIndexViewModel homeIndexView = new HomeIndexViewModel()
{
//some codes
};
return homeIndexView;
}
}
In your Startup Class:
public void ConfigureServices(IServiceCollection services)
{
.....
services.AddTransient<ISomeService, SomeService>();
.....
}
In your Controller:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly ISomeService _someService;
private readonly ITaskRepository _taskRepository;
private readonly IConfiguration _configuration;
public HomeController(ILogger<HomeController> logger, ISomeService someService, ITaskRepository taskRepository, IConfiguration configuration)
{
_logger = logger;
_someService = someService;
_taskRepository = taskRepository;
_configuration = configuration;
}
public IActionResult Index()
{
var homeindexviewmodel = _someService.GetHomeIndexViewModel(_configuration,_taskRepository);
//you could get the homeindexviewmodel in other controllers with the same method
return View();
}
}
I am receiving null exception error on my framework. I have tried to apply Repository and Unit of Work design patterns in my application. What I am trying to do is simply retreiving user titles from my data base with GetAll() method.
Here is my repository class:
public class Repository<T> : IRepository<T> where T : class
{
protected readonly DbContext Context;
public Repository(DbContext context)
{
this.Context = context;
}
public T Get(int id)
{
return Context.Set<T>().Find(id);
}
public IEnumerable<T> GetAll()
{
return Context.Set<T>().ToList();
}
public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)
{
return Context.Set<T>().Where(predicate);
}
public void Add(T entity)
{
Context.Set<T>().Add(entity);
}
public void AddRange(IEnumerable<T> entityList)
{
Context.Set<T>().AddRange(entityList);
}
public void Remove(T entity)
{
Context.Set<T>().Remove(entity);
}
public void RemoveRange(IEnumerable<T> entityList)
{
Context.Set<T>().RemoveRange(entityList);
}
}
This is IUserTitlesRepository:
public interface IUserTitlesRepository : IRepository<UserTitles>
{
}
And, the class where above interface implemented:
public UserTitlesRepository(XaPaDataContext context) : base(context)
{
}
public XaPaDataContext XaPaDataContext
{
get { return Context as XaPaDataContext; }
}
Before coming to Controller layer, I have two more layers, which are Operation and Manager layers. And, I think I have messed up on that part (on Base Manager class as shown below).
This is operation layer:
public class UserTitlesOperations
{
private readonly IUnitOfWork _uow;
public UserTitlesOperations(IUnitOfWork uow)
{
_uow = uow;
}
public List<UserTitles> GetAllUserTitles()
{
try
{
List<UserTitles> userTitleList = _uow.UserTitles.GetAll().ToList();
_uow.Complete();
return userTitleList;
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}
}
Below is the BaseManager class which gives inheritance to all manager classes.
public abstract class BaseManager
{
private IUnitOfWork _iUow;
private readonly XaPaDataContext _context;
public IUnitOfWork IUOW
{
get
{
if (_iUow == null)
{
_iUow = new XaPaUnitOfWork(_context);
}
return _iUow;
}
}
}
This is the manager class:
public class UserTitlesManager : BaseManager
{
private readonly UserTitlesOperations _userTitlesOperations;
public UserTitlesManager()
{
_userTitlesOperations = new UserTitlesOperations(base.IUOW);
}
public List<UserTitlesWM> GetAllUserTitles()
{
try
{
return UserTitlesMapping.MaptoWM(_userTitlesOperations.GetAllUserTitles());
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}
}
Finally, this is my API Controller:
[Route("api/LoginRequest")]
public class TitlesController : BaseController
{
UserTitlesManager _userTitlesManager;
public LoginController()
{
_userTitlesManager = new UserTitlesManager();
}
[Route("RetreiveTitles")]
public HttpResponseMessage GetTitles()
{
try
{
return Request.CreateResponse(HttpStatusCode.OK, _userTitlesManager.GetAllUserTitles());
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.ToString());
}
}
}
By the way BaseController is just another API controller which gives inheritance to all other API controllers, and houses a method which is used by all the other controllers.
So, I'm still trying to sharpen my self on this design patterns and would be glad if anyone could show my mistake on BaseManager class. As I said, I suppose the problem is caused by that private readonly XaPaDataContext _context; line. On the other hand,I can't figure out how to corrrect it as my operation classes' constructors are asking for IUnitOfWork.
Thank you in advance!
EDIT:
Just realized that I forgot to share my Unit of Work class:
public class XaPaUnitOfWork : IUnitOfWork
{
private readonly XaPaDataContext _context;
public XaPaUnitOfWork(XaPaDataContext context)
{
_context = context;
Categories = new CategoriesRepository(_context);
OrderDetails = new OrderDetailsRepository(_context);
Orders = new OrdersRepository(_context);
ProductImages = new ProductImagesRepository(_context);
Products = new ProductsRepository(_context);
Users = new UsersRepository(_context);
UserTitles = new UserTitlesRepository(_context);
UserTokens = new UserTokensRepository(_context);
}
public ICategoriesRepository Categories { get; private set; }
public IOrderDetailsRepository OrderDetails { get; private set; }
public IOrdersRepository Orders { get; private set; }
public IProductImagesRepository ProductImages { get; private set; }
public IProductsRepository Products { get; private set; }
public IUsersRepository Users { get; private set; }
public IUserTitlesRepository UserTitles { get; private set; }
public IUserTokensRepository UserTokens { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
After I have changed my BaseManager class as below:
public abstract class BaseManager
{
private IUnitOfWork _iUow;
public IUnitOfWork IUOW
{
get
{
if (_iUow == null)
{
_iUow = new XaPaUnitOfWork(new XaPaDataContext());
}
return _iUow;
}
}
}
I have achived to receive HttpStatusCode.OK
But, honestly, I'm still unsure about the real reason. I make this correction mostly by heart.
I have an action in HomeController with Dependency Injecttion in Asp.Net Core 2.1.0 Razor Page.
Action Code
private readonly Test.Data.MyContext _Context;
public HomeController(Test.Data.MyContext context)
{ _Context = context; }
[HttpGet]
public ActionResult TypeofAccounts(string at)
{
var result = _Context.TypeOfAccounts
.Where(x => x.AccountType == at)
.Select(x =>
new
{
label = x.AccountType,
id = x.AccountType
}
);
return Json(result);
}
I would like use this result in various Razor PageModel. How can I achieve. Here is sample Razor Page.
public class IndexModel : PageModel
{
private readonly Test.Data.MyContext _Context;
public IndexModel(Test.Data.MyContext context)
{ _Context = context; }
public void OnGet()
{
// Here I want bind HomeController's action.
}
}
I tried with var ta = new Test.Controllers.HomeController().TypeofAccounts("B001"); but no luck.
Though I am not familiar of the practice having an instance of your data context in both view model and controller, you can try this way.
Controller:
private readonly Test.Data.MyContext _Context;
public HomeController(Test.Data.MyContext context)
{ _Context = context; }
[HttpGet]
public ActionResult TypeofAccounts(string at)
{
var result = GetTypeOfAccounts(_Context, at);
return Json(result);
}
public static IQueryable<dynamic> GetTypeOfAccounts(Test.Data.MyContext context, string at)
{
var result = context.TypeOfAccounts
.Where(x => x.AccountType == at)
.Select(x =>
new
{
label = x.AccountType,
id = x.AccountType
}
);
return result;
}
View Model:
public class IndexModel : PageModel
{
private readonly Test.Data.MyContext _Context;
public IndexModel(Test.Data.MyContext context)
{ _Context = context; }
public void OnGet()
{
// Here I want bind HomeController's action.
var ta = Test.Controllers.HomeController.GetTypeOfAccounts(_Context, "B001");
}
}