مطالب
توسعه اپلیکیشن های ASP.NET با Windows Azure Active Directory
ابزار ASP.NET برای Windows Azure Active Directory فعال کردن احراز هویت در وب اپلیکیشن هایی که روی  Windows Azure Web Sites  میزبانی شده اند را ساده‌تر می‌کند. می‌توانید از Windows Azure Authentication برای احراز هویت کاربران Office 365 استفاده کنید، حساب‌های کاربری را از On-Premise Active Directory خود همگام سازی (Sync) کنید و یا از یک دامنه سفارشی Windows Azure Active Directory بهره ببرید. فعال سازی Windows Azure Authentication، اپلیکیشن شما را طوری پیکربندی می‌کند تا تمامی کاربران را با استفاده از یک  Windows Azure Active Directory tenant  احراز هویت کند.

این مقاله ساختن یک اپلیکیشن ASP.NET را که بر اساس  organizational accounts  پیکربندی شده و بر روی  Windows Azure Active Directory  میزبانی می‌شود، مرور می‌کند.

پیش نیاز ها

  1. Visual Studio Express 2013 RC for Web یا Visual Studio 2013 RC 
  2. یک حساب کاربری در Windows Azure. می‌توانید یک حساب رایگان بسازید.


یک مدیر کلی به حساب کاربری Active Directory خود اضافه کنید

  1. وارد Windows Azure Portal شوید.
  2. یک حساب کاربری (Windows Azure Active Directory (AD انتخاب یا ایجاد کنید. اگر قبلا حساب کاربری ساخته اید از همان استفاده کنید در غیر اینصورت یک حساب جدید ایجاد کنید. مشترکین Windows Azure یک AD پیش فرض با نام Default Directory خواهند داشت.
  3. در حساب کاربری AD خود یک کاربر جدید در نقش Global Administrator بسازید. اکانت AD خود را انتخاب کنید و Add User را کلیک کنید. برای اطلاعات کامل‌تر به Managing Windows Azure AD from the Windows Azure Portal 1– Sign Up with an Organizational Account مراجعه کنید.

یک نام کاربری انتخاب کرده و به مرحله بعد بروید.

نام کاربری را وارد کنید و نقش Global Administrator را به آن اختصاص دهید. مدیران کلی به یک آدرس ایمیل متناوب هم نیاز دارند. به مرحله بعد بروید.

بر روی Create کلیک کنید و کلمه‌ی عبور موقتی را کپی کنید. پس از اولین ورود باید کلمه عبور را تغییر دهید.


یک اپلیکیشن ASP.NET بسازید

در ویژوال استودیو یک پروژه جدید ASP.NET Web Forms یا MVC بسازید و روی Change Authentication  کلیک کنید. 

گزینه Organizational Accounts را انتخاب کنید. نام دامنه خود را وارد کنید و سپس گزینه Single Sign On, Read directory data را انتخاب کنید. به مرحله بعد بروید.

نکته: در قسمت More Options می توانید قلمرو اپلیکیشن (Application ID URI) را تنظیم کنید. تنظیمات پیش فرض برای اکثر کاربران مناسب است اما در صورت لزوم می‌توانید آنها را ویرایش کنید، مثلا از طریق Windows Azure Portal دامنه‌های سفارشی خودتان را تنظیم کنید.

اگر گزینه Overwrite را انتخاب کنید اپلیکیشن جدیدی در Windows Azure برای شما ساخته خواهد شد. در غیر اینصورت فریم ورک سعی می‌کند اپلیکیشنی با شناسه یکسان پیدا کند (در پست متدهای احراز هویت در VS 2013 به تنظیمات این قسمت پرداخته شده).

اطلاعات مدیر کلی دامنه در Active Directory خود را وارد کنید (Credentials) و پروژه را با کلیک کردن بر روی Create Project بسازید.

با کلیدهای ترکیبی Ctrl + F5، اپلیکیشن را اجرا کنید. مرورگر شما باید یک اخطار SSL Certificate به شما بدهد. این بدین دلیل است که مدرک استفاده شده توسط IIS Express مورد اعتماد (trusted) نیست. این اخطار را بپذیرید و اجازه اجرا را به آن بدهید. پس از آنکه اپلیکیشن خود را روی Windows Azure منتشر کردید، این پیغام دیگر تولید نمی‌شود؛ چرا که Certificate‌های استفاده شده trusted هستند.

با حساب کاربری سازمانی (organizational account) که ایجاد کرده‌اید، وارد شوید.

همانطور که مشاهده می‌کنید هم اکنون به سایت وارد شده اید.



توزیع اپلیکیشن روی Windows Azure

در Windows Azure Portal یک وب سایت را به‌همراه یک دیتابیس، ایجاد کنید. در پانل سمت چپ صفحه روی Websites کلیک کنید و بعد New را انتخاب کنید. سپس گزینه Custom Create را برگزینید.

اپلیکیشن را روی Windows Azure منتشر کنید. روی پروژه کلیک راست کرده و Publish را انتخاب کنید. در مرحله تنظیمات (Settings) مشاهده می‌کنید که احراز هویت حساب‌های سازمانی (organizational accounts) فعال است. همچنین سطح دسترسی به خواندن تنظیم شده است. در قسمت Database رشته اتصال دیتابیس را تنظیم کنید.

حال به وب سایت Windows Azure خود بروید و توسط حساب کاربری ایجاد شده وارد سایت شوید. در این مرحله دیگر نباید خطای امنیتی SSL را دریافت کنید.


خواندن اطلاعات پروفایل کاربران توسط Graph API

قالب پروژه ویژوال استودیو برای organizational accounts یک متد و نما بنام UserProfile به پروژه اضافه کرده است.
[Authorize]
public async Task<ActionResult> UserProfile()
{
    string tenantId = ClaimsPrincipal.Current.FindFirst(TenantSchema).Value;

    // Get a token for calling the Windows Azure Active Directory Graph
    AuthenticationContext authContext = new AuthenticationContext(String.Format(CultureInfo.InvariantCulture, LoginUrl, tenantId));
    ClientCredential credential = new ClientCredential(AppPrincipalId, AppKey);
    AuthenticationResult assertionCredential = authContext.AcquireToken(GraphUrl, credential);
    string authHeader = assertionCredential.CreateAuthorizationHeader();
    string requestUrl = String.Format(
        CultureInfo.InvariantCulture,
        GraphUserUrl,
        HttpUtility.UrlEncode(tenantId),
        HttpUtility.UrlEncode(User.Identity.Name));

    HttpClient client = new HttpClient();
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
    request.Headers.TryAddWithoutValidation("Authorization", authHeader);
    HttpResponseMessage response = await client.SendAsync(request);
    string responseString = await response.Content.ReadAsStringAsync();
    UserProfile profile = JsonConvert.DeserializeObject<UserProfile>(responseString);

    return View(profile);
}

کلیک کردن لینک UserProfile  اطلاعات پروفایل کاربر جاری را نمایش می‌دهد.



اطلاعات بیشتر

اشتراک‌ها
معرفی WebHook ها
WebHooks is a lightweight HTTP pattern providing a simple pub/sub model for wiring together Web APIs and SaaS services. When an event happens in a service, a notification is sent in the form of an HTTP POST request to registered subscribers. The POST request contains information about the event which makes it possible for the receiver to act accordingly  Introducing Microsoft ASP.NET WebHooks PreviewSending WebHooks with ASP.NET WebHooks Preview ASP.NET WebHooks Documentation

Introducing Microsoft ASP.NET WebHooks Preview
ASP.NET WebHooks Documentation
معرفی WebHook ها
اشتراک‌ها
دوره توسعه Web API با دات نت 8 در 2 ساعت

Web API Development in .NET 8 in 2 Hours | ASP.NET CORE | RESTFUL API

00:00:00 Introduction
00:03:06 What is Web API & Why create Web API
00:10:21 How Web API Works in Theory
00:14:49 How Web API Works  (Demo with Minimal APIs)
00:27:32 What is a Web API Framework
00:33:27 ASP.NET Core Middleware Pipeline
00:37:34 Web API Controller
00:42:25 Routing in Web API
00:51:17 Model Binding
01:01:06 Model Validation with DataAnnatation
01:08:07 Model Validation with ValidationAttribute
01:15:10 Web API Return Types
01:21:30 In Mememory Repository
01:25:01 Model Validation with Action Filter
01:35:30 Read Endpoint
01:36:55 Create Endpoint
01:46:45 Validating Create Endpoint with ActionFilter
01:51:23 Update Endpoint
01:59:48 Exception Hanlding with Exception Filter
02:05:48 Delete Endpoint
 

دوره توسعه Web API با دات نت 8 در 2 ساعت
مطالب
ضبط تصاویر Webcam در پروژه‌های Angular
هدف ما از این مقاله این است که از طریق وب کم، تصاویر را ضبط کنیم (یک نمونه ). برای انجام این کار فایل app.component.html  را باز کرده و مطابق زیر ویرایش کنید: 
<div id="app">
  <div><video #video id="video" width="640" height="480" autoplay></video></div>
  <div><button id="snap" (click)="capture()">ضبط تصویر</button></div>
  <canvas #canvas id="canvas" width="640" height="480"></canvas>
  <ul>
    <li *ngFor="let capture of captures">
        <img src="{{ capture }}" height="50" />
    </li>
 </ul>
</div>
کد‌های HTML زیادی در اینجا وجود ندارند. به تگ <video> و <canvas> توجه کنید. برای هر کدام از این تگ‌ها، یک local variable وجود دارد که با سمبل # مشخص شده‌اند. به عبارت دیگر، دو متغیر video# و canvas# وجود دارند . این گونه است که ما می‌توانیم به این المنت‌ها، در کد‌های تایپ اسکریپت دسترسی داشته باشیم.  
المنت <button>، در رویداد کلیک آن، متد capture را فراخوانی می‌کند که کارش ضبط تصویر می‌باشد. 
و در پایان یک حلقه بر روی آرایه‌ی captures داریم که کارش نمایش تصاویر ضبط شده است. چون هر بار که بر روی دکمه ضبط تصویر کلیک کنیم، یک تصویر به آرایه‌ی captures  اضافه می‌شود .
 
فایل app.component.ts :
export class AppComponent implements OnInit, AfterViewInit {
  @ViewChild('video')
  public video: ElementRef;

  @ViewChild('canvas')
  public canvas: ElementRef;

  public captures: Array<any>;

  public constructor() {
    this.captures = [];
  }

  public ngOnInit() { }

  public capture() {
    this.canvas.nativeElement.getContext('2d').drawImage(this.video.nativeElement, 0, 0, 640, 480);
    this.captures.push(this.canvas.nativeElement.toDataURL('image/png'));
  }

  public ngAfterViewInit() {
    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
      navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
        this.video.nativeElement.src = window.URL.createObjectURL(stream);
        this.video.nativeElement.play();
      });
    }
  }
}

