نظرات اشتراکها
«هویت» و کار آن، دریافت حروف نمایش داده شده به عدد هست. بعد عدد نوشته شود؟
نظرات مطالب
یکپارچه کردن ELMAH با WCF RIA Services
سلام
من از روش تشخیص هویت ویندوز استفاده نمی کنم چطور می تونم جلوی دسترسی افراد به صفحه myelmah.axd رو بگیرم
ممنون
من از روش تشخیص هویت ویندوز استفاده نمی کنم چطور می تونم جلوی دسترسی افراد به صفحه myelmah.axd رو بگیرم
ممنون
اشتراکها
کتابی در مورد Angular و Firebase
What you will learn in this eBook?
We will cover the following Angular concepts in this book:
- Using Cloud Firestore with an Angular application
- Angular Material and Bootstrap
- Template-driven forms
- Form validation
- Custom pipes
- Auth-guards in Angular
- Authentication and Authorization
- Login with Google using Firebase
- Social share option using ngx-share
- Client-Side pagination using ngx-pagination
- Deploying an Angular app in Firebase
ماژول Http در Angular، برای برقراری ارتباط بین کلاینت و سمت سرور، مورد استفاده قرار میگیرد. معمولا هنگام ساخت درخواستهای Http، یکسری کدهای تکراری برای تنظیم هدر (برای اعتبارسنجی و همچنین تنظیمات دیگر) نوشته میشوند که در هر درخواست یکسان هستند. همچنین بعد از آمدن جواب (Response) از سمت سرور نیز یکسری کدهای تکراری جهت برسی کد response و یا تغییر فرمت اطلاعات رسیده، به ساختار مورد توافق نوشته خواهند شد.
برای مثال در صورتیکه در برنامه خود از اعتبار سنجی مبتنی بر توکن (Token Base Authentication) استفاده میکنید، قبل از ارسال هر درخواست (request)، کدهایی مشابه کد زیر باید نوشته شوند:
همچنین فرض کنید بعد از رسیدن جواب هر درخواست، میخواهید response code را چک کنید و خطاهای احتمالی را مدیریت کنید. مثلا درصورت دریافت کد 401، کاربر را به صفحه «ورود» و با دریافت کد 404 آنرا را به صفحه «یافت نشد» هدایت کنید و یا با دریافت کد 403 یا 500 پیغام مناسبی را نمایش دهید. بدیهی است در این صورت بعد از هر آمدن پاسخ از سمت سرور (response)، این کدها بایستی تکرار شوند.
جهت پرهیز از این کدهای تکراری، میتوان برای ماژول Http، یک interceptor واحد درنظر گرفت که تمامی کدهای تکراری را تنها یکبار داخل آن پیاده سازی کرد. مزیت این روش، مدیریت راحت کد، کاهش پیچیدگیها و همچنین حذف کدهای تکراری و یکسان سازی آنها است.
هرچند در Angular دیگر به مانند Angular 1.x مفهوم intercept بر روی Http را به صورت توکار نداریم، ولی به دلایل زیر ما نیاز به پیاده سازی interceptor برای ماژول Http را داریم:
- تنظیم هدرهای سفارشی و اصلاح آدرس، قبل از ارسال درخواست به سمت سرور
- تنظیم token در هدر درخواست، جهت اعتبار سنجی
- مدیریت سراسری خطاهای Http
- انجام هرگونه عملیات crosscutting
حالا که Angular مفهموم intercept را برای ماژول Http خود به صورت توکار درنظر نگرفته است، راهحل چیست؟ بهترین راهحل برای پیاده سازی موارد مطرح شده در بالا، ارث بری و یا گسترش (extend) مستقیم ماژول Http است:
تمامی افعال Http، از جمله get ،post ،put ،delete ،patch ،head و options در نهایت از متد request موجود در ماژول http برای ارسال درخواست خود استفاده میکنند. به همین جهت تمامی عملیات crosscutting را در این متد پیاده سازی کردهایم. به علاوه قبل از ارسال درخواست، توسط متد updateUrl آدرس url خود را اصلاح کردهایم. همچنین توسط متد getRequestOptionArgs هدر درخواست را جهت اعتبار سنجی مقداردهی کردهایم. در اینجا بعد از ارسال درخواست و آمدن response از سمت سرور، توسط catch خطاهای احتمالی را برسی کردهایم.
نکته: به عنوان مثال، در صورتیکه قصد دارید، برای درخواستهایی از جنس get، هدر متفاوتی نسبت به دیگر درخواستها داشته باشید، آنگاه پیاده سازی عملیات اصلاح هدر در متد request جواب کار را نخواهد داد. برای حل این موضوع میتوانید به جای اصلاح header در متد request، تمامی متدهای get ،post، put ،delete ،patch ،head و options را باز نویسی کرده و در هرکدام از این متدها اینکار را انجام دهید.
حالا با تغییر قسمت providers در ماژول اصلی برنامه به شکل زیر، Angular را مجبور میکنیم بجای استفاده از ماژول Http توکار خود، از ماژول جدید InterceptedHttp استفاده کند:
همه چیز آماده است. اکنون کافی است ماژول Http را در سرویس یا کامپوننتهای خود تزریق کرده و درخواستهای Http را بدون هیچگونه نوشتن کد اضافی برای تنظیم هدر و غیره (با فرض اینکه تمامی آنها در متد request از ماژول http نوشته شدهاند)، به مانند قبل صادر کنید. برای نمونه کد زیر را ببینید.
با اینکه Angular از interceptor پشتیبانی نمیکند، ولی کتابخانههایی برای ایجاد قابلیت مشابه interceptor به وجود آمدهاند که برخی از آنها عبارتند از: angular2-cool-http ، ng2-http-interceptor ، ng2-interceptors . به جای extend مستقیم ماژول Http توسط خودتان، اینکار را میتوانید به این کتابخانهها بسپارید.
برای مثال در صورتیکه در برنامه خود از اعتبار سنجی مبتنی بر توکن (Token Base Authentication) استفاده میکنید، قبل از ارسال هر درخواست (request)، کدهایی مشابه کد زیر باید نوشته شوند:
let headers = new Headers(); let token = localStorage.getItem('token'); headers.append('Authorization', 'bearer ' + token); this.http.get('/api/controller/action', { headers: headers })
همچنین فرض کنید بعد از رسیدن جواب هر درخواست، میخواهید response code را چک کنید و خطاهای احتمالی را مدیریت کنید. مثلا درصورت دریافت کد 401، کاربر را به صفحه «ورود» و با دریافت کد 404 آنرا را به صفحه «یافت نشد» هدایت کنید و یا با دریافت کد 403 یا 500 پیغام مناسبی را نمایش دهید. بدیهی است در این صورت بعد از هر آمدن پاسخ از سمت سرور (response)، این کدها بایستی تکرار شوند.
جهت پرهیز از این کدهای تکراری، میتوان برای ماژول Http، یک interceptor واحد درنظر گرفت که تمامی کدهای تکراری را تنها یکبار داخل آن پیاده سازی کرد. مزیت این روش، مدیریت راحت کد، کاهش پیچیدگیها و همچنین حذف کدهای تکراری و یکسان سازی آنها است.
هرچند در Angular دیگر به مانند Angular 1.x مفهوم intercept بر روی Http را به صورت توکار نداریم، ولی به دلایل زیر ما نیاز به پیاده سازی interceptor برای ماژول Http را داریم:
- تنظیم هدرهای سفارشی و اصلاح آدرس، قبل از ارسال درخواست به سمت سرور
- تنظیم token در هدر درخواست، جهت اعتبار سنجی
- مدیریت سراسری خطاهای Http
- انجام هرگونه عملیات crosscutting
حالا که Angular مفهموم intercept را برای ماژول Http خود به صورت توکار درنظر نگرفته است، راهحل چیست؟ بهترین راهحل برای پیاده سازی موارد مطرح شده در بالا، ارث بری و یا گسترش (extend) مستقیم ماژول Http است:
import { Injectable } from "@angular/core"; import { ConnectionBackend, RequestOptions, Request, RequestOptionsArgs, Response, Http, Headers } from "@angular/http"; import { Observable } from "rxjs/Rx"; import 'rxjs/add/operator/catch'; import 'rxjs/add/observable/throw'; @Injectable() export class InterceptedHttp extends Http { constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) { super(backend, defaultOptions); } request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> { // اصلاح url if (typeof (url) === 'string') url = this.updateUrl((url as string)); else url.url = this.updateUrl((url as Request).url); return super.request(url, this.getRequestOptionArgs(options)).catch((err: Response) => { // Exception handling switch (err.status) { case 400: console.log('interceptor: 400'); console.log(err); break; case 404: console.log('interceptor: 404'); console.log(err); break; case 500: console.log('interceptor: 500'); console.log(err); break; case 401: console.log('interceptor: 401'); console.log(err); break; case 403: console.log('interceptor: 403'); console.log(err); break; default: console.log('interceptor: ' + err.status); console.log(err); } return Observable.throw(err); }); } private updateUrl(req: string) { return `http://localhost:61366/api/${req}` } private getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs { if (options == null) { options = new RequestOptions(); } if (options.headers == null) { options.headers = new Headers(); } // هدر درخواست تنظیم let token = localStorage.getItem('token'); options.headers.append('Authorization', 'bearer ' + token); return options; } }
نکته: به عنوان مثال، در صورتیکه قصد دارید، برای درخواستهایی از جنس get، هدر متفاوتی نسبت به دیگر درخواستها داشته باشید، آنگاه پیاده سازی عملیات اصلاح هدر در متد request جواب کار را نخواهد داد. برای حل این موضوع میتوانید به جای اصلاح header در متد request، تمامی متدهای get ،post، put ،delete ،patch ،head و options را باز نویسی کرده و در هرکدام از این متدها اینکار را انجام دهید.
حالا با تغییر قسمت providers در ماژول اصلی برنامه به شکل زیر، Angular را مجبور میکنیم بجای استفاده از ماژول Http توکار خود، از ماژول جدید InterceptedHttp استفاده کند:
//… providers: [{ provide: Http, useFactory: (backend: XHRBackend, options: RequestOptions) => { return new InterceptedHttp(backend, options); }, deps: [XHRBackend, RequestOptions], }], //…
همه چیز آماده است. اکنون کافی است ماژول Http را در سرویس یا کامپوننتهای خود تزریق کرده و درخواستهای Http را بدون هیچگونه نوشتن کد اضافی برای تنظیم هدر و غیره (با فرض اینکه تمامی آنها در متد request از ماژول http نوشته شدهاند)، به مانند قبل صادر کنید. برای نمونه کد زیر را ببینید.
import { Http, URLSearchParams } from '@angular/http'; //… constructor(private _http: Http) { } ngOnInit() { let urlSearchParams: URLSearchParams = new URLSearchParams(); urlSearchParams.append('page', page.toString()); urlSearchParams.append('count', count.toString()); let params = urlSearchParams.toString(); this._http.get(`/cars`, { params: params }) .subscribe(result => { console.log('service: Succ'); this.cars = result.json(); }, err => { console.log('service: error'); }); } //…
اشتراکها
ویژگیهای جدید NET Core 3.0.
اشتراکها
JetBrains Rider 2017.2 منتشر شد
- Support for .NET Core 2.0: you can now edit, run, debug, test, navigate and refactor your shiny new .NET Core applications.
- Rider 2017.2 comes with ReSharper 2017.2 as its engine for providing .NET support. This means a number of features announced with ReSharper 2017.2 are now available in Rider.
به روز رسانی
- بستهی NET Core Windows Server Hosting. مخصوص NET Core 1.0.1. را از اینجا دریافت کنید.
ماخذ (قسمت Windows (Server Hosting))
- بستهی NET Core Windows Server Hosting. مخصوص NET Core 1.0.1. را از اینجا دریافت کنید.
ماخذ (قسمت Windows (Server Hosting))
خیر؛ نمیتوان. ASP.NET Core Identity برای این نوع کارها (تامین هویت چندین برنامهی مجزا) طراحی نشده و هدفش فقط و فقط پوشش یک تک برنامهاست. اطلاعات بیشتر: «نیاز به تامین کنندهی هویت مرکزی»
مطالب دورهها
استفاده از Full Text Search بر روی اسناد XML
امکان استفادهی همزمان قابلیت Full Text Search و اسناد XML ایی نیز در SQL Server پیش بینی شدهاست. به این ترتیب میتوان متون این اسناد را ایندکس و جستجو کرد. در این حالت تگهای XML ایی و ویژگیها، به صورت خودکار حذف شده و در نظر گرفته نمیشوند. Syntax استفاده از Full text search در اینجا با سایر حالات و ستونهای متداول رابطهای SQL Server تفاوتی ندارد. به علاوه امکان ترکیب آن با یک XQuery نیز میسر است. در این حالت، Full text search، ابتدا انجام شده و سپس با استفاده از XQuery میتوان بر روی این نتایج، نودها، مسیرها و ویژگیهای خاصی را جستجو کرد.
نحوهی استفاده از Full Text Search بر روی ستونهای XML ایی
برای آزمایش، ابتدا یک جدول جدید را که حاوی ستونی XML ایی است، ایجاد کرده و سپس چند سند XML را که حاوی متونی نسبتا طولانی هستند، در آن ثبت میکنیم. ذکر CONSTRAINT در اینجا جهت دستور ایجاد ایندکس Full Text Search ضروری است.
سپس با استفاده از دستورات ذیل، Full text search را بر روی ستون doc جدول ایجاد شده، فعال میکنیم:
اکنون میتوانیم با ترکیبی از امکانات Full Text Search و XQuery، از ستون doc، کوئریهای پیشرفته و سریعی را تهیه کنیم.
راه اندازی سرویس Full Text Search
البته پیش از ادامهی بحث به کنسول سرویسهای ویندوز مراجعه کرده و مطمئن شوید که سرویس SQL Full-text Filter Daemon Launcher MSSQLSERVER در حال اجرا است. در غیراینصورت با خطای ذیل مواجه خواهید شد:
اگر این سرویس در حال اجرا است و باز هم خطای فوق ظاهر شد، مجددا به کنسول سرویسهای ویندوز مراجعه کرد، در برگهی خواص سرویس SQL Full-text Filter Daemon Launcher MSSQLSERVER، گزینهی logon را یافته و آنرا به local system account تغییر دهید و سپس سرویس را ری استارت کنید. پس از آن نیاز است دستور ذیل را نیز اجرا کنید:
بعد از اینکار، بازسازی مجدد Full text search را فراموش نکنید. در این حالت در management studio، به بانک اطلاعاتی مورد نظر مراجعه کرده، نود Storage / Full Text Catalog را باز کنید. سپس بر روی FT_CATALOG ایجاد شده در ابتدای بحث کلیک راست کرده و از منوی ظاهر شده، گزینهی Rebuild را انتخاب کنید. در غیراینصورت کوئریهای ادامهی بحث، خروجی خاصی را نمایش نخواهند داد.
استفاده از متد Contains
در ادامه، نحوهی ترکیب امکانات Full text search و XQuery را ملاحظه میکنید:
ابتدا توسط متد Contains مرتبط به Full text search، ردیفهای مورد نظر را یافته و سپس بر روی آنها با استفاده از XQuery جستجوی دلخواهی را انجام میدهیم؛ از این جهت که Full text search تنها متون فیلدهای XML ایی را ایندکس میکند و نه تگهای آنها را.
خروجی کوئری فوق، Sample book title 1 است.
Full text search امکانات پیشرفتهتری را نیز ارائه میدهد. برای مثال در ردیفهای ثبت شده داریم fox jumps، اما در متن ورودی عبارت جستجو، jumped را وارد کرده و به دنبال نزدیکترین رکورد به آن خواهیم گشت:
و یا دو کلمهی نزدیک به هم را میتوان جستجو کرد:
نکتهای در مورد متد Contains
هم Full text search و هم XQuery، هر دو دارای متدی به نام Contains هستند اما یکی نمیباشند.
در اینجا نحوهی استفاده از متد contains مرتبط با XQuery را مشاهده میکنید. اگر این کوئری را اجرا کنید، نتیجهای را دریافت نخواهید کرد. زیرا در ردیفها داریم quick brown fox و نه Quick Brown Fox (حروف ابتدای کلمات، بزرگ نیستند).
بنابراین متد contains مرتبط با XQuery یک جستجوی case sensitive را انجام میدهد.
نحوهی استفاده از Full Text Search بر روی ستونهای XML ایی
برای آزمایش، ابتدا یک جدول جدید را که حاوی ستونی XML ایی است، ایجاد کرده و سپس چند سند XML را که حاوی متونی نسبتا طولانی هستند، در آن ثبت میکنیم. ذکر CONSTRAINT در اینجا جهت دستور ایجاد ایندکس Full Text Search ضروری است.
CREATE TABLE ftsXML( id INT IDENTITY PRIMARY KEY, doc XML NULL CONSTRAINT UQ_FTS_Id UNIQUE(id) ) GO INSERT ftsXML VALUES(' <book> <title>Sample book title 1</title> <author>Vahid</author> <chapter ID="1"> <title>Chapter 1</title> <content> "The quick brown fox jumps over the lazy dog" is an English-language pangram—a phrase that contains all of the letters of the English alphabet. It has been used to test typewriters and computer keyboards, and in other applications involving all of the letters in the English alphabet. Owing to its brevity and coherence, it has become widely known. </content> </chapter> <chapter ID="2"> <title>Chapter 2</title> <content> In publishing and graphic design, lorem ipsum is a placeholder text commonly used to demonstrate the graphic elements of a document or visual presentation. By replacing the distraction of meaningful content with filler text of scrambled Latin it allows viewers to focus on graphical elements such as font, typography, and layout. </content> </chapter> </book> ') INSERT ftsXML VALUES(' <book> <title>Sample book title 2</title> <author>Farid</author> <chapter ID="1"> <title>Chapter 1</title> <content> The original passage began: Neque porro quisquam est qui dolorem ipsum quia dolor sit amet consectetur adipisci velit </content> </chapter> <chapter ID="2"> <title>Chapter 2</title> <content> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </content> </chapter> </book> ') GO
CREATE FULLTEXT CATALOG FT_CATALOG GO CREATE FULLTEXT INDEX ON ftsXML([doc]) KEY INDEX UQ_FTS_Id ON ([FT_CATALOG], FILEGROUP [PRIMARY]) GO
راه اندازی سرویس Full Text Search
البته پیش از ادامهی بحث به کنسول سرویسهای ویندوز مراجعه کرده و مطمئن شوید که سرویس SQL Full-text Filter Daemon Launcher MSSQLSERVER در حال اجرا است. در غیراینصورت با خطای ذیل مواجه خواهید شد:
SQL Server encountered error 0x80070422 while communicating with full-text filter daemon host (FDHost) process.
sp_fulltext_service 'restart_all_fdhosts' go
استفاده از متد Contains
در ادامه، نحوهی ترکیب امکانات Full text search و XQuery را ملاحظه میکنید:
-- استفاده از ایکس کوئری برای جستجو در نتایج حاصل SELECT T.doc.value('(/book/title)[1]', 'varchar(100)') AS title FROM -- استفاده از اف تی اس برای جستجو (SELECT * FROM ftsXML WHERE CONTAINS(doc, '"Quick Brown Fox "')) AS T
خروجی کوئری فوق، Sample book title 1 است.
Full text search امکانات پیشرفتهتری را نیز ارائه میدهد. برای مثال در ردیفهای ثبت شده داریم fox jumps، اما در متن ورودی عبارت جستجو، jumped را وارد کرده و به دنبال نزدیکترین رکورد به آن خواهیم گشت:
SELECT T.doc.value('(/book/title)[1]', 'varchar(100)') AS title FROM (SELECT * FROM ftsXML WHERE CONTAINS(doc, 'FORMSOF (INFLECTIONAL ,"Quick Brown Fox jumped")')) AS T
و یا دو کلمهی نزدیک به هم را میتوان جستجو کرد:
SELECT T.doc.value('(/book/title)[1]', 'varchar(100)') AS title FROM (SELECT * FROM ftsXML WHERE CONTAINS(doc, 'quick NEAR fox')) AS T
نکتهای در مورد متد Contains
هم Full text search و هم XQuery، هر دو دارای متدی به نام Contains هستند اما یکی نمیباشند.
SELECT doc.value('(/book/title)[1]', 'varchar(100)') AS title FROM ftsXML WHERE doc.exist('/book/chapter/content[contains(., "Quick Brown Fox")]') = 1
بنابراین متد contains مرتبط با XQuery یک جستجوی case sensitive را انجام میدهد.