بهتره رو یه هاست دیگه آپلودش کنید و لینک بدید.
سپاسگذارم
InMemoryWebApiModule.forRoot(ProductData, { delay: 1000 }),
{ path: 'products', component: ProductListComponent, data: { pageTitle: 'Product List'} },
this.pageTitle = this.route.snapshot.data['pageTitle'];
> ng g s product/ProductResolver -m product/product.module installing service create src\app\product\product-resolver.service.spec.ts create src\app\product\product-resolver.service.ts update src\app\product\product.module.ts
providers: [ProductService, ProductResolverService]
import { Injectable } from '@angular/core'; import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/catch'; import 'rxjs/add/observable/of'; import 'rxjs/add/operator/map'; import { ProductService } from './product.service'; import { IProduct } from './iproduct'; @Injectable() export class ProductResolverService implements Resolve<IProduct> { constructor(private productService: ProductService, private router: Router) { } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<IProduct> { let id = route.params['id']; if (isNaN(id)) { console.log(`Product id was not a number: ${id}`); this.router.navigate(['/products']); return Observable.of(null); } return this.productService.getProduct(+id) .map(product => { if (product) { return product; } console.log(`Product was not found: ${id}`); this.router.navigate(['/products']); return null; }) .catch(error => { console.log(`Retrieval error: ${error}`); this.router.navigate(['/products']); return Observable.of(null); }); } }
export class ProductResolverService implements Resolve<IProduct> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<IProduct> {
import { ProductResolverService } from './product-resolver.service'; const routes: Routes = [ { path: 'products', component: ProductListComponent }, { path: 'products/:id', component: ProductDetailComponent, resolve: { product: ProductResolverService } }, { path: 'products/:id/edit', component: ProductEditComponent, resolve: { product: ProductResolverService } } ];
constructor(private route: ActivatedRoute) { } ngOnInit(): void { this.product = this.route.snapshot.data['product']; }
ngOnInit(): void { this.route.data.subscribe(data => { this.onProductRetrieved(data['product']); }); }
>ng g c Dashboard/CallProtectedApi
import { CallProtectedApiComponent } from "./call-protected-api/call-protected-api.component"; const routes: Routes = [ { path: "callProtectedApi", component: CallProtectedApiComponent, data: { permission: { permittedRoles: ["Admin", "User"], deniedRoles: null } as AuthGuardPermission }, canActivate: [AuthGuard] } ];
<li *ngIf="isLoggedIn" routerLinkActive="active"> <a [routerLink]="['/callProtectedApi']">Call Protected Api</a> </li>
import { Component, OnInit } from "@angular/core"; import { AuthService } from "../../core/services/auth.service"; @Component({ selector: "app-call-protected-api", templateUrl: "./call-protected-api.component.html", styleUrls: ["./call-protected-api.component.css"] }) export class CallProtectedApiComponent implements OnInit { isAdmin = false; isUser = false; result: any; constructor(private authService: AuthService) { } ngOnInit() { this.isAdmin = this.authService.isAuthUserInRole("Admin"); this.isUser = this.authService.isAuthUserInRole("User"); } callMyProtectedAdminApiController() { } callMyProtectedApiController() { } }
<button *ngIf="isAdmin" (click)="callMyProtectedAdminApiController()"> Call Protected Admin API [Authorize(Roles = "Admin")] </button> <button *ngIf="isAdmin || isUser" (click)="callMyProtectedApiController()"> Call Protected API ([Authorize]) </button> <div *ngIf="result"> <pre>{{result | json}}</pre> </div>
getBearerAuthHeader(): HttpHeaders { return new HttpHeaders({ "Content-Type": "application/json", "Authorization": `Bearer ${this.getRawAuthToken(AuthTokenType.AccessToken)}` }); }
import { Injectable } from "@angular/core"; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from "@angular/common/http"; import { Observable } from "rxjs/Observable"; import { AuthService, AuthTokenType } from "./auth.service"; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private authService: AuthService) { } intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const accessToken = this.authService.getRawAuthToken(AuthTokenType.AccessToken); if (accessToken) { request = request.clone({ headers: request.headers.set("Authorization", `Bearer ${accessToken}`) }); } return next.handle(request); } }
import { HTTP_INTERCEPTORS } from "@angular/common/http"; import { AuthInterceptor } from "./services/auth.interceptor"; @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ] }) export class CoreModule {}
compiler.js:19514 Uncaught Error: Provider parse errors: Cannot instantiate cyclic dependency! InjectionToken_HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1
import { Injector } from "@angular/core"; constructor(private injector: Injector) { } intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const authService = this.injector.get(AuthService);
@Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private injector: Injector) { } intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const authService = this.injector.get(AuthService); const accessToken = authService.getRawAuthToken(AuthTokenType.AccessToken); if (accessToken) { request = request.clone({ headers: request.headers.set("Authorization", `Bearer ${accessToken}`) }); } return next.handle(request); } }
constructor( private authService: AuthService, private httpClient: HttpClient, @Inject(APP_CONFIG) private appConfig: IAppConfig, ) { }
callMyProtectedAdminApiController() { this.httpClient .get(`${this.appConfig.apiEndpoint}/MyProtectedAdminApi`) .map(response => response || {}) .catch((error: HttpErrorResponse) => Observable.throw(error)) .subscribe(result => { this.result = result; }); } callMyProtectedApiController() { this.httpClient .get(`${this.appConfig.apiEndpoint}/MyProtectedApi`) .map(response => response || {}) .catch((error: HttpErrorResponse) => Observable.throw(error)) .subscribe(result => { this.result = result; }); }
return next.handle(request) .catch((error: any, caught: Observable<HttpEvent<any>>) => { if (error.status === 401 || error.status === 403) { this.router.navigate(["/accessDenied"]); } return Observable.throw(error); });
@Injectable() export class AuthInterceptor implements HttpInterceptor { constructor( private injector: Injector, private router: Router) { } intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const authService = this.injector.get(AuthService); const accessToken = authService.getRawAuthToken(AuthTokenType.AccessToken); if (accessToken) { request = request.clone({ headers: request.headers.set("Authorization", `Bearer ${accessToken}`) }); return next.handle(request) .catch((error: any, caught: Observable<HttpEvent<any>>) => { if (error.status === 401 || error.status === 403) { this.router.navigate(["/accessDenied"]); } return Observable.throw(error); }); } else { // login page return next.handle(request); } } }
using ASPNETCore2JwtAuthentication.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc; namespace ASPNETCore2JwtAuthentication.WebApp.Controllers { [Route("api/[controller]")] [EnableCors("CorsPolicy")] [Authorize(Policy = CustomRoles.Editor)] public class MyProtectedEditorsApiController : Controller { public IActionResult Get() { return Ok(new { Id = 1, Title = "Hello from My Protected Editors Controller! [Authorize(Policy = CustomRoles.Editor)]", Username = this.User.Identity.Name }); } } }
callMyProtectedEditorsApiController() { this.httpClient .get(`${this.appConfig.apiEndpoint}/MyProtectedEditorsApi`) .map(response => response || {}) .catch((error: HttpErrorResponse) => Observable.throw(error)) .subscribe(result => { this.result = result; }); }
using System.Web; using System.Windows.Forms; namespace PdfReportSamples { public static class AppPath { public static string ApplicationPath { get { if (isInWeb) return HttpRuntime.AppDomainAppPath; return Application.StartupPath; } } private static bool isInWeb { get { return HttpContext.Current != null; } } } }
using System; namespace PdfReportSamples.IList { public class User { public int Id { set; get; } public string Name { set; get; } public string LastName { set; get; } public long Balance { set; get; } public DateTime RegisterDate { set; get; } } }
using System; using System.Collections.Generic; using PdfRpt.Core.Contracts; using PdfRpt.FluentInterface; namespace PdfReportSamples.IList { public class IListPdfReport { public IPdfReportData CreatePdfReport() { return new PdfReport().DocumentPreferences(doc => { doc.RunDirection(PdfRunDirection.RightToLeft); doc.Orientation(PageOrientation.Portrait); doc.PageSize(PdfPageSize.A4); doc.DocumentMetadata(new DocumentMetadata { Author = "Vahid", Application = "PdfRpt", Keywords = "Test", Subject = "Test Rpt", Title = "Test" }); }) .DefaultFonts(fonts => { fonts.Path(Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\tahoma.ttf", Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\verdana.ttf"); }) .PagesFooter(footer => { footer.DefaultFooter(DateTime.Now.ToString("MM/dd/yyyy")); }) .PagesHeader(header => { header.DefaultHeader(defaultHeader => { defaultHeader.ImagePath(AppPath.ApplicationPath + "\\Images\\01.png"); defaultHeader.Message("گزارش جدید ما"); }); }) .MainTableTemplate(template => { template.BasicTemplate(BasicTemplate.ClassicTemplate); }) .MainTablePreferences(table => { table.ColumnsWidthsType(TableColumnWidthType.Relative); table.NumberOfDataRowsPerPage(5); }) .MainTableDataSource(dataSource => { var listOfRows = new List<User>(); for (int i = 0; i < 200; i++) { listOfRows.Add(new User { Id = i, LastName = "نام خانوادگی " + i, Name = "نام " + i, Balance = i + 1000 }); } dataSource.StronglyTypedList<User>(listOfRows); }) .MainTableSummarySettings(summarySettings => { summarySettings.OverallSummarySettings("جمع کل"); summarySettings.PerviousPageSummarySettings("نقل از صفحه قبل"); summarySettings.PageSummarySettings("جمع صفحه"); }) .MainTableColumns(columns => { columns.AddColumn(column => { column.PropertyName("rowNo"); column.IsRowNumber(true); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(0); column.Width(1); column.HeaderCell("#"); }); columns.AddColumn(column => { column.PropertyName<User>(x => x.Id); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(1); column.Width(2); column.HeaderCell("شماره"); }); columns.AddColumn(column => { column.PropertyName<User>(x => x.Name); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(2); column.Width(3); column.HeaderCell("نام"); }); columns.AddColumn(column => { column.PropertyName<User>(x => x.LastName); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(3); column.Width(3); column.HeaderCell("نام خانوادگی"); }); columns.AddColumn(column => { column.PropertyName<User>(x => x.Balance); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(4); column.Width(2); column.HeaderCell("موجودی"); column.ColumnItemsTemplate(template => { template.TextBlock(); template.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)); }); column.AggregateFunction(aggregateFunction => { aggregateFunction.NumericAggregateFunction(AggregateFunction.Sum); aggregateFunction.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)); }); }); }) .MainTableEvents(events => { events.DataSourceIsEmpty(message: "رکوردی یافت نشد."); }) .Export(export => { export.ToExcel(); export.ToCsv(); export.ToXml(); }) .Generate(data => data.AsPdfFile(AppPath.ApplicationPath + "\\Pdf\\RptIListSample.pdf")); } } }
var rpt = new IListPdfReport().CreatePdfReport(); // rpt.FileName
یعنی الان یک Context به ازای کل برنامه دارید که دچار این تداخل شدید؟ معمولا در WPF و همچنین WinForms این Context به ازای هر فرم تعریف میشود و با بسته شدن آن تخریب.
حالا یک سؤال مهم! به نظر شما در اولین سؤالی که پرسیدید، یک شخص چطور میبایستی ساختار کار شما رو که بر مبنای یک Context در کل برنامه است، حدس میزد و عیب یابی میکرد؟!
adb devices adb reboot bootloader fastboot devices fastboot flash recovery TWRP.img fastboot reboot-bootloader
adb devices adb shell getprop ro.product.device adb shell getprop ro.build.product
assert(getprop("ro.product.device") == "j7elte" || getprop("ro.build.product") == "j7elte" || abort("E3004: This package is for device: j7elte; this device is " + getprop("ro.product.device") + "."););
adb devices adb push LINEAGE.zip /sdcard/ adb push GAPPS.zip /sdcard/
با اینکه توصیه نامه W3C از پایان کار پیاده سازی این قابلیت خبر میدهد ولی در حال حاضر که این مقاله تدوین شده است هنوز نهایی اعلام نشده است. برای پشتیبانی مرورگرهای قدیمی از webstorage میتوان از فایل جاوااسکریپتی Store.js کمک گرفت.
مفاهیم امنیتی و محافظت از داده ها
محدودیتهای حمایتی و حفاظتی webstorage دقیقا همانند کوکی هاست. به این معنی که وب سایتهای دیگر توانایی اتصال به webstorage سایت دیگری را ندارند. البته این مورد ممکن است برای وب سایت هایی که بر ساب دومین تکیه کردهاند ایجاد مشکل کند. برای حل این مسائل میتوانید از کتابخانههای سورس بازی چون Cross Storage که توسط Zendesk ارائه شده است، استفاده کرد.
همانند هر مکانیزم ذخیره سازی سمت کلاینت، مواردی توصیه میگردد که رعایت آنها از لحاظ امنیتی پر اهمیت است. به عنوان نمونه ذخیرهی اطلاعات شخصی و موارد حساس توصیه نمیگردد؛ چرا که احتمال دسترسی آسان نفوذگران به دادههای محلی و خواندن آنها وجود دارد.
Data Integrity یا یکپارچگی دادهها نیز در نظر گرفته شده است. باید حفاظتی در برابر عدم موفقیت ذخیره سازی دادهها نیز وجود داشته باشد. این عدم موفقیتها میتواند به دلایل زیر رخ دهد:
IndexedDB
یکی از فرایندهای ذخیره سازی دادهها که همان مزایای webstorage را ارائه میدهد indexed Database API است. این قابلیت از HTML 5 اضافه شده است و قسمتی از مشخصات webstorage شناخته نمیشود. برای همین مستنداتی در حوزهی webstorage برای آن پیدا نخواهید کرد ولی قابلیتهایی فراتر از webstorage دارد.
این قابلیت پیچیدگی بیشتری را نسبت به خود webstorage ایجاد میکند، ولی فرصتهای بسیاری را برای ذخیره سازی دادههایی با معماریهای پیچیدهتر و رابطهها را میدهد. با استفاده از IndexedDB دادهها به شکل دیتابیسهای سمت سرور RDMS ذخیره میشوند و این قابلیت را دارید که به سمت آن کوئری هایی مشابه بانکهای اطلاعاتی سمت سرور را ارسال کنید.
در قسمت آتی نحوه کدنویسی آن را فرا خواهیم گرفت.