addim-addim-asp.net-core-ders-3.-startup-fayli

Addım-Addım ASP.NET CORE Dərs 3. Startup faylı

Asp.NET CORE-da praktikaya keçməmişdən öncə mütləq şəkildə template(şablon) proyektin hansı hissələrdən ibarət olduğunu və həmin hissələrin nə işə yaradığını bilmək lazımdır. Keçən dərsimizdə asp.net core proyektin daxili strukturunu öyrəndik. Bugün isə Asp.NET CORE –da Startup faylı haqqında danışacaq və aşağıdakı sualları cavablandırmağa çalışacağıq:

1)Startup.cs nədir?

2)ConfigureServices metodu nədir?

3)IServiceCollection interfeysi

4)Configure metodu nə işə yarayır?


1)Startup.cs nədir?

               Startup.cs faylı bütün növ CORE MVC template-lərində default olaraq generasiya olunan, proyektin servis və pipeline(gediş-gəliş sorğularının filtri) konfiqurasiyasını saxlayır.Generasiya olunmuş default Startup.cs belədir:

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }


        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }


            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
    }

Gördüyümüz kimi Startup.cs faylı əsas 2 metoddan ibarətdir. Bütün Startup.cs faylının gördüyü iş məhz bu 2 metodda cəmlənir. Startup faylının olması proyektdə məcburi deyil!! Beləki Program.cs faylında onun işini əvəzləyən mexanizmi rahatlıqla yazmaq olar:

 public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
            })
            .ConfigureServices(services =>
            {
               //this is the same method located in Startup.cs
            })
            .Configure(app =>
            {
            //this is the same method located in Startup.cs
            });

Startup.cs faylının ayrı yazılması daha düzgündür. Bu imkan yaradırki proyekti daha rahat başa düşək, daha rahat müşayiət edək və oxunaqlığı artıraq. Adətən çox kimi app üçün Startup.cs faylını ayrıca yaratmadan yuxarıdakı kimi yaza bilərsiniz.

2)ConfigureServices metodu nədir?

ConfigureServices() – metodu Asp.NET CORE-un servislərinin konfiqurasiyasını saxlayır.

Bəs servis nədir? Asp.NET CORE-u Asp.NET ilə müqayisə edən zaman (detallı bu linkdən oxu) demişdik ki, ASP.NET CORE ASP.NET-ə nisbətən daha modulyar, daha kimi komponentlərdən(hissələrdən,servislərdən) ibarət olduğunu demişdik. Bu hissələr imkan verir ki, proyekt yazan zaman yalnız lazım olan servisi qoşaq. Misalçün, əgər Asp.NET CORE default olaraq 50 servisdən ibarətdirsə və sənə yalnız 5-i lazımdırsa sən bu servislərin hamısını qoşmaq məcburiyyətində deyilsən. Yalnız sənə lazım olan hissəni qoşursan. Real proyektimizdən Startup.cs-in ConfigureServices() metodu(fraqment olaraq..):

