نظرات مطالب
رمزنگاری کانکشن استرینگ در ASP.Net
سلام آقای نصیری.خوبین؟من چجوری میتونم مراتب تشکرم روبه شما اعلام کنم.فقط میتونم دعا کنم خدا کار شما رو همیشه راه بندازه.ان شا الله.
من برای انکریپشن از این کتابخونه استفاده میکنم:
http://www.codeproject.com/KB/security/SimpleEncryption.aspx
من برای ویندوز یه فایل ایکس ام ال برای پیکر بندی ایجاد میکنم(شبیه app.config) که مواردی که برای برنمم لازم هست رو با الگوریتم TripleDES و با یه رشته عجیب غریب که توش کاراکترهای عجیب غریب داره کد میکنم.الان موردی که هست اینه که من برای پروژه DAL ام باید این فایل رو باز کنم رشته کانکشن استرینگ مورد نظر رو دیکد کنم و بعد ازش استفاده کنم.آیا این قیمتیه که باید برای امنیت بدیم؟راه بهتری وجود داره؟یعنی میشه یه بار این رشته رو دیکد کرد و در حافظه نگه داشت؟اما خوب برای این کار باید همیشه یه نمونه از کلاس DAL وجود داشته باشه.
برای نت هم آیا به صرفه هست یه پروایدر دیگه برای دیکد بنویسیم که از غیر قابل برگشت بودن اون مظمئن بشیم؟
ممنون از لطف و محبت شما
همیشه موفق باشید
نیما
مطالب
مسیریابی در Angular - قسمت دوم - مسیریابی ماژول‌ها
اغلب برنامه‌های بزرگ Angular، ویژگی‌های مختلف خود را به ماژول‌های مجزایی تبدیل می‌کنند. این ماژول‌ها شبیه به مفهوم Area در ASP.NET MVC هستند و هدف آن‌ها نظم بخشیدن به کامپوننت‌های ویژه‌ی یک قسمت خاص از برنامه، در ناحیه‌‌ای مختص به آن می‌باشد. به علاوه ایجاد ماژول‌ها، قابلیت lazy loading مسیریابی‌ها را نیز مسیر می‌کند. هر برنامه‌ی Angular حداقل به همراه یک ماژول است که بر اساس قراردادی، AppModule نام گرفته‌است و در فایل src\app\app.module.ts قرار دارد. با توسعه‌ی برنامه و بیشتر شدن قابلیت‌های آن، استفاده‌ی از این تک ماژول پیش فرض، مشکل تداخل مسئولیت‌ها را به همراه خواهد داشت. برای رفع این مشکل توصیه شده‌است که کامپوننت‌های مرتبط به یک ویژگی خاص را درون ماژولی مختص به خود قرار دهید؛ برای مثال مانند ماژول محصولات، برای نظم دهی به کامپوننت‌های لیست محصولات، جزئیات محصولات، ویرایش محصولات و غیره، ماژول کاربران برای تعریف کامپوننت‌های لاگین، تغییر کلمه‌ی عبور و امثال آن. در این قسمت قصد داریم نحوه‌ی تنظیمات مسیریابی و هدایت کاربران را به ماژول‌های مختلف برنامه، بررسی کنیم.


تنظیم مسیریابی ماژول‌ها

در اینجا نیازی به تنظیم base path نیست و این تنظیم تنها یکبار به ازای کل برنامه انجام می‌شود. همانطور که در قسمت قبل نیز عنوان شد، ماژول مسیریابی Angular و یا همان RouterModule، به همراه سرویسی برای دسترسی به امکانات آن، تنظیمات مسیریابی و یک سری دایرکتیو مانند routerLink، جهت تعامل با آن است. از آنجائیکه سرویس ماژول مسیریابی در فایل src\app\app-routing.module.ts تعریف و تنظیم شده‌است، باید اطمینان حاصل کرد که این سرویس تنها یکبار در طول عمر برنامه وهله سازی می‌شود و از آنجائیکه هر ماژول تنظیمات مجزای مسیریابی خود را خواهد داشت، دیگر نمی‌توان از متد RouterModule.forRoot سراسری استفاده کرد و در اینجا باید از متد forChild این ماژول، جهت تعریف تنظیمات مسیریابی‌های ماژول‌های مختلف کمک گرفت. متد forChild نیز شبیه به همان آرایه‌ی تنظیمات مسیریابی متد forRoot را دریافت می‌کند.