توضیحات :

با استفاده از local variable ‌هایی که در کد‌های HTML تعریف کردیم و ViewChild@، می‌توانیم المنت‌ها را در متغیر‌ها، load کنیم. در این حالت این امکان وجود دارد تا المنت‌های DOM را دستکاری کنیم.
  public ngAfterViewInit() {
    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
      navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
        this.video.nativeElement.src = window.URL.createObjectURL(stream);
        this.video.nativeElement.play();
      });
    }
  }
  1. MediaDevices : این اینترفیس دستیابی به دستگاه‌های ورودی متصل شده، مثلا دوربین، میکروفن و ... را فراهم می‌سازد. 
  2. MediaDevices.getUserMedia: با گرفتن مجوزی از کاربر از طریق یک هشدار، دوربین کاربر را روشن می‌کند و هم چنین این متد یک promise را بازگشت می‌دهد؛ در صورتیکه کاربر اجازه دسترسی بدهد.
  3. URL.createObjectURL: یک URL را برای یک BLOB  مشخص شده ایجاد می‌کند ( BLOB: Binary large object ) که می‌تواند به متدی که انتظار یک URL را دارد، پاس داده شود. بعد از برگشت URL، متد ()revokeObjectURL فراخوانی میشود که کارش آزاد سازی منابع مرتبط با url ایجاد شده‌ی توسط createObjectURL  می‌باشد. در ضمن طول عمر url ایجاد شده برابر با بستن سند (document) در پنجره‌ای (window) که در آن ایجاد شده‌است، می‌باشد. 
 
