I am working on .net core porject. My Project structure has 4 projects.
I have implemented Entity Framework core. And try to using Usermanager for insert data. Now when I am calling method "CreateAsync" from controller(Student_Web) it works fine and user inserted. But I want to implement database operation in Student_Service. So when I am calling "CreateAsync" from UserService it gives me error "Cannot access a disposed object.\r\nObject name: 'UserManager`1"
I am calling this interface IUserService from controller. So here is my code in UserService.
Please help me to solve this.
public class UserService : IUserService
{
#region Properties
private readonly IDbContext _context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<IdentityRole<int>> _roleManager;
#endregion
#region Consturctor
public UserService(
IDbContext context
, UserManager<ApplicationUser> userManager
, RoleManager<IdentityRole<int>> roleManager
{
_context = context;
_userManager = userManager;
_roleManager = roleManager;
}
#endregion
#region Methods
public async Task<bool> Create(NewUsers model)
{
bool result = false;
try
{
var user = await _userManager.FindByNameAsync(model.UserName);
if (user == null)
{
model.Password = GeneratePassword();
user = new ApplicationUser
{
//Id = 10,
UserName = model.UserName,
Email = model.UserName,
AccessFailedCount = 0,
FirstName = model.FirstName,
LastName = model.LastName,
CreatedBy = 2,
CreatedDate = DateTime.UtcNow,
Active = false
};
var returnResult = await _userManager.CreateAsync(user, model.Password);
if (returnResult.Succeeded)
{
returnResult = await _userManager.AddToRoleAsync(user, _roleManager.Roles.Where(x=>x.Id == model.RoleId).Select(x => x.Name).FirstOrDefault());
}
if (model.CompanyId!= null)
{
foreach (var item in model.CompanyId)
{
var userMap = new UserCompanyMapping();
userMap.UserId = user.Id;
userMap.CompanyId = item;
_userCompanyMappingRepository.Insert(userMap);
}
}
result = returnResult.Succeeded;
}
}
catch (Exception ex)
{
return false;
}
return result;
}
#endregion
}
//startup class
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(option =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
option.Filters.Add(new AuthorizeFilter(policy));
});
services.AddDbContextPool<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentityCore<ApplicationUser>();
// Register Dependencies extra service
services.AddAppServices();
services.AddIdentity<ApplicationUser, IdentityRole<int>>(options =>
{
options.User.RequireUniqueEmail = true;
options.Password.RequireNonAlphanumeric = false;
})
.AddRoles<IdentityRole<int>>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(option =>
{
option.LoginPath = "/login";
option.AccessDeniedPath = "/Login/AccessDenied";
});
// Register dependancy
RegisterAutoMapper(services);
RegisterServices(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.ConfigureRequestPipeline();
app.UseStaticFiles();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//register all routes
EngineContext.Current.Resolve<IRoutePublisher>().RegisterRoutes(endpoints);
});
//app.UseEndpoints(endpoints =>
//{
// endpoints.MapControllerRoute(
// name: "default",
// pattern: "{controller=Login}/{action=Index}/{id?}");
//});
}
private void RegisterServices(IServiceCollection services)
{
// Get class libraryGetAssembly(ty)
var serviceLibraries = Assembly.Load("Student.Services")
.GetTypes()
.Where(x => x.IsClass && x.GetInterfaces().Any() && x.Namespace.Contains(".Services.Services"))
.ToList();
if (serviceLibraries != null && serviceLibraries.Count > 0)
{
foreach (var service in serviceLibraries)
{
var interfaceType = service.GetInterfaces().FirstOrDefault();
services.AddScoped(interfaceType, service);
}
}
}
private void RegisterAutoMapper(IServiceCollection services)
{
// Auto Mapper Configurations
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new MappingProfile());
});
IMapper mapper = mappingConfig.CreateMapper();
services.AddSingleton(mapper);
}
}
//Action controller method
namespace Student.Web.Controllers
{
[Authorize]
public class UserController : Controller
{
private readonly IUserService userService;
private readonly ICommonService commonService;
public UserController(
IUserService userService,
ICommonService commonService)
{
this.userService = userService;
this.commonService = commonService;
}
public IActionResult Index()
{
return View();
}
[HttpGet]
public IActionResult Create()
{
ViewBag.RoleList = commonService.GetRoles().Result;
ViewBag.CompanyList = commonService.GetCompanies().Result;
ViewBag.CityList = commonService.GetCities().Result;
ViewBag.CompanyAccessList = commonService.GetCompanyAccessListMultiCheck().Result;
return View();
}
[HttpPost]
public IActionResult Create(UserAddModel model)
{
if (ModelState.IsValid)
{
var response = userService.Create(model);
}
return RedirectToAction("Index");
}
}
}
The call to your service
is never awaited
, so it is kind of became fire-and-forget
which means the request might ends before the service finishes its job which would cause the requested services to get disposed.
To fix that you need to alter your Create Action
a little bit by doing the followings:
async
and let it return Task<IActionResult>
. [HttpPost]
public async Task<IActionResult> Create(UserAddModel model)
{
if (ModelState.IsValid)
{
var response = await userService.Create(model);
}
return RedirectToAction("Index");
}
Then it should work just fine.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.