یک مثال: در ادامه‌ی مثالی که در قسمت قبل به کمک Angular CLI ایجاد کردیم، ماژول جدید محصولات را به همراه تنظیمات ابتدایی مسیریابی آن ایجاد می‌کنیم:
 >ng g m product --routing
پس از اجرای این دستور، ماژول جدید محصولات در فایل src\app\product\product.module.ts و تنظیمات ابتدایی آن در فایل src\app\product\product-routing.module.ts تشکیل می‌شوند:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class ProductRoutingModule { }
همانطور که مشاهده می‌کنید، در حین تشکیل تنظیمات ابتدایی مسیریابی این ماژول جدید، اینبار از متد forChild استفاده شده‌است و نه متد forRoot که مختص به ماژول اصلی و سراسری برنامه‌است.
سپس ProductRoutingModule به قسمت imports ماژول محصولات به صورت خودکار اضافه شده‌است:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { ProductRoutingModule } from './product-routing.module';

@NgModule({
  imports: [
    CommonModule,
    ProductRoutingModule
  ],
  declarations: []
})
export class ProductModule { }

در ادامه کامپوننت جدید لیست محصولات را به این ماژول اضافه می‌کنیم:
 >ng g c product/ProductList
به این ترتیب داخل پوشه‌ای به نام produc-list، کامپوننت product-list.component.ts تشکیل خواهد شد. در حقیقت این دستور اعمال ذیل را انجام می‌دهد:
 installing component
  create src\app\product\product-list\product-list.component.css
  create src\app\product\product-list\product-list.component.html
  create src\app\product\product-list\product-list.component.spec.ts
  create src\app\product\product-list\product-list.component.ts
  update src\app\product\product.module.ts
اگر به سطر آخر آن دقت کنید، کار به روز رسانی فایل ماژول محصولات، جهت درج این کامپوننت جدید، در قسمت declarations فایل product.module.ts نیز به صورت خودکار انجام شده‌است:
import { ProductListComponent } from './product-list/product-list.component';

@NgModule({
  imports: [
  ],
  declarations: [ProductListComponent]
})
export class ProductModule { }

اکنون که این ماژول جدید را به همراه یک کامپوننت نمونه در آن تعریف کردیم، برای افزودن مسیریابی به آن، به فایل src\app\product\product-routing.module.ts مراجعه کرده و آرایه‌ی  Routes آن‌را تکمیل می‌کنیم:
import { ProductListComponent } from './product-list/product-list.component';

const routes: Routes = [
  { path: 'products', component: ProductListComponent }
];
ابتدا کامپوننت لیست محصولات import شده و سپس آرایه‌ی Routes مسیری را به این کامپوننت تعریف کرده‌ایم.

در ادامه می‌خواهیم لینکی را به این مسیریابی جدید اضافه کنیم. در قسمت قبل منویی را به برنامه اضافه کردیم. به همین جهت به فایل src\app\app.component.html مراجعه کرده و routerLink جدیدی را به آن اضافه می‌کنیم:
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <a class="navbar-brand">{{title}}</a>
    <ul class="nav navbar-nav">
      <li>
        <a [routerLink]="['/home']">Home</a>
      </li>
      <li>
        <a [routerLink]="['/products']">Product List</a>
      </li>
    </ul>
  </div>
</nav>
<div class="container">
  <router-outlet></router-outlet>
</div>
پیشتر لینکی را به کامپوننت welcome در قسمت قبل اضافه کرده بودیم. در اینجا لینک جدیدی را به کامپوننت لیست محصولات، در ذیل آن تعریف کرده‌ایم.
در اینجا نیز نحوه‌ی تعریف لینک‌ها مانند قبل است و آرایه‌ی تنظیمات پارامترهای لینک باید به مقدار خاصیت path تعریف شده اشاره کند.

اکنون دستور ng serve -o را صادر کنید تا برنامه در حافظه ساخته شده و در مرورگر نمایش داده شود. در ادامه اگر بر روی لینک لیست محصولات کلیک کنید، صفحه‌ی ذیل را مشاهده خواهید کرد:


به این معنا که برنامه اطلاعی از این مسیریابی جدید نداشته و صفحه‌ی یافت نشدن مسیریابی را که در قسمت قبل تنظیم کردیم، نمایش داده‌است. برای رفع این مشکل باید به فایل src\app\app.module.ts مراجعه کرده و این ماژول جدید را به آن معرفی کنیم:
import { ProductModule } from './product/product.module';