public void ConfigureServices(IServiceCollection services)
        {
            //identity configiration for app - another service
            services.Configure(options =>
            {
                // Password settings.
                options.Password.RequireDigit = true;
                options.Password.RequireLowercase = true;
                options.Password.RequireNonAlphanumeric = true;
                options.Password.RequireUppercase = true;
                options.Password.RequiredLength = 6;
                options.Password.RequiredUniqueChars = 1;


                // Lockout settings.
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                options.Lockout.MaxFailedAccessAttempts = 10;
                options.Lockout.AllowedForNewUsers = true;


                // User settings.
                options.User.AllowedUserNameCharacters =
                "a";
                options.User.RequireUniqueEmail = true;


                options.SignIn.RequireConfirmedEmail = true;
            });


            //Enabling Session service
            services.AddDistributedMemoryCache();

         services.AddSession(options =>
                    {
                        options.Cookie.IsEssential = true;
                        options.Cookie.Name = ".XAPP.SessionInfo";
                        options.IdleTimeout = TimeSpan.FromHours(3);
                        options.Cookie.SameSite = SameSiteMode.None;
                        options.Cookie.HttpOnly = true;
                    });
        
        
        
                    services.ConfigureApplicationCookie(options =>
                    {
                        // Cookie settings
                        options.Cookie.IsEssential = true;
                        options.Cookie.HttpOnly = true;
                        options.Cookie.SameSite = SameSiteMode.None;
                        options.ExpireTimeSpan = TimeSpan.FromMinutes(25);
                        options.SlidingExpiration = true;
        
                        options.Events = new Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents
                        {
                            OnRedirectToLogin = ctx =>
                            {
                                ctx.Response.Redirect($"/{ctx.HttpContext.GetCurrentUICultureStr()}/Home/Index");
                                return Task.CompletedTask;
                            },
                            OnRedirectToAccessDenied = ctx =>
                            {
                                var requestPath = ctx.Request.Path;
                                if (requestPath.Value.Contains("/Admin"))
                                    ctx.Response.Redirect($"/{ctx.HttpContext.GetCurrentUICultureStr()}/Admin/Error/AccessDenied");
                                else if(requestPath.Value.Contains("/Profile"))
                                    ctx.Response.Redirect($"/{ctx.HttpContext.GetCurrentUICultureStr()}/Profile/Error/AccessDenied");
                                else
                                    ctx.Response.Redirect($"/{ctx.HttpContext.GetCurrentUICultureStr()}/Error/AccessDenied");
        
        
                                return Task.CompletedTask;
                            }
                            
                        };
        
        
                    });
        
        
                    services.Configure(options => {
                        options.Cookie.IsEssential = true;
                    });
                                
                  //add anti forgery service
                    services.AddAntiforgery(o => o.SuppressXFrameOptionsHeader = true);
        
                    //add location service
                    services.AddLocalization(x => x.ResourcesPath = "Resources");
        
        
                    //add mvc service..
                    services.AddMvc()
                            .SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1)
                            .AddSessionStateTempDataProvider()
                            .AddViewLocalization()
                            .AddDataAnnotationsLocalization(options => {
                                options.DataAnnotationLocalizerProvider = (type, factory) =>
                                    factory.Create(typeof(SharedResource));
                            });
        
        
                    services.AddAuthorization(x =>
                    {
                        x.AddPolicy("EmailConfirm", builder =>
                        {
                            builder
                            .RequireAuthenticatedUser()
                            .RequireRole("User")
                            .AddRequirements(new ConfirmationRequirment()
                            {
                                CheckEmailConfirmation = true,
                                CheckPhoneNumberConfirmation = false
                            });
                        });
            });
            services.AddScoped();

           //add SignalR service
            services.AddSignalR();
        }


Sadə dillə təsvir : Asp.NET CORE-u çoxlu servislər toplusu olaraq təsəvvür edin: bazaya qoşulma servisi, email servisi, login-registrasiya servisi(identity),signalR servisi, MVC servisi,lokalizasiya servisi, sessiya servisi, kuki servisi,öz yazdığımız onlarla servislər vəs.( bunların hər biri detallı öyrənəcəyik, narahat olmayın) Bizə app develop edən zaman bu servislərin hansı lazımdirsa yalnız onları qoşmaq üçün ConfigureServices() metodunu istifadə edirik. Yeri gəlmişkən, Startup faylında ConfigureServices metodu məcburi metod deyil, yəni yazılmasa da olar!!!

3)IServiceCollection interfeysi

               ConfigureServices metodu arqument olaraq IServiceCollection  interfeysi qəbul edir.  Bu interfeys Asp.NET CORE-da proyekt yaranan zaman özündə bütün servisləri saxlayır.ASP.NET CORE default olaraq bu interfeysin obyektini yaradaraq bizim metoda ötürür. Əgər hansısa bir servisi proyektə qoşmaq istəyiriksə ozaman onu IServiceCollection  interfeysinə extension method( genişlənmələr) vasitəsilə əlavə etməliyik. Adətən servislər AddServiceName() şəklində qoşulurlar. Misal:

  1. AddDbContext()-EntityFrameworkun qoşulması
  2. AddLocalization()- Lokalizasiya –qlobalizasiya üçün. (App-in bir neçə dil dəstəkləməsi üçün)
  3. AddIdentity()- Asp.NET CORE İdentity servisin qoşulması və.s