عملیات ضبط تصویر در این متد انجام میشود:
  public capture() {
    this.canvas.nativeElement.getContext('2d').drawImage(this.video.nativeElement, 0, 0, 640, 480);
    this.captures.push(this.canvas.nativeElement.toDataURL('image/png'));
  }
  1. ()getContext : این متد یک شیء را برگشت می‌دهد که فراهم کننده‌ی متد‌ها و خصوصیت‌ها، برای رسم در Canvas میباشد. 
  2. ()drawImage: این متددر Canvas رسم را انجام می‌دهد و همچنین این متد می‌تواند بخش‌هایی از یک تصویر را رسم کند یا سایز یک تصویر را افزایش یا کاهش دهد.
  3.  () toDataURL: این متد یک data URI  را بازگشت می‌دهد که یک تصویر در فرمت مشخص شده را بر اساس پارامتر type، برگشت می‌دهد (پیش فرض آن png می‌باشد). 
تمام !
DEMO  
مطالب
نکات استفاده از افزونه‌ی Web Essentials جهت کار با تصاویر
در این مطلب نکات کار با تصاویر را توسط افزونه‌ی Web Esstentials بررسی می‌کنیم. این افزونه قابلیت‌های زیر را در کار با تصاویر در اختیار شما قرار می‌دهد:
بهینه‌سازی تصاویر
یکی از موارد مهمی که باید مورد توجه قرار بگیرد، استفاده از تصاویر کم حجم در وب‌سایت می‌باشد. روش‌های مختلفی جهت بهینه‌سازی تصاویر مورد استفاده در سایت وجود دارند، به طور مثال جهت بهینه‌سازی تصاویر PNG می‌توانید از ابزار PNGGauntlet استفاده کنید. همچنین اینجا نیز یک ابزار آنلاین موجود می‌باشد. افزونه‌ی Web Essentails این قابلیت را به آسانی در اختیار شما قرار می‌دهد؛ اینکار را می‌توانید توسط این افزونه به روش‌های زیر انجام دهید:
  • کلیک راست بر روی تصویر