@NgModule({
  declarations: [
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,

    ProductModule,

    AppRoutingModule
  ],
در اینجا در ابتدا ماژول محصولات import شده و سپس به قسمت لیست imports ماژول App اضافه گردیده‌است. اکنون مسیریابی به این کامپوننت جدید واقع شده‌ی در قسمت ماژول محصولات، کار می‌کند:


نکته 1: علت اینکه ProductModule را پیش از AppRoutingModule تعریف کردیم این است که AppRoutingModule دارای تعریف مسیریابی ** یا catch all است که در قسمت قبل آن‌را جهت مدیریت مسیرهای یافت نشده به برنامه افزودیم. اگر ابتدا AppRoutingModule تعریف می‌شد و سپس ProductModule، هیچگاه فرصت به پردازش مسیریابی‌های ماژول محصولات نمی‌رسید؛ چون مسیر ** پیشتر برنده شده بود.
نکته 2: می‌توان در قسمت import متد RouterModule.forRoot را نیز مستقیما قرار داد (بجای AppRoutingModule). اگر این کار صورت گیرد، ابتدا مسیریابی‌های موجود در ماژول‌ها پردازش می‌شوند و در آخر مسیرهای موجود در RouterModule.forRoot صرفنظر از محل قرارگیری آن در این لیست بررسی خواهد شد (حتی اگر در ابتدای لیست قرار گیرد). هرچند جهت مدیریت بهتر برنامه، این متد به AppRoutingModule منتقل شده‌است. بنابراین اکنون «نکته‌ی 1» برقرار است.


انتخاب استراتژی مناسب نامگذاری مسیرها

هنگام کار کردن با تعدادی ویژگی مرتبط به هم قرار گرفته‌ی داخل یک ماژول، بهتر است روش نامگذاری مناسبی را برای تنظیمات مسیریابی آن درنظر گرفت تا مسیرهای تعیین شده علاوه بر زیبایی، وضوح بیشتری را نیز پیدا کنند. به علاوه این نامگذاری مناسب، گروه بندی مسیریابی‌ها و lazy loading آن‌ها را نیز ساده‌تر می‌کند.
استراتژی ابتدایی که به ذهن می‌رسد، نامگذاری هر مسیر بر اساس عملکرد آن‌ها است مانند products برای نمایش لیست محصولات، product/:id برای نمایش جزئیات محصولی خاص که در اینجا id پارامتر مسیریابی است و productEdit/:id برای ویرایش جزئیات یک محصول مشخص. همانطور که مشاهده می‌کنید، هرچند این مسیرها متعلق به یک ماژول هستند، اما مسیرهای تعیین شده‌ی برای آن‌ها اینگونه به نظر نمی‌رسد. بنابراین بهتر است تمام ویژگی‌های قرار گرفته‌ی درون یک ماژول را با مسیر ریشه‌ی یکسانی شروع کنیم. به این ترتیب نمایش لیست محصولات همان products باقی خواهد ماند اما برای نمایش جزئیات محصولی خاص از مسیر products/:id استفاده می‌کنیم (همان اسم جمع ریشه‌ی مسیر؛ بجای اسم مفرد). اینبار مسیر ویرایش جزئیات یک محصول به صورت products/:id/edit تنظیم خواهد شد:
products
products/:id
products/:id/edit
در اینجا نام ریشه‌ی یکسانی را برای عناصر مختلف قرارگرفته‌ی درون یک ماژول انتخاب کرده‌ایم؛ تا ارتباط بین آن‌ها بهتر مشخص شود و همچنین در آینده بتوان مباحث گروه بندی و lazy loading را نیز بر این اساس پیاده سازی کرد.


فعالسازی یک مسیر با کدنویسی

تا اینجا نحوه‌ی فعالسازی یک مسیر را با استفاده از دایرکتیو routerLink بررسی کردیم. اما گاهی از اوقات نیاز است تا بتوان با کدنویسی نیز کاربران را به مسیری خاص هدایت کرد. برای مثال پس از عملیات logout می‌خواهیم مجددا صفحه‌ی اول سایت نمایش داده شود. برای اینکار از سرویس Router مسیریاب Angular کمک گرفته می‌شود. ابتدا آن‌را در سازنده‌ی یک کامپوننت تزریق کرده و سپس می‌توان به قابلیت‌های آن مانند استفاده‌ی از متد navigate آن، در کدهای برنامه دسترسی یافت.
باید درنظر داشت که دایرکتیو routerLink نیز در پشت صحنه از همین متد navigate سرویس Router استفاده می‌کند. بنابراین تمام پارامترهای آن در متد navigate نیز قابل استفاده هستند. برای مثال زمانیکه تعداد پارامترهای routerLink یک مورد است، می‌توان آرایه‌ی آن‌را به یک رشته خلاصه کرد. یک چنین قابلیتی با متد navigate نیز میسر است.
متد navigate تنها قسمت‌هایی از URL جاری را تغییر می‌دهد. اگر نیاز باشد تا کل آدرس تعویض شود، می‌توان از متد دیگر سرویس Router به نام navigateByUrl استفاده کرد. این متد تمام URL segments موجود را با مسیر جدیدی جایگزین می‌کند. به علاوه برخلاف متد navigate، تنها یک رشته را به عنوان پارامتر می‌پذیرد.

در ادامه مثال جاری می‌خواهیم پیاده سازی ابتدایی login و logout را به برنامه اضافه کنیم. به همین منظور ابتدا ماژول جدید user را به همراه تنظیمات ابتدایی مسیریابی آن اضافه می‌کنیم:
 >ng g m user --routing
به این ترتیب دو فایل src\app\user\user-routing.module.ts و src\app\user\user.module.ts به برنامه اضافه می‌شوند.
همانند ماژول قبلی، نیاز است UserModule را به قسمت imports فایل src\app\app.module.ts نیز معرفی کنیم:
import { UserModule } from './user/user.module';

@NgModule({
  declarations: [
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,

    ProductModule,
    UserModule,

    AppRoutingModule
  ],

سپس کامپوننت جدید لاگین را به ماژول user برنامه اضافه می‌کنیم:
 >ng g c user/login
که اینکار سبب به روز رسانی فایل user.module.ts جهت تکمیل قسمت declarations آن با LoginComponent نیز می‌شود.

در ادامه به فایل src\app\user\user-routing.module.ts مراجعه کرده و مسیریابی جدیدی را به کامپوننت لاگین تعریف می‌کنیم:
import { LoginComponent } from './login/login.component';

const routes: Routes = [
  { path: 'login', component: LoginComponent}
];
ابتدا این کامپوننت import شده و سپس یک path جدید را به آن انتساب می‌دهیم.

مرحله‌ی بعد، فعالسازی این مسیریابی است، با تعریف لینکی به آن. به همین جهت به فایل src\app\app.component.html مراجعه کرده و منوی برنامه را تکمیل می‌کنیم:
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <a class="navbar-brand">{{title}}</a>
    <ul class="nav navbar-nav">
      <li>
        <a [routerLink]="['/home']">Home</a>
      </li>
      <li>
        <a [routerLink]="['/products']">Product List</a>
      </li>
    </ul>
    <ul class="nav navbar-nav navbar-right">
      <li>
        <a [routerLink]="['/login']">Log In</a>
      </li>
    </ul>
  </div>
</nav>
<div class="container">
  <router-outlet></router-outlet>
</div>
اکنون دستور ng serve -o را صادر کنید تا برنامه در حافظه ساخته شده و در مرورگر نمایش داده شود و سپس بر روی لینک login کلیک کنید تا قالب ابتدایی آن نمایش داده شود:



تکمیل کامپوننت login و افزودن لینک logout

در ادامه می‌خواهیم یک فرم لاگین مقدماتی را پس از کلیک بر روی لینک لاگین نمایش دهیم و هدایت به صفحه‌ی لیست محصولات را پس از لاگین و مخفی کردن لینک لاگین و نمایش لینک خروج را در این حالت پیاده سازی کنیم. برای این منظور ابتدا اینترفیس خالی کاربر را ایجاد می‌کنیم:
 >ng g i user/user
که سبب ایجاد فایل src\app\user\user.ts خواهد شد. این اینترفیس را به صورت زیر تکمیل می‌کنیم:
export interface IUser {
    id: number;
    userName: string;
    isAdmin: boolean;
}

پس از آن یک سرویس ابتدایی اعتبارسنجی کاربران را نیز اضافه خواهیم کرد:
 >ng g s user/auth -m user/user.module
که سبب افزوده شدن سرویس auth.service.ts و همچنین به روز رسانی خودکار قسمت providers ماژول user.module.ts نیز می‌شود:
 installing service
  create src\app\user\auth.service.spec.ts
  create src\app\user\auth.service.ts
  update src\app\user\user.module.ts
اگر نام ماژول را ذکر نکنیم، سرویس مدنظر تولید خواهد شد، اما قسمت providers هیچ ماژولی به صورت خودکار تکمیل نمی‌شود.

پس از ایجاد قالب ابتدایی فایل auth.service.ts آن‌را به نحو ذیل تکمیل کنید:
import { IUser } from './user';
import { Injectable } from '@angular/core';

@Injectable()
export class AuthService {
  currentUser: IUser;

  constructor() { }

  isLoggedIn(): boolean {
    return !this.currentUser;
  }

  login(userName: string, password: string): boolean {
    if (!userName || !password) {
      return false;
    }

    if (userName === 'admin') {
      this.currentUser = {
        id: 1,
        userName: userName,
        isAdmin: true
      };
      return true;
    }

    this.currentUser = {
      id: 2,
      userName: userName,
      isAdmin: false
    };
    return true;
  }

  logout(): void {
    this.currentUser = null;
  }
}
در اینجا اگر کاربر هر نوع کلمه‌ی عبور و یا نام کاربری را وارد کند، به سیستم وارد خواهد شد. اگر نامش admin باشد، دسترسی admin پیدا می‌کند و همچنین متدهای logout با null کردن یوزر وارد شده‌ی به سیستم و isLoggedIn برای مشخص بودن نال نبودن شیء کاربر جاری، به این سرویس اضافه شده‌اند.

سپس کامپوننت لاگین واقع در فایل src\app\user\login\login.component.ts را به نحو ذیل تکمیل کنید:
import { Router } from '@angular/router';
import { AuthService } from './../auth.service';

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  errorMessage: string;
  pageTitle = 'Log In';

  constructor(private authService: AuthService,
    private router: Router) { }

  ngOnInit() {
  }

  login(loginForm: NgForm) {
    if (loginForm && loginForm.valid) {
      let userName = loginForm.form.value.userName;
      let password = loginForm.form.value.password;
      if (this.authService.login(userName, password)) {
        this.router.navigate(['/products']);
      }
    } else {
      this.errorMessage = 'Please enter a user name and password.';
    };
  }
}
در این کامپوننت دو سرویس AuthService، که پیشتر ایجاد کردیم و سرویس Router، به سازنده‌ی کلاس تزریق شده‌اند.
از AuthService برای اعتبارسنجی کاربر و لاگین او به سیستم استفاده می‌کنیم و از سرویس مسیریاب Angular جهت فراخوانی متد navigate آن به صفحه‌ی مشاهده‌ی محصولات، پس از لاگین کاربر استفاده شده‌است.

اکنون می‌خواهیم قالب این کامپوننت را نیز تکمیل کنیم. پیش از آن به فایل src\app\user\user.module.ts مراجعه کرده و در قسمت imports آن FormsModule را نیز اضافه کنید:
import { FormsModule } from '@angular/forms';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    UserRoutingModule
  ],

سپس فایل src\app\user\login\login.component.html را به نحو ذیل تغییر دهید:
<div class="panel panel-default">
  <div class="panel-heading">
    {{pageTitle}}
  </div>

  <div class="panel-body">
    <form class="form-horizontal" novalidate (ngSubmit)="login(loginForm)" #loginForm="ngForm" autocomplete="off">
      <fieldset>
        <div class="form-group" [ngClass]="{'has-error': (userNameVar.touched || 
                                               userNameVar.dirty) && 
                                               !userNameVar.valid }">
          <label class="col-md-2 control-label" for="userNameId">User Name</label>
          <div class="col-md-8">
            <input class="form-control" id="userNameId" type="text" 
                   placeholder="User Name (required)" required 
                   (ngModel)="userName" name="userName" #userNameVar="ngModel" />
            <span class="help-block" *ngIf="(userNameVar.touched ||
                                             userNameVar.dirty) &&
                                             userNameVar.errors">
                            <span *ngIf="userNameVar.errors.required">
                                User name is required.
                            </span>
            </span>
          </div>
        </div>

        <div class="form-group" [ngClass]="{'has-error': (passwordVar.touched || 
                                               passwordVar.dirty) && 
                                               !passwordVar.valid }">
          <label class="col-md-2 control-label" for="passwordId">Password</label>

          <div class="col-md-8">
            <input class="form-control" id="passwordId" type="password" 
                   placeholder="Password (required)" required 
                  (ngModel)="password" name="password" #passwordVar="ngModel" />
            <span class="help-block" *ngIf="(passwordVar.touched ||
                                             passwordVar.dirty) &&
                                              passwordVar.errors">
                            <span *ngIf="passwordVar.errors.required">
                                Password is required.
                            </span>
            </span>
          </div>
        </div>

        <div class="form-group">
          <div class="col-md-4 col-md-offset-2">
            <span>
               <button class="btn btn-primary"
                       type="submit"
                       style="width:80px;margin-right:10px"
                       [disabled]="!loginForm.valid">
                               Log In
               </button>
            </span>
            <span>
                <a class="btn btn-default"
                   [routerLink]="['/welcome']">
                     Cancel
                </a>
            </span>
          </div>
        </div>
      </fieldset>
    </form>
    <div class="has-error" *ngIf="errorMessage">{{errorMessage}}</div>
  </div>