Sual 4. Configure metodu nə işə yarayır?

 Configure metodu proyekti middleware-lərin qoşulması üçündür.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.MapWhen(context => context.Request.Path.Value.Contains("/Admin"), builder =>
             {
                 builder.UseRequestLocalization();
                 if (env.IsDevelopment())
                     builder.UseDeveloperExceptionPage();
                 else
                 {
                     builder.UseExceptionHandler("/az-LATN/Admin/Error");
                     
                 }
                 builder.UseStatusCodePages(new StatusCodePagesOptions()
                 {
                     HandleAsync = async (context) =>
                     {
                         context.HttpContext.Response.Redirect($"/az-LATN/Admin/Error/{context.HttpContext.Response.StatusCode}");
                         await Task.CompletedTask;
                     }
                 });

                 builder.UseStaticFiles();

                 builder.UseSession();

                 builder.UseAuthentication();

                 builder.UseMvc(routes =>
                 {
                     routes.MapRoute(
                          name: "areasWithCulture",
                          template: "{culture}/{area:exists}/{controller=Home}/{action=Index}/{id?}"
                          );

                     routes.MapRoute(
                     name: "secondDefault",
                     template: "{culture}/{controller=Home}/{action=Index}/{id?}");


                     routes.MapRoute(
                         name: "default",
                         template: "{culture=az-LATN}/{controller=Home}/{action=Index}/{id?}");
                 });
             });

            app.UseRequestLocalization();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }
            app.UseStatusCodePages(new StatusCodePagesOptions()
            {
                HandleAsync = async (context) =>
                {
                    context.HttpContext.Response.Redirect($"/{context.HttpContext.GetCurrentUICultureStr()}/Error/{context.HttpContext.Response.StatusCode}");
                    await Task.CompletedTask;
                }
            });     
        }

Middleware-lər yazdığımız veb application-a gələn və geriyə qayıdan (Request-Response) sorğuların keçdiyi bir informasiya axını borusudur. Sadə dillə desək, Middleware-lər filtrlərdir. Kimsə bizim saytımıza sorğu verirsə həmin sorğu emal olunmamışdan öncə müəyyən filtr-lərdən keçir. Middleware müxtəlif ola bilər: gələn sorğu doğru parametrlə gəlirmi, doğru adamdan gəlirmi, doğru ünvana gəlirmi vəs. Bir növ təhlükəsizlik işləri yerinə yetirilir. Amma Middleware-lər təkcə bu işə yaramır. Middleware həmçinin sorğunun parametr,rol, http header vəs. əsasında doğru səhifəyə yönlənməsini təmin edir. Bundan əlavə Middleware geriyə,istifadəçiyə qayıdan sorğuları da emal edə bilir.  

Middleware adətən UseMiddlewareName()  şəklində qoşulur.

Bir çox servislərimiz varki, onların Middleware-ləri qoşulmadan işləmirlər. Misalçün : Əgər AddLocation() servisini qoşmuşuqsa ozaman UseRequestLocalization() yazıb həmin servisin Middleware-ni qoşmaq lazımdır. AddSession-UseSession, AddIdentity – UseAuthentication, AddSession-UseSession vəs.

Middleware-lər haqqında gələn dərsimizdə detallı danışacağıq amma saytımızda bu linkə klik edərək daha detallı türk dilində oxuya bilərsiniz.

 

Tural

Tural Süleymani

Süleymani Tural Microsoft-un MCSD statuslu mütəxəssisidir, 2008-ci ildən bu yana proqramlaşdırma üzrə tədris aparır

Müəllifin bu dildə ən son postları

Bu yazıları da bəyənə bilərsiniz