برای اینکار بر روی فایلی که می‌خواهید optimize کنید، کلیک راست کرده و از منوی ظاهر شده گزینه Web Essentials و سپس Optimize Image را انتخاب کنید:

در قسمت status bar نیز می‌توانید نتیجه را مشاهده کنید:

  • انتخاب چندین تصویر
روال قبلی را می‌توانید برای چندین فایل انتخاب شده و یا یک پوشه تکرار کنید:

  • بهینه‌سازی تصاویر موجود در فایل‌های CSS
همچنین امکان بهینه‌سازی تصاویر داخل فایل‌های CSS نیز توسط این افزونه امکان پذیر است:

  • بهینه سازی تصاویر Base64 Encode
توسط این افزونه می‌توانیم تصاویر  Data Uri  را نیز بهینه سازی کنیم:

همانطور که در تصویر فوق مشاهده می‌کنید می‌توانیم تصاویری که به صورت Data Uri درون کد پیوست شده اند را با کلیک بر روی Save to file به صورت یک فایل ذخیره کنیم.

ایجاد تصاویر Sprite
یکی دیگر ار قابلیت‌های افزونه Web Essentials امکان تهیه تصاویر به صورت Sprite می باشد. برای اینکار کافی است به این صورت عمل کنید:

بعد از کلیک بر روی Create image sprite باید یک نام برای آن تعیین کنید و سپس بر روی کلید Save کلیک کنید. با اینکار یک فایل از نوع XML با پسوند sprite برای شما ساخته خواهد شد:
<?xml version="1.0" encoding="utf-8"?>
<sprite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://vswebessentials.com/schemas/v1/sprite.xsd">
  <settings>
    <!--Determines if the sprite image should be automatically optimized after creation/update.-->
    <optimize>true</optimize>
    <!--Determines the orientation of images to form this sprite. The value must be vertical or horizontal.-->
    <orientation>vertical</orientation>
    <!--File extension of sprite image.-->
    <outputType>png</outputType>
    <!--Determin whether to generate/re-generate this sprite on building the solution.-->
    <runOnBuild>false</runOnBuild>
    <!--Use full path to generate unique class or mixin name in CSS, LESS and SASS files. Consider disabling this if you want class names to be filename only.-->
    <fullPathForIdentifierName>true</fullPathForIdentifierName>
    <!--Use absolute path in the generated CSS-like files. By default, the URLs are relative to sprite image file (and the location of CSS, LESS and SCSS).-->
    <useAbsoluteUrl>false</useAbsoluteUrl>
    <!--Specifies a custom subfolder to save CSS files to. By default, compiled output will be placed in the same folder and nested under the original file.-->
    <outputDirectoryForCss />
    <!--Specifies a custom subfolder to save LESS files to. By default, compiled output will be placed in the same folder and nested under the original file.-->
    <outputDirectoryForLess />
    <!--Specifies a custom subfolder to save SCSS files to. By default, compiled output will be placed in the same folder and nested under the original file.-->
    <outputDirectoryForScss />
  </settings>
  <!--The order of the <file> elements determines the order of the images in the sprite.-->
  <files>
    <file>/Content/Images/01.png</file>
    <file>/Content/Images/02.png</file>
    <file>/Content/Images/03.png</file>
    <file>/Content/Images/04.png</file>
  </files>