</div>
تا اینجا صفحه‌ی لاگین نمایش داده شده و کاربر می‌تواند به سیستم وارد شود. تا زمانیکه کلمه‌ی عبور و نام کاربری وارد نشده باشند، دکمه‌ی login این فرم غیرفعال باقی می‌ماند. پس از آن کاربر با هر نوع ترکیبی از کلمه‌ی عبور و نام کاربری می‌تواند به سیستم وارد شده و بلافاصله به صفحه‌ی لیست محصولات هدایت می‌شود.

اکنون می‌خواهیم پس از ورود او، نام او را نمایش داده و همچنین دکمه‌ی logout را بجای login در منوی بالای سایت نمایش دهیم. به همین جهت در قالب کامپوننت App که منوی برنامه در آن تنظیم شده‌است، نیاز است بتوانیم به سرویس Auth سفارشی دسترسی یافته و خروجی متد isLoggedIn آن‌را بررسی کنیم. به همین منظور به فایل src\app\app.component.ts مراجعه کرده و آن‌را به صورت ذیل تکمیل کنید:
import { Router } from '@angular/router';
import { AuthService } from './user/auth.service';
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  pageTitle: string = 'Routing Lab';

  constructor(private authService: AuthService,
    private router: Router) { }

  logOut(): void {
    this.authService.logout();
    this.router.navigateByUrl('/welcome');
  }
}
در اینجا دو سرویس Auth و Router به سازنده‌ی کامپوننت App تزریق شده‌اند. به این ترتیب می‌توان از شیء authService در قالب این کامپوننت برای دسترسی به متد isLoggedIn و سایر خواص این سرویس استفاده کرد. همچنین از سرویس مسیریاب Angular برای پیاده سازی logout و هدایت کاربر به صفحه‌ی welcome کمک گرفته‌ایم. در اینجا از متد navigateByUrl استفاده شده‌است؛ از این جهت که پس از Logout دیگر حفظ URL Segments موجود بی‌مفهوم است و تمام آن‌ها باید پاک شده و با آدرس جدید جایگزین شوند.
پس از این تغییرات، اکنون می‌توان قالب src\app\app.component.html را به نحو ذیل تکمیل کرد:
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <a class="navbar-brand">{{title}}</a>
    <ul class="nav navbar-nav">
      <li>
        <a [routerLink]="['/home']">Home</a>
      </li>
      <li>
        <a [routerLink]="['/products']">Product List</a>
      </li>
    </ul>
    <ul class="nav navbar-nav navbar-right">
      <li *ngIf="authService.isLoggedIn()">
        <a>Welcome {{ authService.currentUser.userName }}</a>
      </li>
      <li *ngIf="!authService.isLoggedIn()">
        <a [routerLink]="['/login']">Log In</a>
      </li>
      <li *ngIf="authService.isLoggedIn()">
        <a (click)="logOut()">Log Out</a>
      </li>
    </ul>
  </div>
