کتابخانه Spectro.js
کتابخانه jQuery Chat
@model IEnumerable<FsWeb.Models.Book> <!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" /> </head> <body> <div data-role="page" data-theme="a" id="booksPage"> <div data-role="header"> <h1>Guitars</h1> </div> <div data-role="content"> <ul data-role="listview" data-filter="true" data-inset="true"> @foreach(var x in Model) { <li><a href="#">@x.Name</a></li> } </ul> </div> </div> <script src="http://code.jquery.com/jquery-1.6.4.min.js"> </script> <script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"> </script> <script> $(document).delegate("#bookPage", 'pageshow', function (event) { $("div:jqmData(role='content') > ul").listview('refresh'); }); </script> </body> </html>
برای ساخت کنترلر جدید، در پروژه #F ساخته شده یک Source File ایجاد نمایید و کدهای زیر را در آن کپی نمایید:
namespace FsWeb.Controllers open System.Web.Mvc open FsWeb.Models [<HandleError>] type BooksController() = inherit Controller() member this.Index () = seq { yield Book(Name = "My F# Book") yield Book(Name = "My C# Book") } |> this.View
اما نکته ای که در مثال بالا وجود دارد این است که دو نمونه از نوع Book را برای ساخت seq وهله سازی میکند. در نتیجه باید Book Type را به عنوان مدل تعریف کنیم. به صورت زیر:
namespace FsWeb.Models type Book = { Id : Guid; Name : string }
namespace FsWeb.Models type Book() = member val Name = "" with get, set
اگر همچون پروژههای #C قصد دارید با استفاده از Attributeها مدل خود را اعتبارسنجی نمایید میتوانید به صورت زیر اقدام نمایید:
open System.ComponentModel.DataAnnotations type Book() = [<Required>] member val Name = "" with get, set
namespace FsWeb.Models open System open System.ComponentModel.DataAnnotations type Book() = [<Key>] member val Id = Guid.NewGuid() with get, set [<Required>] member val Name = "" with get, set
نکته: دستور open معادل با using در #C است.
IHttpContextAccessor را باید در لایه سرویس تزریق کنید: «بررسی روش دسترسی به HttpContext در ASP.NET Core»
صورت مساله
میخواهیم اطلاعات نمایش داده شده در گرید را به نحوی فرمت کنیم که
الف) اگر id ردیف مساوی 5 بود، رنگ و پس زمینهی آن تغییر کند.
ب) نام محصول، به جزئیات آن لینک شود و این اطلاعات توسط یک jQuery UI Dialog نمایش داده شود.
ج) عدد قیمت با سه رقم جدا کننده همراه باشد.
تکمیل مدل برنامه
مدل قسمت اول صرفا یک محصول بود. مدل قسمت جاری، اطلاعات تولید/تامین کننده آنرا توسط کلاس Supplier نیز به همراه دارد:
namespace jqGrid02.Models { public class Product { public int Id { set; get; } public string Name { set; get; } public decimal Price { set; get; } public Supplier Supplier { set; get; } } public class Supplier { public int Id { set; get; } public string CompanyName { set; get; } public string Address { set; get; } public string PostalCode { set; get; } public string City { set; get; } public string Country { set; get; } public string Phone { set; get; } public string HomePage { set; get; } } }
کدهای سمت سرور
کدهای سمت سرور مانند متد GetProducts به همراه صفحه بندی و مرتب سازی پویای آن دقیقا مانند قسمت قبل است.
در اینجا فقط یک اکشن متد جدید جهت بازگشت اطلاعات تولید کنندهای مشخص با فرمت JSON، اضافه شدهاست:
public ActionResult GetGetSupplierData(int id) { var list = ProductDataSource.LatestProducts; var product = list.FirstOrDefault(x => x.Id == id); if (product == null) return Json(null, JsonRequestBehavior.AllowGet); return Json(new { product.Supplier.CompanyName, product.Supplier.Address, product.Supplier.PostalCode, product.Supplier.City, product.Supplier.Country, product.Supplier.Phone, product.Supplier.HomePage }, JsonRequestBehavior.AllowGet); }
کدهای سمت کلاینت
صفحه دیالوگی که قرار است اطلاعات تولید کننده را نمایش دهد، یک چنین ساختاری دارد:
<div dir="rtl" id="supplierDialog"> <span id="CompanyName"></span><br /><br /> <span id="Address"></span><br /> <span id="PostalCode"></span>, <span id="City"></span><br /> <span id="Country"></span><br /><br /> <span id="Phone"></span><br /> <span id="HomePage"></span> </div>
<script type="text/javascript"> function showSupplierDialog(linkElement, supplierId) { //request json data $.getJSON('@Url.Action("GetGetSupplierData","Home")', { id: supplierId }, function (data) { //set values in dialog for (var property in data) { if (data.hasOwnProperty(property)) { $('#' + property).text(data[property]); } } //get link position var linkPosition = $(linkElement).offset(); $('#supplierDialog').dialog('option', 'position', [linkPosition.left, linkPosition.top]); //open dialog $('#supplierDialog').dialog('open'); }); } $(document).ready(function () { $('#supplierDialog').dialog({ autoOpen: false, bgiframe: true, resizable: false, title: 'تولید کننده' }); $('#list').jqGrid({ // .... مانند قبل colNames: ['شماره', 'نام محصول', 'قیمت'], //columns model colModel: [ { name: 'Id', index: 'Id', align: 'right', width: 20, formatter: function (cellvalue, options, rowObject) { var cellValueInt = parseInt(cellvalue); if (cellValueInt == 5) { return "<span style='background: brown; color: yellow'>" + cellvalue + "</span>"; } return cellvalue; } }, { name: 'Name', index: 'Name', align: 'right', width: 300, formatter: function (cellvalue, options, rowObject) { return "<a href='#' onclick='showSupplierDialog(this, " + rowObject[0] + ");'>" + cellvalue + "</a>"; } }, { name: 'Price', index: 'Price', align: 'center', width: 50, formatter: 'currency', formatoptions: { decimalSeparator: '.', thousandsSeparator: ',', decimalPlaces: 2, prefix: '$' } } ], // .... مانند قبل }); }); </script>
در حالت ستون Id، از یک formatter سفارشی استفاده شدهاست. در اینجا این فرمت کننده به صورت یک callback عمل کرده و پیش از رندر نهایی اطلاعات، مقدار سلول جاری را توسط cellvalue در اختیار ما قرار میدهد. در این بین هر نوع فرمتی را که نیاز است میتوان اعمال کرد و سپس یک رشته را بازگشت میدهیم. این رشته در سلول جاری درج خواهد شد.
- اگر مانند ستون Name، نیاز به مقادیر سایر سلولها نیز وجود داشت، میتوان از آرایهی rowObject استفاده کرد. برای مثال در این حالت، یک لینک که کلیک بر روی آن سبب فراخوانی تابع showSupplierDialog میشود، در سلولهای ستون Name درج خواهند شد. اولین rowObject که در اینجا مورد استفاده است، به ستون اول یا همان Id محصول اشاره میکند.
- در ستون Price از یک سری formatter از پیش تعریف شده استفاده شدهاست. نمونهای از آن را در قسمت اول در ستون نمایش وضعیت موجود بودن محصول با تنظیم formatter: checkbox مشاهده کردهاید. در اینجا از یک formatter توکار دیگر به نام currency برای کار با مقادیر پولی استفاده شدهاست به همراه تنظیمات خاص آن.
- متد showSupplierDialog طوری تنظیم شدهاست که پس از دریافت Id یک محصول، آنرا به سرور ارسال کرده و مشخصات تولید کنندهی آنرا با فرمت JSON دریافت میکند. سپس در حلقهای که مشاهده میکنید، خواص شیء جاوا اسکریپتی دریافتی استخراج و به spanهای supplierDialog انتساب داده میشوند. جهت سهولت کار، Id این spanها دقیقا مساوی Id خواص شیء دریافتی از سرور، درنظر گرفته شدهاند.
- در مورد راست به چپ نمایش داده شدن عنوان دیالوگ، تغییرات CSS ایی لازم است که در قسمت اول بیان شدند.
برای مطالعه بیشتر
لیست کامل فرمت کنندههای توکار
فرمت کنندههای سفارشی
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید
jqGrid02.zip
چندی قبل مطلبی را در مورد پردازش فایلهای xml با استفاده از قابلیت Ajax جی کوئری نوشتم. در سایت پیسافت، تعدادی فایل XML از شعرا و جملات قصار و امثال آن موجود است (با تقدیر و تشکر از زحمات این عزیزان) که امروز قصد داریم از فایل XML جملات قصار آن یک افزونه jQuery درست کنیم تا آنها را به صورت اتفاقی (random) در صفحه نمایش دهد:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>XML</title>
<script src='jquery-1.3.min.js' type='text/javascript'></script>
<script type="text/javascript">
var ourXml = '';
function parseXml(xml){
ourXml = xml; //for our timer
var i;
var rnd = Math.floor(Math.random() * 130) + 1; //we have 130 entries
for (i = 1; i < 5; i++) //M1 to M4
{
$(xml).find("Ghesaar" + rnd + " > M" + i).each(function(){
$("#output").append($(this).text() +' ');
});
}
}
//ajax loader
$(document).ready(function(){
$.ajax({
type: "GET",
url: "Ghesaar.xml",
dataType: "xml",
success: parseXml
});
});
//timer
window.setInterval(function(){
$("#output").empty().hide();
parseXml(ourXml);
$("#output").fadeIn("slow");
}, 10000);
</script>
</head>
<body>
<span id="output" dir="rtl" style=" "/>
</body>
</html>
همه چیز از قسمت Ajax کد فوق شروع میشود. فایل Ghesaar.xml بارگذاری شده و به تابع parseXml ارسال میشود. در این تابع یک کپی از xml دریافت شده را نگهداری میکنیم تا در تایمری که بعدا جهت نمایش اتفاقی پیامها درست خواهیم کرد، مجبور نشویم مجددا محتویات فایل xml را بارگذاری کنیم.
در تابع parseXml قصد داریم فایل xml ایی با فرمت زیر را پردازش کنیم:
<Ghesaar10>
<M1>ناامیدی، آخرین نتیجه گیری </M1>
<M2>بی خردان است</M2>
<M3>
</M3>
<M4>« ضرب المثل انگلیسی »</M4>
</Ghesaar10>
تا اینجا فقط یکی از جملات قصار در هنگام بارگذاری صفحه نمایش داده خواهند شد. برای تکرار نمایش، از یک تایمر میتوان کمک گرفت که کد آنرا در بالا ملاحظه میکنید.
همین!
برای تبدیل آن به یک پلاگین/افزونه جیکوئری ، میتوان به صورت زیر عمل کرد:
$.fn.ghesaar = function(options){
var defaults = {
interval: 1
};
var options = $.extend(defaults, options);
return this.each(function(){
var obj = $(this);
var ourXml = '';
function parseXml(xml){
ourXml = xml; //for our timer
var i;
var rnd = Math.floor(Math.random() * 130) + 1; //we have 130 entries
for (i = 1; i < 5; i++) //M1 to M4
{
$(xml).find("Ghesaar" + rnd + " > M" + i).each(function(){
obj.append($(this).text() + ' ');
});
}
}
//ajax loader
$.ajax({
type: "GET",
url: "Ghesaar.xml",
dataType: "xml",
success: parseXml
});
//timer
window.setInterval(function(){
obj.empty().hide();
parseXml(ourXml);
obj.fadeIn("slow");
}, options.interval * 1000);
});
};
سپس قسمت استاندارد توسعه options اضافه میشود تا بتوان به تابع افزونه خود مقدار interval را پاس کرد تا از این حالت خشک و جمود خارج شود.
کل وقایع افزونه درون تابع زیر رخ میدهد:
return this.each(function(){
...
});
سپس در ابتدای کار شیء this که اشارهگری است به شیء انتخاب شده توسط جیکوئری را دریافت کرده و هرجایی را که قبلا $("#output") داشتیم، تبدیل به obj میکنیم. (یعنی این مورد هم به انتخاب کاربر خواهد شد)
جهت دریافت مقدار تنظیمی interval هم میتوان از options.interval استفاده کرد.
به این صورت کد ما تبدیل به یک افزونه جیکوئری میشود.
اینبار نحوهی استفاده از افزونهی تولیدی به صورت زیر است: (عدد interval بر اساس ثانیه است)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>XML</title>
<script src='jquery-1.3.min.js' type='text/javascript'></script>
<script src='jquery.ghesaar.js' type='text/javascript'></script>
<script type="text/javascript">
$(document).ready(function(){
$("#output").ghesaar({interval:5});
});
</script>
</head>
<body>
<span id="output" dir="rtl" style=" "/>
</body>
</html>
به صورت ساده:
برای استفاده از آن، سه فایل jquery-1.3.min.js (یا نگارش جدیدتر آن)، jquery.ghesaar.js و Ghesaar.xml را باید آپلود کنید. چند سطری را که در قسمت head صفحه فوق مشاهده مینمائید باید اضافه شوند. سپس یک span یا div را جهت نمایش این جملات قصار به هر جایی از ساختار صفحه خود که علاقمند بودید اضافه کنید (id آن مهم است و در قسمت نمایش جملات قصار مورد جستجو قرار میگیرد).
فایلهای این پروژه را از اینجا دریافت کنید.
public class HomeViewModel { public string Id { get; set; } public string Message { get; set; } public DateTime DateTime { get; set; } }
اکنون به پوشهی Views بروید و فایل Index.cshtml را به این صورت تغییر دهید:
@model AspNetCoreDependencyInjection.Models.HomeViewModel @{ ViewData["Title"] = "Home"; } <div> <div> <div> <p> <b>Id : </b><span>@Model.Id</span> <br /> <b>Date And Time : </b><span> @Model.DateTime </span> <br/> <b>Message : </b><span>@Model.Message</span> </p> </div> </div> </div>
using AspNetCoreDependencyInjection.Services; namespace AspNetCoreDependencyInjection.ServicesImplentaions { public class MessageServiceAA { public string Message() { return "A message from MessageServiceAA"; } } }
namespace AspNetCoreDependencyInjection.Helpers { public class GuidProvider { private readonly Guid _serviceGuid; public GuidProvider() { _serviceGuid = Guid.NewGuid(); } public Guid GetNewGuid() => Guid.NewGuid(); public string GetGuidAsFormatedString(string prefix = "") => getFormatedGuid(_serviceGuid, prefix); private string getFormatedGuid(Guid guid, string prefix = "") { var guidString = guid.GetHashCode().ToString("x"); if (string.IsNullOrEmpty(prefix) == false) guidString = new StringBuilder($"{prefix}-").Append(guidString).ToString(); return guidString; } } }
حالا درون کنترل HomeController، این تغییرات را انجام میدهیم:
private readonly ILogger<HomeController> _logger; private readonly MessageServiceAA _messageService; private readonly GuidProvider _ guidProvider; public HomeController(ILogger<HomeController> logger) { _logger = logger; _messageService = new MessageServiceAA(); _guidProvider = new GuidProvider(); } public IActionResult Index() { var model = new HomeViewModel() { Id = _ guidProvider.GetGuidAsFormatedString(), Message = _messageService.Message(), DateTime = DateTime.Now, }; return View(model); }
همانطور که میبینید، در کد بالا، کنترلر HomeController، به دو شیء از کلاسها و یا سرویسهای GuidProvider و MessageServiceAA به صورت مستقیم وابسته شدهاست و با هر تغییری در هر کدام از این سرویسها، باید دوباره کامپایل شود. علاوه بر این اگر بخواهیم پیاده سازیهای مختلفی را برای هر کدام از این موارد، ارائه دهیم، به مشکل بر میخوریم. خب بیاید تغییراتی را در کد بالا بدهیم تا مشکلات ذکر شده را حل کنیم.
برای این منظور پوشهای را به نام Services میسازیم و اینترفیسی را
به نام IMessageBrokerA ایجاد میکنیم و سپس کاری میکنیم که MessageServiceAA از این
اینترفیس ارث بری کند:
namespace AspNetCoreDependencyInjection.Services { public interface IMessageServiceA { string Message(); } }
و حالا میخواهیم با
استفاده از تزریق وابستگی، وابستگی کنترلر HomeController را از کلاس MessageBrokerAA لغو کرده و آن را به اینترفیس IMessageBrokerA (انتزاع) وابسته کنیم. در
اینجا ما از تکنیک تزریق درون سازنده یا Constructor Injection استفاده میکنیم.
تزریق درون سازنده
در این تکنیک، ما لیستی از وابستگیهای مورد نیاز را به عنوان پارامترهای ورودی سازندهی کلاس، تعریف میکنیم:private readonly ILogger<HomeController> _logger; private readonly IMessageServiceA _messageService; private readonly GuidProvider _guidHelper; public HomeController(ILogger<HomeController> logger , IMessageServiceA messageService) { _logger = logger; _messageService = messageService; _messageService = new MessageServiceAA(); _guidHelper = new GuidProvider(); }
- IServiceCollection : برای ثبت سرویسها
- IServiceProvider : برای واکشی سرویسها
در ASP.NET Core معمولترین مکان برای ثبت کردن سرویسها درون Container، به صورت پیش فرض درون کلاس Startup و درون متد ConfigureServices انجام میگیرد.
به صورت پیش فرض کلاس Startup دو متد دارد:
- ConfigureServices : برای پیکربندی و ثبت سرویسهای درونی DI Container استفاده میشود.
- Configure : برای تنظیمات pipeline میان افزارها ( Middlewares ) بکار میرود.
در اینجا پیاده سازی پیش فرض کلاس Startup را میبینیم که البته کدهای درون متد Configure را برای درگیر نکردن ذهن شما، مخفی کردهایم:
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // کدها جهت خوانایی بیشتر مخفی شده اند } }
همانطورکه میبینید، متد ConfigureService پارامتر IServiceCollection را میگیرد که به وسیلهی WebHost در زمان اجرای برنامه، مقدار دهی میشود.
تعداد زیادی Extension method برای IServiceCollection وجود دارند که برای پشتیبانی از ثبت کردن سرویسهای مختلف در سناریوهای گوناگون به کار میروند. در اینجا ما از نسخهی 3.1 چارچوب ASP.NET Core استفاده میکنیم. برای همین هم برای ثبت سرویسهای پیش فرض فریمورک MVC از متد توسعهی services.AddControllersWithViews() استفاده میکنیم. متد توسعهی AddControllersWithViews() سرویسهایی را که معمولا در فریم ورک MVC استفاده میشوند، درون IServiceCollection ثبت میکند. در نسخههای قبلی چارچوب ASP.NET Core، مانند نسخههای 2.1 و 2.2 برای این کار از متد توسعهی AddMvc() استفاده میشد.
در Microsoft Dependency Injection Container ، معمولا ترتیب ثبت سرویسها مهم نیست.
خب، اولین سرویس اختصاصی برنامهی خودمان را با چرخهی حیات Transient و زیر سرویس پیشین، به شکل زیر ثبت میکنیم :
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddTransient<IMessageServiceA, MessageServiceAA>(); }
public static IServiceCollection AddTransient<TService, TImplementation>(this IServiceCollection services)
در اینجا وقتی ما برای IMessageServiceA ، پیاده سازی MessageServiceA را ثبت میکنیم، از این به بعد DI Container، هر زمانیکه در لیست پارامترهای سازندهی یک کلاس، IMessageServiceA را مشاهده کند، بررسی میکند که چه کلاسی به عنوانی پیاده سازی این اینترفیس ثبت شدهاست، سپس از آن نمونه سازی میکند و درون سازندهی مورد نظر تزریق میکند. خب، حالا برنامه را دوباره اجرا کنید؛ میبینید که برنامه اجرا میشود.
- Visual Studio Express 2013 RC for Web یا Visual Studio 2013 RC
- یک حساب کاربری در Windows Azure. میتوانید یک حساب رایگان بسازید.
یک مدیر کلی به حساب کاربری Active Directory خود اضافه کنید
- وارد Windows Azure Portal شوید.
- یک حساب کاربری (Windows Azure Active Directory (AD انتخاب یا ایجاد کنید. اگر قبلا حساب کاربری ساخته اید از همان استفاده کنید در غیر اینصورت یک حساب جدید ایجاد کنید. مشترکین Windows Azure یک AD پیش فرض با نام Default Directory خواهند داشت.
- در حساب کاربری 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 بسازید
گزینه 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 منتشر کنید. روی پروژه کلیک راست کرده و Publish را انتخاب کنید. در مرحله تنظیمات (Settings) مشاهده میکنید که احراز هویت حسابهای سازمانی (organizational accounts) فعال است. همچنین سطح دسترسی به خواندن تنظیم شده است. در قسمت Database رشته اتصال دیتابیس را تنظیم کنید.
حال به وب سایت Windows Azure خود بروید و توسط حساب کاربری ایجاد شده وارد سایت شوید. در این مرحله دیگر نباید خطای امنیتی SSL را دریافت کنید.
خواندن اطلاعات پروفایل کاربران توسط Graph API
[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 اطلاعات پروفایل کاربر جاری را نمایش میدهد.
اطلاعات بیشتر
- ابتدا سرویس self host آنرا با دسترسی ادمین اجرا کنید.
- بعد برنامهی وب را اجرا کنید.