</sprite>
یکی از زیر مجموعه‌های این فایل، تصویر نهایی می‌باشد، همچنین فایل‌های css, less, map و scss آن نیز تولید می‌شود:

به عنوان مثال فایل CSS تصویر فوق به صورت زیر می‌باشد:
/*
This is an example of how to use the image sprite in your own CSS files
*/
.Content-Images-01 {
/* You may have to set 'display: block' */
width: 32px;
height: 32px;
background: url('icons.png') 0 0;
}
.Content-Images-02 {
/* You may have to set 'display: block' */
width: 32px;
height: 32px;
background: url('icons.png') 0 -32px;
}
.Content-Images-03 {
/* You may have to set 'display: block' */
width: 32px;
height: 32px;
background: url('icons.png') 0 -64px;
}
.Content-Images-04 {
/* You may have to set 'display: block' */
width: 32px;
height: 32px;
background: url('icons.png') 0 -96px;
}
هر کدام از کلاس‌های فوق به یک تصویر در فایل مربوطه توسط image position اشاره می‌کند. شما می‌توانید با انتساب هر کدام از کلاس‌های فوق به یک المنت از آن تصویر استفاده نمائید:
<div class="Content-Images-01"></div>
<div class="Content-Images-02"></div>
<div class="Content-Images-03"></div>
<div class="Content-Images-04"></div>

استفاده از تصاویر Data URIs
یکی دیگر از روش‌های کاهش درخواست‌های HTTP در یک سایت استفاده از Data URIs  می باشد، توسط این روش می‌توانید فایل هایتان را درون HTML و یا CSS قرار دهید یا به اصطلاح embed کنید. به طور مثال جهت استفاده از یک تصویر می‌توانید به راحتی با آدرس دهی تصویر درون تگ img، تصویر را درون صفحه نمایش دهید:
<img src="https://www.dntips.ir/images/logo.png" />

همین کار را می‌توانیم توسط Data URIs انجام دهیم:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC" />
در کد فوق تصویر موردنظر را درون HTML به صورت embed شده قرار داده ایم، در این حالت دیگری نیازی به رفت و برگشت به سرور جهت نمایش تصویر نیست.
سینتکس Data URIs
به طور مثال تگ زیر را در نظر داشته باشید:
<img src="data:image/png;base64,iVBOR..." />
مقدار ویژگی src شامل موارد زیر است:
data: نام schema
image/png: نوع محتوا(content type)
base64: نوع encoding استفاده شده برای encode کردن اطلاعات
iVBOR...: اطلاعات encode شده.
توسط افزونه Web Essentials به راحتی می‌توانید تصویر موردنظرتان را به صورت Data URI تهیه کنید:

اشتراک‌ها
کتابخانه Responsive Tabs
  1. 8 Tab Designs
  2. Flexible Designs
  3. Fully Responsive including its contents
  4. Includes Typographical Elements (Headings, Text Callout, Blockquote)
  5. Includes Responsive Tables
  6. Includes Responsive Bar Chart
  7. Includes Responsive Column Chart
  8. Includes Responsive Video
  9. Includes Responsive Forms with 3 designs
کتابخانه Responsive Tabs
اشتراک‌ها
انتقال WebAssembly به سرور یا WASI

Bringing WebAssembly to the .NET Mainstream - Steve Sanderson, Microsoft

Many developers still consider WebAssembly to be a leading-edge, niche technology tied to low-level systems programming languages. However, C# and .NET (open-source, cross-platform technologies used by nearly one-third of all professional developers [1]) have run on WebAssembly since 2017. Blazor WebAssembly brought .NET into the browser on open standards, and is now one of the fastest-growing parts of .NET across enterprises, startups, and hobbyists. Next, with WASI we could let you run .NET in even more places, introducing cloud-native tools and techniques to a wider segment of the global developer community. This is a technical talk showing how we bring .NET to WebAssembly. Steve will demonstrate how it runs both interpreted and AOT-compiled, how an IDE debugger can attach, performance tradeoffs, and how a move from Emscripten to WASI SDK lets it run in Wasmtime/Wasmer or higher-level runtimes like wasmCloud. Secondly, you'll hear lessons learned from Blazor as an open-source project - challenges and misconceptions faced bringing WebAssembly beyond early adopters. [1] StackOverflow survey 2021 

انتقال WebAssembly به سرور یا WASI