</nav>
<div class="container">
  <router-outlet></router-outlet>
</div>
همانطور که مشاهده می‌کنید، دوبار لاگین بودن کاربر جاری توسط متد authService.isLoggedIn بررسی شده‌است. اگر خروجی این متد true باشد، نام کاربری شخص به همراه لینک Logout نمایش داده می‌شود. اگر خروجی این متد false باشد، تنها لینک login نمایان شده و مابقی گزینه‌ها (لینک لاگین و نمایش نام شخص) از صفحه حذف می‌شوند.

اکنون اگر برنامه را توسط دستور ng serve -o اجرا کنید، صفحه‌ی لاگین و منوی بالای صفحه چنین شکلی را خواهد داشت:


پس از لاگین، لینک لاگین از منو حذف شده و سپس نام کاربری و لینک به logout نمایان می‌شوند.


اینبار اگر بر روی logout کلیک کنید، نام کاربری و لینک logout از صفحه حذف و مجددا لینک لاگین نمایش داده می‌شود.


کدهای کامل این قسمت را از اینجا می‌توانید دریافت کنید: angular-routing-lab-01.zip
برای اجرای آن فرض بر این است که پیشتر Angular CLI را نصب کرده‌اید. سپس از طریق خط فرمان به ریشه‌ی پروژه وارد شده و دستور npm install را صادر کنید تا وابستگی‌های آن دریافت و نصب شوند. در آخر با اجرای دستور ng serve -o برنامه ساخته شده و در مرورگر پیش فرض سیستم نمایش داده خواهد شد.
نظرات مطالب
پیاده سازی JSON Web Token با ASP.NET Web API 2.x
سلام
وقتی در متد هایی از controller از [JwtAuthorize] استفاده میکنم در بعضی از مواقع اررور زیر رو میده و سیستم به مدت چند دقیقه از کار میافته و اررور 500 میده. ممنون میشم راهنمایی کنید که باید چیکار کنم. ممنون

