public enum CustomerType { Person = 0, Company = 1 } public class Customer { public CustomerType Type { get; set; } }
با وجود چنین کلاسی از مشتری و نیاز به انجام فعالیتهای مختلفی بر روی آن، احتمالا نیاز خواهد بود که در بخشهای مختلف کد، گذارهی switch ای مانند زیر را اضافه کنید:
switch (customer.Type) { case CustomerType.Person: // calculate discount, or send message or edit customer or anything else break; case CustomerType.Company: // calculate discount, or send message or edit customer or anything else break; default: throw new ArgumentOutOfRangeException(); }
برای انجام فعالیتهای مختلفی مانند محاسبه تخفیف، ارسال پیام و یا ویرایش مشتری، نیاز خواهد بود این گذاره تکرار شود که خود این موضوع بوی بد duplicate code است و به الگوی shotgun surgery نیز ختم خواهد شد.
حال فرض کنید نیاز است مشتریان حقوقی، خود به دو نوع مشتری حقوقی بخش خصوصی و مشتری حقوقی بخش دولتی تقسیم شوند. در پیاده سازی ذکر شده باید به CustomerType یک آیتم افزوده شود و در تمامی switchها نیز در صورت نیاز شرط مربوط به آن اضافه شود.
برای حل این نوع از کد بد بو، معمولا یک کلاس پدر را به نام مشتری ایجاد کرده و کلاسهای مختص هر یک از انواع مشتری را از آن به ارث میبرند (Replace type code with subclass):
یا میتوان طراحی را کمی متفاوتتر و به صورت زیر انجام داد:
دلیل مشابه دیگر ایجاد این الگوی بد کد استفاده از type code به عنوان وضعیت یک تایپ است. که در این صورت میتوان بجای type code از state object استفاده کرد (Replace type code with strategy). به این مورد در مباحث مربوط به refactoring به طور مفصل پرداخته شده است.
جمع بندی
این کد بد بو در شرایط متفاوتی ایجاد میشود. با این حال یکی از پر تکرارترین آنها استفاده بد یا عدم استفاده از الگوهای طراحی شیء گرا است. تصحیص این الگوی بد، به خوانایی و نگهداری کد در بلند مدت کمک بسیار زیادی میکند.
5 JavaScript Security Best Practices for 2024
Any JavaScript web application needs to have a Content Security Policy (CSP), a browser security standard that dictates what the browser is allowed to load — whether that be a domain, subdomain, or resource. Without a CSP, hackers can exploit cross-site scripting vulnerabilities, potentially resulting in a data breach.
@import '~@angular/material/theming'; @include mat-core(); $green-primary: mat-palette($mat-green,A700); $green-accent: mat-palette($mat-green, A700, A200, A700); $green-warn: mat-palette($mat-green,A700); $green-app-theme: mat-light-theme($green-primary, $green-accent, $green-warn); .green{ @include angular-material-theme($green-app-theme); } $yellow-primary: mat-palette($mat-yellow,A200); $yellow-accent: mat-palette($mat-green, A700, A200, A700); // The warn palette is optional (defaults to red). $yellow-app-warn: mat-palette($mat-green,A700); // Create the theme object (a Sass map containing all of the palettes). $yellow-app-theme: mat-light-theme($yellow-primary, $yellow-accent, $yellow-app-warn); .yellow{ @include angular-material-theme($yellow-app-theme); }
<div [ngClass]="themeClass" color="primary"> <mat-toolbar #toolbar color="primary"> <p>تست قالب پویا</p> <a routerLink='' mat-button>خانه</a> <button mat-button [matMenuTriggerFor]="menu">قالب</button> <mat-menu #menu="matMenu"> <button mat-menu-item (click)="changeTheme('')">پیشفرض</button> <button mat-menu-item (click)="changeTheme('green')">سبز</button> <button mat-menu-item (click)="changeTheme('yellow')">زرد</button> </mat-menu> </mat-toolbar> </div>
import { Component } from '@angular/core'; import { Http } from '@angular/http'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; themeClass = localStorage.getItem('nameOfThemeClass'); constructor() { } ngOnInit() { } changeTheme(theme) { this.themeClass = theme; localStorage.setItem('nameOfThemeClass', this.themeClass); } }
froala/wysiwyg-editor 1.2.6 منتشر شد
یادگیری SASS در 15 دقیقه
If you write copious amounts of CSS, a pre-processor can greatly decrease your stress levels and save you a lot of precious time. Using tools such as Sass, Less, Stylus or PostCSS makes large and complicated stylesheets clearer to understand and easier to maintain. Thanks to features like variables, functions and mixins the code becomes more organized, allowing developers to work quicker and make less mistakes.
سری بررسی مقدمات Blazor
Blazor Fundamentals Tutorial
Blazor server-side vs client-side (WebAssembly) | What should you choose?
What are Razor Components? | Blazor Tutorial 1
Dependency Injection | Blazor Tutorial 2
What are Blazor Layouts? | Blazor Tutorial 3
Routing and Navigation | Blazor Tutorial 4
JS Interop: Calling JavaScript from C# | Blazor Tutorial 5
JS Interop: Calling C# methods from JavaScript | Blazor Tutorial 6
Creating Forms with Validation | Blazor Tutorial 7
How to add Authentication in Server-side Blazor | Blazor Tutorial 8
Authorization in Server-Side Blazor | Blazor Tutorial 9
How to use HTML5 Web Storage in Blazor | Blazor Tutorial 10
Managing Blazor state using Redux | Blazor Tutorial 11
Creating a desktop application using Blazor and Electron | Blazor Tutorial 12
Deploying Server-Side Blazor in Azure with SignalR service | Blazor Tutorial 13
Building cross platform mobile apps with Blazor (Experimental)
انقضای اهراز هویت کاربر پس از رفرش کردن صفحه در پروژه ای مشابه
برای یادگیری من دارم پروژه ای شبیه به پروژه شما میسازم. یعنی به عبارتی مراحل شمارو یکی ، یکی طی میکنم. حالا به جایی رسیدم که هرچقدر هم تلاش کردم متاسفانه پاسخی براش پیدا نکردم.
مشکل من اینه. زمانی که کاربر دکمه ورود رو میزنه و وارد سیستم میشه ، زمانی که صفحه رو رفرش کنه یا از صفحه ای به صفحهی دیگه بره اهراز هویتیش تموم میشه. با اینکه "مرا به خاطر داشته باش" رو هم تیک میزنم ولی باز این مشکل پیش میاد. جالب اینجاست کدهای خودتون به درستی در پروژه خودتون کار میکنه ولی وقتی میارمشون تو پروژهی خودم این مشکل پیش میاد. نمیدونم کجارو اشتباه کردم ولی میدونم یک چیزی کمه.
توجه کنید زمانی که کاربر ورود میکنه مقدار @User.Identity.IsAuthenticated برابر با true هستش. پس قطعا کاربر ورود میکنه ولی زمانی که صفحه تغییر میکنه این مقدار برابر false میشه.
کدهای کلاس Startup دقیقا همون کدهای شما و من تغییری بهشون ندادم فقط اسم کوکی رو عوض کردم یعنی اینطوری :
public class Startup { public void Configuration(IAppBuilder app) { ConfigureAuth(app); app.MapSignalR(); } private static void ConfigureAuth(IAppBuilder appBuilder) { const int twoWeeks = 14; ProjectObjectFactory.Container.Configure(config => config.For<IDataProtectionProvider>() .HybridHttpOrThreadLocalScoped() .Use(() => appBuilder.GetDataProtectionProvider())); appBuilder.CreatePerOwinContext( () => ProjectObjectFactory.Container.GetInstance<ApplicationUserManager>()); appBuilder.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), ExpireTimeSpan = TimeSpan.FromDays(twoWeeks), SlidingExpiration = true, CookieName = "MyFirstCms", Provider = new CookieAuthenticationProvider { OnValidateIdentity = ProjectObjectFactory.Container.GetInstance<IApplicationUserManager>().OnValidateIdentity() } }); ProjectObjectFactory.Container.GetInstance<IApplicationRoleManager>() .SeedDatabase(); ProjectObjectFactory.Container.GetInstance<IApplicationUserManager>() .SeedDatabase(); appBuilder.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process. //appBuilder.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5)); // Enables the application to remember the second login verification factor such as phone or email. // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from. // This is similar to the RememberMe option when you log in. // appBuilder.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie); appBuilder.UseFacebookAuthentication( appId: "fdsfdsfs", appSecret: "fdfsfs"); appBuilder.UseGoogleAuthentication( clientId: "fdsfsdfs", clientSecret: "fdsfsf"); } }
این هم کدهای صفحه ورود :
[HttpPost] [AllowAnonymous] //[CheckReferrer] [ValidateAntiForgeryToken] public virtual async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (!ModelState.IsValid) { return View(model); } if (!_userManager.CheckUserNameExist(model.UserName,null)) { this.AddErrors("UserName", "نام کاربری یا کلمه عبور وارد شده نادرست است"); return View(model); } if (_userManager.CheckIsUserBannedOrDelete(model.UserName)) { this.AddErrors("UserName", "حساب کاربری شما مسدود شده است"); return View(model); } if (!_userManager.IsEmailConfirmedByUserNameAsync(model.UserName)) { this.NotyWarning("برای ورود به سایت لازم است حساب خود را فعال کنید"); return RedirectToAction(MVC.Account.ActionNames.ReceiveActivatorEmail, MVC.Account.Name); } var result = await _signInManager.PasswordSignInAsync (model.UserName.ToLower(), model.Password, model.RememberMe, shouldLockout: true); switch (result) { case SignInStatus.Success: this.NotySuccess("شما با موفقیت وارد سیستم شدید"); return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: this.NotyError( $"دقیقه دوباره امتحان کنید {_userManager.DefaultAccountLockoutTimeSpan} حساب شما قفل شد ! لطفا بعد از "); return View(model); case SignInStatus.Failure: this.NotyError(ModelState.GetListOfErrors()); return View(model); default: this.NotyError( "در این لحظه امکان ورود به سابت وجود ندارد . مراتب را با مسئولان سایت در میان بگذارید"); return View(model); } }
ممنون میشم اگر میدونید کجارو اشتباه کردم بهم بگید.
با سپاس
کتاب Cryptography in .NET Succinctly
Irresponsible ownership of data is the cause of many leaked emails,
data, and other damaging information. Securing a user’s personal
information is the job of software developers. If you, as a developer,
can decrypt the information stored in the database of the system you are
working on, then so can anyone else. In Cryptography in .NET Succinctly,
Dirk Strauss will take readers through generating cryptographic
signatures, hashing and salting passwords, and when and how to use
symmetric vs. asymmetric encryption.