none
Advise on Working With Area And Code First Approach RRS feed

  • Question

  • Hello,

    Please, I am in a little bit fix working with DB first approach in EF. Need some advice and best practices.

    In my new MVC project, I created a new area which would have the MVC folder structure to be empty. Now, I created a class and performed a migration (of course, this only migrates the default MS identities). But now, how do I gain access to the DB context i.e the gateway to my db?. In my past project, I could do this by going to the identity models and writing the below line of code under ApplicationDbContext

    Public DbSet<User> Users {get; set;}

    With the above line of code, I could gain access to the user class and consume it where necessary. But this is a different ball game, whereby I created a new area for the admin…..Does it make sense to create my classes under the default model folder or the admin area model folder. Bear in mind that the admin area will serve as a back-end interface for users in the company to perform operations while the default MVC folders will serve as the front end where customers could play around. Don’t know if I am making some sense with my explanation.

    I don’t wana create an ApplicationDbContext class yet in the model of the admin area. Need advice on the best approach to go, as this is a long term project I plan to embark upon.

    Any advice would be appreciated on what to do....
    Thursday, January 10, 2019 2:51 AM

All replies

  • So what you are saying is that you are using Areas in MVC?

    In my new MVC project, I created a new area which would have the MVC folder structure to be empty. Now, I created a class and performed a migration (of course, this only migrates the default MS identities). But now, how do I gain access to the DB context i.e the gateway to my db?. In my past project, I could do this by going to the identity models and writing the below line of code under ApplicationDbContext

    It would mean that you would have to use one of the IoC(s), like Unity and Dependency Inject the ApplicationDBContext into a class so that a method in the class can use the context.

    https://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/

    Bear in mind that the admin area will serve as a back-end interface for users in the company to perform operations while the default MVC folders will serve as the front end where customers could play around. Don’t know if I am making some sense with my explanation.

    You should learn how to use ASP.NET MVC 5 Areas, becuase that is what Areas are about in MVC 5 to segregate MVC solutions within an ASP.NET MVC project.

    I am also going to mention this. 

    https://en.wikipedia.org/wiki/Separation_of_concerns

    https://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/

    https://www.codeproject.com/Articles/1225526/What-is-ViewModel-in-MVC-2

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs

    <copied>

    An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.

    A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.

    In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.

    <end>

    Layered or n-tier

    https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10)

    Remember this, it's not called Viewbag View Controller. It is called Model View Controller so don't fall downj into the viewbag rabbit hole. 

    I don’t wana create an ApplicationDbContext class yet in the model of the admin area. Need advice on the best approach to go, as this is a long term project I plan to embark upon.

    You should go to MVC Core and EF core, becuase of MVC Core usage of services and dependency injection like the ApplicationDBContext, and MVC Core has Areas too.

    https://stackify.com/asp-net-core-features/

    MVC Core can be discussed at the ASP.NET forums.

    https://forums.asp.net/

    MVC Core Statup.cs

    using System;
    using System.IO;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.FileProviders;
    using Microsoft.Extensions.Logging;
    using ProgMgmntCore2UserIdentity.Data;
    using ProgMgmntCore2UserIdentity.Models;
    using ProgMgmntCore2UserIdentity.WebApi;
    using Serilog;
    
    namespace ProgMgmntCore2UserIdentity
    {
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
                Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
            }
    
            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.Configure<CookiePolicyOptions>(options =>
                {
                    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                    options.CheckConsentNeeded = context => true;
                    options.MinimumSameSitePolicy = SameSiteMode.None;
                });
    
                services.AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(
                        Configuration.GetConnectionString("DefaultConnection")));
                services.AddDefaultIdentity<IdentityUser>()
                    .AddEntityFrameworkStores<ApplicationDbContext>();
    
    
                //Password Strength Setting
                services.Configure<IdentityOptions>(options =>
                {
                    // Password settings
                    options.Password.RequireDigit = true;
                    options.Password.RequiredLength = 8;
                    options.Password.RequireNonAlphanumeric = false;
                    options.Password.RequireUppercase = true;
                    options.Password.RequireLowercase = false;
                    options.Password.RequiredUniqueChars = 6;
    
                    // Lockout settings
                    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                    options.Lockout.MaxFailedAccessAttempts = 10;
                    options.Lockout.AllowedForNewUsers = true;
    
                    // User settings
                    options.User.RequireUniqueEmail = true;
                });
    
                //Seting the Account Login page
                services.ConfigureApplicationCookie(options =>
                {
                    // Cookie settings
                    options.Cookie.HttpOnly = true;
                    options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                    options.LoginPath = "/Account/Login"; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
                    options.LogoutPath = "/Account/Logout"; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
                    options.AccessDeniedPath = "/Account/AccessDenied"; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
                    options.SlidingExpiration = true;
                });
    
                services.AddSingleton<IFileProvider>(
                    new PhysicalFileProvider(
                        Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")));
    
                //Models
                services.AddTransient<IProjectModel, ProjectModel>();
                services.AddTransient<ITaskModel, TaskModel>();
                services.AddTransient<IModelHelper, ModelHelper>();
                services.AddTransient<ICacheModel, CacheModel>();
    
                //WebApis
                services.AddTransient<IWebApi, WebApi.WebApi>();
    
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider services, ILoggerFactory loggerFactory)
            {
                loggerFactory.AddSerilog();
    
                app.UseExceptionHandler("/Error/Error");
               
                app.UseStaticFiles();
    
                app.UseAuthentication();
                
                app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
                });
            }
        }
    }

     


    • Edited by DA924x Thursday, January 10, 2019 6:07 AM
    Thursday, January 10, 2019 5:45 AM
  • So what you are saying is that you are using Areas in MVC?

    In my new MVC project, I created a new area which would have the MVC folder structure to be empty. Now, I created a class and performed a migration (of course, this only migrates the default MS identities). But now, how do I gain access to the DB context i.e the gateway to my db?. In my past project, I could do this by going to the identity models and writing the below line of code under ApplicationDbContext

    It would mean that you would have to use one of the IoC(s), like Unity and Dependency Inject the ApplicationDBContext into a class so that a method in the class can use the context.

    https://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/

    Bear in mind that the admin area will serve as a back-end interface for users in the company to perform operations while the default MVC folders will serve as the front end where customers could play around. Don’t know if I am making some sense with my explanation.

    You should learn how to use ASP.NET MVC 5 Areas, becuase that is what Areas are about in MVC 5 to segregate MVC solutions within an ASP.NET MVC project.

    I am also going to mention this. 

    https://en.wikipedia.org/wiki/Separation_of_concerns

    https://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/

    https://www.codeproject.com/Articles/1225526/What-is-ViewModel-in-MVC-2

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs

    <copied>

    An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.

    A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.

    In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.

    <end>

    Layered or n-tier

    https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10)

    Remember this, it's not called Viewbag View Controller. It is called Model View Controller so don't fall downj into the viewbag rabbit hole. 

    I don’t wana create an ApplicationDbContext class yet in the model of the admin area. Need advice on the best approach to go, as this is a long term project I plan to embark upon.

    You should go to MVC Core and EF core, becuase of MVC Core usage of services and dependency injection like the ApplicationDBContext, and MVC Core has Areas too.

    https://stackify.com/asp-net-core-features/

    MVC Core can be discussed at the ASP.NET forums.

    https://forums.asp.net/

    MVC Core Statup.cs

    using System;
    using System.IO;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.FileProviders;
    using Microsoft.Extensions.Logging;
    using ProgMgmntCore2UserIdentity.Data;
    using ProgMgmntCore2UserIdentity.Models;
    using ProgMgmntCore2UserIdentity.WebApi;
    using Serilog;
    
    namespace ProgMgmntCore2UserIdentity
    {
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
                Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
            }
    
            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.Configure<CookiePolicyOptions>(options =>
                {
                    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                    options.CheckConsentNeeded = context => true;
                    options.MinimumSameSitePolicy = SameSiteMode.None;
                });
    
                services.AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(
                        Configuration.GetConnectionString("DefaultConnection")));
                services.AddDefaultIdentity<IdentityUser>()
                    .AddEntityFrameworkStores<ApplicationDbContext>();
    
    
                //Password Strength Setting
                services.Configure<IdentityOptions>(options =>
                {
                    // Password settings
                    options.Password.RequireDigit = true;
                    options.Password.RequiredLength = 8;
                    options.Password.RequireNonAlphanumeric = false;
                    options.Password.RequireUppercase = true;
                    options.Password.RequireLowercase = false;
                    options.Password.RequiredUniqueChars = 6;
    
                    // Lockout settings
                    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                    options.Lockout.MaxFailedAccessAttempts = 10;
                    options.Lockout.AllowedForNewUsers = true;
    
                    // User settings
                    options.User.RequireUniqueEmail = true;
                });
    
                //Seting the Account Login page
                services.ConfigureApplicationCookie(options =>
                {
                    // Cookie settings
                    options.Cookie.HttpOnly = true;
                    options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                    options.LoginPath = "/Account/Login"; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
                    options.LogoutPath = "/Account/Logout"; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
                    options.AccessDeniedPath = "/Account/AccessDenied"; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
                    options.SlidingExpiration = true;
                });
    
                services.AddSingleton<IFileProvider>(
                    new PhysicalFileProvider(
                        Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")));
    
                //Models
                services.AddTransient<IProjectModel, ProjectModel>();
                services.AddTransient<ITaskModel, TaskModel>();
                services.AddTransient<IModelHelper, ModelHelper>();
                services.AddTransient<ICacheModel, CacheModel>();
    
                //WebApis
                services.AddTransient<IWebApi, WebApi.WebApi>();
    
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider services, ILoggerFactory loggerFactory)
            {
                loggerFactory.AddSerilog();
    
                app.UseExceptionHandler("/Error/Error");
               
                app.UseStaticFiles();
    
                app.UseAuthentication();
                
                app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
                });
            }
        }
    }

     


    Hi DA924x,

    Appreciate your feedback.

    Not sure you understand the point earlier. I don’t wana use MVC Core yet. I wana take things step by step. I just have one area in my project which will serve as the back.

    Take for instance, in an E-commerce website, the customers can browse through items freely and see other stuff about the company, like about us, home, contact etc. Now, when a customer purchase something like maybe a T-shirt. The users who works in the company should be able to see the orders of a customer. Now, the interface which users see will be coming from the admin area….

    All I just need is the best way on how to get access to my DbContext in the admin areas since that is where some of my classes is. I understand the MVC pattern. If I create a class in the model folder of the admin area using the code first approach, and I perform a migration, how does the identity model knows about the admin area class which I have created?

    Thursday, January 10, 2019 11:15 AM
  • Not sure you understand the point earlier. I don’t wana use MVC Core yet. I wana take things step by step. I just have one area in my project which will serve as the back.

    I understood it. And you can use MVC Core like non MVC core. MVC, a UI design pattern, is MVC concerning the basic principles in using the MVC UI design  pattern. So you can go step by step with Core too. But that's up to you as to how you do it Core or non Core.

    Take for instance, in an E-commerce website, the customers can browse through items freely and see other stuff about the company, like about us, home, contact etc

    One Area in Areas, the Client Area. 

    Now, when a customer purchase something like maybe a T-shirt. The users who works in the company should be able to see the orders of a customer. Now, the interface which users see will be coming from the admin area….

    The Administration Area in Areas.

    <copied>

    ASP.NET MVC lets you partition Web applications into smaller units that are referred to as areas. Areas provide a way to separate a large MVC Web application into smaller functional groupings. An area is effectively an MVC structure inside an application. An application could contain several MVC structures (areas).

    <end>

    You can let the default project layout  before admin using Identity and EF, a non Area solution, bot on the other hand, you can have Client in its own Area independent of the default project layout.

    https://docs.microsoft.com/en-us/previous-versions/aspnet/ee671793(v=vs.100)

    All I just need is the best way on how to get access to my DbContext in the admin areas since that is where some of my classes is

    The DBContect, an object that allows access to the persistence virtual object model for a given database,  can be dependency injected into a given class when an IoC container controls the Dbcontext. 

    If I create a class in the model folder of the admin area using the code first approach, and I perform a migration, how does the identity model knows about the admin area class which I have created?

    I cringe every time I see a developer talk about EF migrations, becuase I flat out do not use an ORM's tools for database administartion. I use database admin tools like SSMS or SQL Scripts. So I cannot help you on migrations. 

    However, you can post to the ASP.NET MVC section in ASP.NET forums. They will help you there.

    Thursday, January 10, 2019 2:47 PM
  • Hi Godymn,

    Since your issue is more related to asp.net MVC, I would suggest that you could post your issue asp.net MVC forum for suitable support.

    https://forums.asp.net/1146.aspx/1?MVC

    Thanks for your understanding.

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, January 11, 2019 7:17 AM