نظرات مطالب
EF Code First #10
آقای نصیری سلام.
روشی برای خرید یا استفاده دائمی از Ef profiler نیست؟ من تابحال چندین ایمیل ساختم و اونو دانلود کردم تا برام کار کنه. ممنون میشم اگه راهنمایی کنید. یاعلی.
نظرات مطالب
اعمال تزریق وابستگی‌ها به مثال رسمی ASP.NET Identity
سلام مجدد؛ دو تا راهنمایی دیگه از دوستان می‌خواستم.
1- همانطور که عنوان شد برای راهکارهای single page app و راهکارهای صرفا WebApi بهتر است از روش jwt استفاده گردد. حالا اگر سیستم نرم افزاری ما ترکیبی باشه(ASS.NET MVC و WebApi و ...) آیا پیاده سازی و توسعه همین سیستم منطقی‌تر نیست؟
2- روال کاری که در ASP.NET Identity در اینجا و در مثال رسمی خود مایکروسافت هستش بصورت ثبت نام و فعال سازی احراز هویت دو مرحله ای بعد از ثبت نام و در کنترل پنل کاربر(User Profile) هستش. ولی اگه بخوایم راهکار ما بصورت ثبت نام کاربر(نام کاربری - رمز عبور - تلفن همراه و ...) باشه و پس از ثبت نام با ارسال کد فعال سازی به تلفن همراه یا ایمیل کاربر و وارد کردن این کد توسط کاربر در صفحه مخصوص خودش(Verify Code) باشه(سیستم احراز هویت برنامه هایی مثل تلگرام و ...) آیا تابع Register دوباره بازنویسی باید بشه(چه در MVC Controller چه در WebApi Controller) یا توابع جدیدی برای این کار تعریف بشه. البته خب فکر میکنم باید View Model‌های جدید تعریف بشه چون یه مقدار اون قسمت ViewModel‌های داخل پروژه(Register  و ...) برای بنده گنگ بود برای پیاده سازی این کار مثل FactorViewModel و  SendCodeViewModel.
ممنون میشم یه مقدار بنده رو راهنمایی کنید تو این مبحث یا اگه پیاده سازی و مثال خاصی با پیاده سازی در این زمینه می‌شناسید به بنده معرفی کنید.
نظرات مطالب
بررسی علت CPU Usage بالای برنامه در حال اجرا
با سلام خدمت آقای نصیری
چند وقتی است روی یکی از سرورهی ما مش out of memory به وجود آمده
مشخصات سرور ویندوز 2003 سی دو بیتی رم بالای 4 گیگابایت که با سویچ /PAE در فایل بوت ... این حافظه به ویندوز معرفی شده در
ضمن اینکه Lock Page in memory برای یوزری که سرویس IIS را Start کرده تنظیم شده در این حالت باز ما خطا را میگیرم
چیزی که به ذخن من میرسه ما در برنامه از کریستال ریپورت استفاده کردیم که داخل اون یک library ار نوع com وجود داره که کار
تبدیل تاریخ میلادی به شمسی رو انجام میده فکر میکنم به خاطر اینکه این کتابخانه به شکل unmanage code است
سوالی که دارم اینه
 چه طور می توانم مطمئن بشم مشکل از این کتابخانه است و یا خیر

لازم میدونم اشاره کنم تعداد کاربرای سایت بالا و همچنین این سرور مختص iis  است و به هیچ عنوان SQL روی اون نصب نمی باشد
مطالب
کلاس کمکی جهت مشاهده آیتم های موجود در حافظه کش و حذف آنها
مواقع بسیاری پیش می‌آید که در زمان کار با یک نرم افزار تحت وب زمان اشکال زدایی پیش می‌آید که به دلیل موجود بودن داده در حافظه کش برنامه نویس نمی‌تواند داده‌های واقعی را ببیند و داده‌های موجود در حافظه کش را مشاهده می‌کند (بیشتر مواقعی که از طریق بانک اطلاعاتی مستقیما اقدام به حذف و اضافه داده می‌کنیم) در این بخش یک کلاس آماده کرده ام که همیشه خودم در نرم افزار هایم استفاده می‌کنم.

شما می‌توانید این کلاس را به یک GridView یا کنترل‌های دیگر بایند کرده و کلید‌های موجود در حافظه کش را مشاهده کنید، و در صورتی که خواستید یک کلید خاص را از حافظه کش حذف نمایید (البته این کلاس بیشتر برای مدیر نرم فزار کاربرد دارد).

  می‌توانید فایل مورد نظر را از طریق لینک کلاس کمکی جهت مشاهده آیتم‌های موجود در حافظه کش و حذف آنها دانلود نمایید.
در کلاس زیر هر کدام از قسمت‌ها را شرح می‌دهیم.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web;
using System.Web.Caching;

namespace PWS.BLL
{
    /// <summary>
    /// کلاس  آیتم‌های حافظه کش
    /// </summary>
    [DataObject(true)]
    public class CacheItems
    {
#region Constructors (2) 

        /// <summary>
        /// سازنده اصلی
        /// </summary>
        /// <param name="cacheItem">عنوان آیتم ذخیره شده در حافظه کش</param>
        public CacheItems(String cacheItem)
        {
            CacheItem = cacheItem;
        }

        /// <summary>
        /// سازنده پیش فرض
        /// </summary>
        public CacheItems(){}

#endregion Constructors 

#region Properties (2) 

        /// <summary>
        /// کش کانتکست جاری
        /// </summary>
        /// <value>
        /// The cache.
        /// </value>
        private static Cache Cache
        {
            get {return HttpContext.Current.Cache; }
        }

        /// <summary>
        /// عنوان آیتم ذخیره شده در حافظه کش
        /// </summary>
        public String CacheItem{ get; set;}

#endregion Properties 

#region Methods (4) 

// Public Methods (3) 

        /// <summary>
        /// لیست تمام آیتم‌های ذخیره شده در حافظه کش
        /// </summary>
        /// <returns></returns>
        public List<CacheItems> GetCaches()
        {
            var items = new List<CacheItems>();
            //بازیابی کل کلید‌های موجود در حافظه کش و اضافه کردن آن به لیست مربوطه
            var enumerator = Cache.GetEnumerator();
            while (enumerator.MoveNext())
            {
                 items.Add(new CacheItems(enumerator.Key.ToString()));
            }
            return items;
        }

        /// <summary>
        /// حذف آیتم جاری از حافظه کش
        /// </summary>
        public void RemoveItemFromCache()
        {
            RemoveItemFromCache(CacheItem);
        }

        /// <summary>
        /// حذف کردن یک آیتم از حافظه کش
        /// </summary>
        /// <param name="key">کلید ذخیره شده در حافظه کش</param>
        public static void RemoveItemFromCache(string key)
        {
            PurgeCacheItems(key);
        }
// Private Methods (1) 

        /// <summary>
        /// حذف کردن یک ایتم از حافظه کش با پشوند وارد شده
        /// </summary>
        /// <param name="prefix">پیشوندی از کلید موجود در حافظه کش</param>
        private static void PurgeCacheItems(String prefix)
        {
            prefix = prefix.ToLower();
            var itemsToRemove = new List<String>();
           //لیست آیتم‌های موجود در حافظه کش
            var enumerator = Cache.GetEnumerator();
            while (enumerator.MoveNext())
            {
//در صورتی که کلید مورد نظر با پارامتر وارد شده شروع شده باشد آن را به یک لیست اضافه می‌کنیم
 if (enumerator.Key.ToString().ToLower().StartsWith(prefix)) itemsToRemove.Add(enumerator.Key.ToString()); } //لیست مورد نظر را پیمایش کرده و گزینه‌های آن را از حافظه کش حذف می‌کنیم foreach (var itemToRemove in itemsToRemove) Cache.Remove(itemToRemove); } #endregion Methods  } }
موفق وموید باشید
نظرات مطالب
آموزش TypeScript #2
سلام من زمانی که فایل پروژه رو ویرایش کردم به این مشکل برخوردم . امکانش هست بگید مشکل از کجاست :
Error 1 The command ""C:\Program Files (x86)\Microsoft SDKs\TypeScript\0.8.0.0\tsc" -target ES5 " exited with code 3. c:\users\IT\documents\visual studio 2012\Projects\MvcApplication6\MvcApplication6\MvcApplication6.csproj 259 5 MvcApplication6