اشتراک‌ها
استفاده از MVVM در ASP.NET Core

Open source MVVM framework for ASP.NET Core and OWIN 

View

@viewModel DotvvmDemo.CalculatorViewModel, Dotvvm
    
<p>
    Enter the first number: 
    <dot:TextBox Text="{value: Number1}" />
</p>
<p>
    Enter the second number: 
    <dot:TextBox Text="{value: Number2}" />
</p>
<p>
    <dot:Button Text="Calculate" Click="{command: Calculate()}" />
</p>
<p>
    The result is: {{value: Result}}
</p>

ViewModel

using System;
    
namespace DotvvmDemo 
{
    public class CalculatorViewModel 
    {
            
        public int Number1 { get; set; }
            
        public int Number2 { get; set; }
            
        public int Result { get; set; }
            
        public void Calculate() 
        {
            Result = Number1 + Number2;
        }
    }
}


استفاده از MVVM در ASP.NET Core
اشتراک‌ها
Rider 2022.1 منتشر شد

Rider 2022.1 includes full Unreal Engine support, which converts Rider into a full-fledged IDE for game development, no matter what game engine you use. 

In v2022.1, Rider also supports a Beta version of the long-awaited remote development workflow. It allows you to connect to a remote machine running Rider’s backend from anywhere in the world.

In addition to these new features, this release also brings Docker Fast mode, updates to the main toolbar, and full-text search throughout the solution right from the Search Everywhere pop-up.

 
Rider 2022.1 منتشر شد
اشتراک‌ها
معرفی BlazorWasm Profiler

BlazorWasmProfiler
Poor Man's Blazor Wasm Profiler
It uses AspectInjector to time the execution of every method in your Blazor WASM project. 

معرفی BlazorWasm Profiler
اشتراک‌ها
پیش نمایش JetBrains Fleet منتشر شد

Built from scratch, based on 20 years of experience developing IDEs. JetBrains Fleet uses the IntelliJ code-processing engine, with a distributed IDE architecture and a reimagined UI. 

پیش نمایش JetBrains Fleet منتشر شد
اشتراک‌ها
انتشار nuget 3.3

Big news: a new version of the NuGet clients has been released! This is version 3.3 of the client, with a new command-line and Visual Studio 2015 extension available for use. 

انتشار nuget 3.3
مطالب
سفارشی سازی ASP.NET Core Identity - قسمت اول - موجودیت‌های پایه و DbContext برنامه
با به پایان رسیدن مرحله‌ی توسعه‌ی ASP.NET Identity 2.x مخصوص نگارش‌های ASP.NETایی که از Full .NET Framework استفاده می‌کنند، نگارش جدید آن صرفا بر پایه‌ی ASP.NET Core تهیه شده‌است و در طی یک سری، نحوه‌ی سفارشی سازی تقریبا تمام اجزای آن‌را بررسی خواهیم کرد. جهت سهولت پیگیری این سری، پروژه‌ی کامل سفارشی سازی شده‌ی ASP.NET Core Identity را از مخزن کد DNT Identity می‌توانید دریافت کنید.


پیشنیازهای اجرای پروژه‌ی DNT Identity

 - ابتدا نیاز است حداقل ASP.NET Core Identity 1.1 را نصب کرده باشید.
 - همچنین بانک اطلاعاتی پایه‌ی آن که به صورت خودکار در اولین بار اجرای برنامه تشکیل می‌شود، مبتنی بر LocalDB است. بنابراین اگر قصد تغییری را در تنظیمات Context آن ندارید، بهتر است LocalDB را نیز بر روی سیستم نصب کنید. هرچند با تغییر تنظیم ActiveDatabase به SqlServer در فایل appsettings.json، برنامه به صورت خودکار از نگارش کامل SqlServer استفاده خواهد کرد. رشته‌ی اتصالی آن نیز در مدخل ConnectionStrings فایل appsettings.json ذکر شده‌است و قابل تغییر است. برای شروع به کار، نیازی به اجرای مراحل Migrations را نیز ندارید و همینقدر که برنامه را اجرا کنید، بانک اطلاعاتی آن نیز تشکیل خواهد شد.
 - کاربر پیش فرض Admin سیستم و کلمه‌ی عبور آن از مدخل AdminUserSeed فایل appsettings.json خوانده می‌شوند.
 - تنظیمات ایمیل پیش فرض برنامه به استفاده‌ی از PickupFolder در مدخل Smtp فایل appsettings.json تنظیم شده‌است. بنابراین تمام ایمیل‌های برنامه را جهت آزمایش محلی می‌توانید در مسیر PickupFolder آن یا همان c:\smtppickup مشاهده کنید. محتوای این ایمیل‌ها را نیز توسط مرورگر (drag&drop بر روی یک tab جدید) و یا برنامه‌ی Outlook می‌توان مشاهده کرد.


سفارشی سازی کلید اصلی موجودیت‌های ASP.NET Core Identity

ASP.NET Core Identity به همراه دو سری موجودیت است. یک سری ساده‌ی آن که از یک string به عنوان نوع کلید اصلی استفاده می‌کنند و سری دوم، حالت جنریک که در آن می‌توان نوع کلید اصلی را به صورت صریحی قید کرد و تغییر داد. در اینجا نیز قصد داریم از حالت جنریک استفاده کرده و نوع کلید اصلی جداول را تغییر دهیم. تمام این موجودیت‌های تغییر یافته را در پوشه‌ی src\ASPNETCoreIdentitySample.Entities\Identity نیز می‌توانید مشاهده کنید و شامل موارد ذیل هستند:

جدول نقش‌های سیستم
    public class Role : IdentityRole<int, UserRole, RoleClaim>, IAuditableEntity
    {
        public Role()
        {
        }

        public Role(string name)
            : this()
        {
            Name = name;
        }

        public Role(string name, string description)
            : this(name)
        {
            Description = description;
        }

        public string Description { get; set; }
    }
کار با ارث بری از نگارش جنریک کلاس IdentityRole شروع می‌شود. این کلاس پایه، حاوی تعاریف اصلی فیلدهای جدول نقش‌های سیستم است که اولین آرگومان جنریک آن، نوع کلید اصلی جدول مرتبط را نیز مشخص می‌کند و در اینجا به int تنظیم شده‌است. همچنین یک اینترفیس جدید IAuditableEntity را نیز در انتهای این تعریف‌ها مشاهده می‌کنید. در مورد این اینترفیس و Shadow properties متناظر با آن، در ادامه‌ی بحث با سفارشی سازی DbContext برنامه بیشتر توضیح داده خواهد شد.


در اولین بار اجرای برنامه، نقش Admin در این جدول ثبت خواهد شد.

جدول کاربران منتسب به نقش‌ها
    public class UserRole : IdentityUserRole<int>, IAuditableEntity
    {
        public virtual User User { get; set; }

        public virtual Role Role { get; set; }
    }
کلاس پایه‌ی جدول کاربران منتسب به نقش‌ها، کلاس جنریک IdentityUserRole است که در اینجا با تغییر آرگومان جنریک آن به int، نوع فیلدهای UserId و RoleId آن به int تنظیم می‌شوند. در کلاس سفارشی سازی شده‌ی فوق، دو خاصیت اضافه‌تر User و Role نیز را مشاهده می‌کنید. مزیت تعریف آن‌ها، دسترسی ساده‌تر به اطلاعات کاربران و نقش‌ها توسط EF Core است.


در اولین بار اجرای برنامه، کاربر شماره 1 یا همان Admin به نقش شماره 1 یا همان Admin، انتساب داده می‌شود.


جدول جدید  IdentityRoleClaim سیستم
public class RoleClaim : IdentityRoleClaim<int>, IAuditableEntity
{
   public virtual Role Role { get; set; }
}
در ASP.NET Core Identity، جدول جدیدی به نام RoleClaim نیز اضافه شده‌است. در این سری از آن برای پیاده سازی سطوح دسترسی پویای به صفحات استفاده خواهیم کرد. ابتدا یک سری نقش ثابت در جدول Roles ثبت خواهند شد. سپس تعدادی کاربر به هر نقش نسبت داده می‌شوند. اکنون می‌توان به هر نقش نیز تعدادی Claim را انتساب داد. برای مثال یک Claim سفارشی که شامل ID سفارشی area:controller:action باشد. به این ترتیب و با بررسی سفارشی آن می‌توان سطوح دسترسی پویا را نیز پیاده سازی کرد و مزیت آن این است که تمام این Claims به صورت خودکار به کوکی شخص نیز اضافه شده و دسترسی به اطلاعات آن بسیار سریع است و نیازی به مراجعه‌ی به بانک اطلاعاتی را ندارد.

جدول UserClaim سیستم
public class UserClaim : IdentityUserClaim<int>, IAuditableEntity
{
   public virtual User User { get; set; }
}
می‌توان به هر کاربر یک سری Claim مخصوص را نیز انتساب داد. برای مثال مسیر عکس ذخیره شده‌ی او در سرور، چه موردی است و این اطلاعات به صورت خودکار به کوکی او نیز توسط ASP.NET Core Identity اضافه می‌شوند. البته ما در این سری روش دیگری را برای سفارشی سازی Claims عمومی کاربران بکار خواهیم گرفت (با سفارشی سازی کلاس ApplicationClaimsPrincipalFactory آن).

جداول توکن و لاگین‌های کاربران
public class UserToken : IdentityUserToken<int>, IAuditableEntity
{
   public virtual User User { get; set; }
}

public class UserLogin : IdentityUserLogin<int>, IAuditableEntity
{
   public virtual User User { get; set; }
}
دراینجا نیز نحوه‌ی سفارشی سازی و تغییر جداول لاگین‌های کاربران و توکن‌های مرتبط با آن‌ها را مشاهده می‌کنید. این جداول بیشتر جهت دسترسی به حالت‌هایی مانند لاگین با حساب کاربری جی‌میل مورد استفاده قرار می‌گیرند و کاربرد پیش فرضی ندارند (اگر از تامین کننده‌های لاگین خارجی نمی‌خواهید استفاده کنید).

جدول کاربران سیستم
    public class User : IdentityUser<int, UserClaim, UserRole, UserLogin>, IAuditableEntity
    {
        public User()
        {
            UserUsedPasswords = new HashSet<UserUsedPassword>();
            UserTokens = new HashSet<UserToken>();
        }

        [StringLength(450)]
        public string FirstName { get; set; }

        [StringLength(450)]
        public string LastName { get; set; }

        [NotMapped]
        public string DisplayName
        {
            get
            {
                var displayName = $"{FirstName} {LastName}";
                return string.IsNullOrWhiteSpace(displayName) ? UserName : displayName;
            }
        }

        [StringLength(450)]
        public string PhotoFileName { get; set; }

        public DateTimeOffset? BirthDate { get; set; }

        public DateTimeOffset? CreatedDateTime { get; set; }

        public DateTimeOffset? LastVisitDateTime { get; set; }

        public bool IsEmailPublic { get; set; }

        public string Location { set; get; }

        public bool IsActive { get; set; } = true;

        public virtual ICollection<UserUsedPassword> UserUsedPasswords { get; set; }

        public virtual ICollection<UserToken> UserTokens { get; set; }
    }

    public class UserUsedPassword : IAuditableEntity
    {
        public int Id { get; set; }

        public string HashedPassword { get; set; }

        public virtual User User { get; set; }
        public int UserId { get; set; }
    }
در اینجا علاوه بر نحوه‌ی تغییر نوع کلید اصلی جدول کاربران سیستم، نحوه‌ی افزودن خواص اضافه‌تری مانند نام، تاریخ تولد، مکان، تصویر و غیره را نیز مشاهده می‌کنید. به علاوه جدولی نیز جهت ثبت سابقه‌ی کلمات عبور هش شده‌ی کاربران نیز تدارک دیده شده‌است تا کاربران نتوانند از 5 کلمه‌ی عبور اخیر خود (تنظیم NotAllowedPreviouslyUsedPasswords در فایل appsettings.json) استفاده کنند.
فیلد IsActive نیز از این جهت اضافه شده‌است تا بجای حذف فیزیکی یک کاربر، بتوان اکانت او را غیرفعال کرد.


تعریف Shadow properties ثبت تغییرات رکوردها

در #C ارث‌بری چندگانه‌ی کلاس‌ها ممنوع است؛ مگر اینکه از اینترفیس‌ها استفاده شود. برای مثال IdentityUser یک کلاس است و در اینجا دیگر نمی‌توان کلاس دومی را به نام BaseEntity جهت اعمال خواص اضافه‌تری اعمال کرد. به همین جهت است که اعمال اینترفیس خالی IAuditableEntity را در اینجا مشاهده می‌کنید. این اینترفیس کار علامت‌گذاری کلاس‌هایی را انجام می‌دهد که قصد داریم به آن‌ها به صورت خودکار، خواصی مانند تاریخ ثبت رکورد، تاریخ ویرایش آن و غیره را اعمال کنیم.
در Context برنامه، به اطلاعات src\ASPNETCoreIdentitySample.Entities\AuditableEntity مراجعه شده و متد AddAuditableShadowProperties بر روی تمام کلاس‌هایی از نوع IAuditableEntity اعمال می‌شود. این متد خواص مدنظر ما را مانند ModifiedDateTime به صورت Shadow properties به موجودیت‌های علامت‌گذاری شده اضافه می‌کند.
همچنین متد SetAuditableEntityPropertyValues، کار مقدار دهی خودکار این خواص را انجام خواهد داد. بنابراین دیگر نیازی نیست در برنامه برای مثال IP شخص ثبت کننده یا ویرایش کننده را به صورت دستی مقدار دهی کرد. هم تعریف و هم مقدار دهی آن توسط Change tracker سیستم به صورت خودکار انجام خواهند شد.


تاثیر افزودن Shadow properties را بر روی کلاس نقش‌های سیستم، در تصویر فوق ملاحظه می‌کنید. خواصی که به صورت معمول در کلاس‌های برنامه ظاهر نمی‌شوند و صرفا هدف بازبینی سیستم را برآورده می‌کنند و مدیریت آن‌ها نیز در اینجا کاملا خودکار است.


سفارشی سازی DbContext برنامه

نحوه‌ی سفارشی سازی DbContext برنامه را در پوشه‌ی src\ASPNETCoreIdentitySample.DataLayer\Context و src\ASPNETCoreIdentitySample.DataLayer\Mappings ملاحظه می‌کنید. پوشه‌ی Context حاوی کلاس ApplicationDbContextBase است که تمام سفارشی سازی‌های لازم بر روی آن انجام شده‌است؛ شامل:
 - تغییر نوع کلید اصلی موجودیت‌ها به همراه معرفی موجودیت‌های تغییر یافته:
 public abstract class ApplicationDbContextBase :
  IdentityDbContext<User, Role, int, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>,
  IUnitOfWork
ما در ابتدای بحث، برای مثال کلاس Role را سفارشی سازی کردیم. اما برنامه از وجود آن بی‌اطلاع است. با ارث بری از IdentityDbContext و ذکر این کلاس‌های سفارشی به همراه نوع int کلید اصلی مورد استفاده، کار معرفی موجودیت‌های سفارشی سازی شده انجام می‌شود.

 - اعمال متد BeforeSaveTriggers به تمام نگارش‌های مختلف SaveChanges
protected void BeforeSaveTriggers()
{
  ValidateEntities();
  SetShadowProperties();
  this.ApplyCorrectYeKe();
}
در اینجا پیش از ذخیره‌ی اطلاعات، ابتدا موجودیت‌ها اعتبارسنجی می‌شوند. سپس مقادیر Shadow properties تنظیم شده و دست آخر، ی و ک فارسی نیز به اطلاعات ثبت شده، جهت یک دست سازی اطلاعات سیستم، اعمال می‌شوند.

- انتخاب نوع بانک اطلاعاتی مورد استفاده در متد OnConfiguring
در اینجا است که خاصیت ActiveDatabase تنظیم شده‌ی در فایل appsettings.json خوانده شده و اعمال می‌شوند. تعریف متد GetDbConnectionString را در کلاس SiteSettingsExtesnsions مشاهده می‌کنید. کار آن استفاده‌ی از بانک اطلاعاتی درون حافظه‌ای، جهت انجام آزمون‌های واحد و یا استفاده‌ی از LocalDb و یا نگارش کامل SQL Server می‌باشد. اگر علاقمند بودید تا بانک اطلاعاتی دیگری (مثلا SQLite) را نیز اضافه کنید، ابتدا enum ایی به نام ActiveDatabase را تغییر داده و سپس متد GetDbConnectionString و متد OnConfiguring را جهت درج اطلاعات این بانک اطلاعاتی جدید، اصلاح کنید.

پس از تعریف این DbContext پایه‌ی سفارشی سازی شده، کلاس جدید ApplicationDbContext را مشاهده می‌کنید. این کلاس ‍Context ایی است که در برنامه از آن استفاده می‌شود و از کلاس پایه ApplicationDbContextBase مشتق شده‌است:
 public class ApplicationDbContext : ApplicationDbContextBase
تعاریف موجودیت‌های جدید خود را به این کلاس اضافه کنید.
تنظیمات mapping آن‌ها نیز به متد OnModelCreating این کلاس اضافه خواهند شد. فقط نحوه‌ی استفاده‌ی از آن را به‌خاطر داشته باشید:
        protected override void OnModelCreating(ModelBuilder builder)
        {
            // it should be placed here, otherwise it will rewrite the following settings!
            base.OnModelCreating(builder);

            // Adds all of the ASP.NET Core Identity related mappings at once.
            builder.AddCustomIdentityMappings(SiteSettings.Value);

            // Custom application mappings


            // This should be placed here, at the end.
            builder.AddAuditableShadowProperties();
        }
ابتدا باید base.OnModelCreating را ذکر کنید. در غیراینصورت تمام سفارشی سازی‌های شما بازنویسی می‌شوند.
سپس متد AddCustomIdentityMappings ذکر شده‌است. این متد اطلاعات src\ASPNETCoreIdentitySample.DataLayer\Mappings را به صورت خودکار و یکجا اضافه می‌کند که در آن برای مثال نام جداول پیش فرض Identity سفارشی سازی شده‌اند.


در آخر باید AddAuditableShadowProperties فراخوانی شود تا خواص سایه‌ای که پیشتر در مورد آن‌ها بحث شد، به سیستم به صورت خودکار اضافه شوند.
تمام نگاشت‌های سفارشی شما باید در این میان و در قسمت «Custom application mappings» درج شوند.

در قسمت بعدی، نحوه‌ی سفارشی سازی سرویس‌های پایه‌ی Identity را بررسی خواهیم کرد. بدون این سفارشی سازی و اطلاعات رسانی به سرویس‌های پایه که از چه موجودیت‌های جدید سفارشی سازی شده‌ایی در حال استفاده هستیم، کار Migrations انجام نخواهد شد.


کدهای کامل این سری را در مخزن کد DNT Identity می‌توانید ملاحظه کنید.
مطالب
ASP.NET Web API - قسمت دوم
در قسمت اول به دلایل ایجاد ASP.NET Web API پرداخته شد. در این قسمت، یک مثال ساده از Web API را بررسی می‌کنیم.
تلاش‌های بسیاری توسط توسعه گران صورت پذیرفته است تا فرایند ایجاد وب سرویس WCF در بستر HTTP آسان شود. امروزه وب سرویس هایی که از قالب REST استفاده می‌کنند مطرح هستند.
ASP.NET Web API از مفاهیم موجود در ASP.NET MVC مانند Controllerها استفاده می‌کند و بر مبنای آنها ساخته شده است. بدین شکل، توسعه گر می‌تواند با دانش موجود خود به سادگی وب سرویس‌های مورد نظر را ایجاد کند. Web API، پروتوکل SOAP را به کتاب‌های تاریخی! سپرده است تا از آن به عنوان روشی برای تعامل بین سیستم‌ها یاد شود. امروزه به دلیل فراگیری پروتوکل HTTP، بیشتر محیط‌های برنامه نویسی و سیستم ها، از مبانی اولیه‌ی پروتوکل HTTP مانند اَفعال آن پشتیبانی می‌کنند.
حال قصد داریم تا وب سرویسی را که در قسمت اول با WCF ایجاد کردیم، این بار با استفاده از Web API ایجاد کنیم. به تفاوت این دو دقت کنید.

using System.Web.Http;

namespace MvcApplication1.Controllers
{
    public class ValuesController : ApiController        
    {
        // GET api/values/5
        public string Get(int id)                         
        {
            return string.Format("You entered: {0}", id);
        }
    }
}
اولین تفاوتی که مشهود است، تعداد خطوط کمتر مورد نیاز برای ایجاد وب سرویس با استفاده از Web API است، چون نیاز به interface و کلاس پیاده ساز آن وجود ندارد. در Controller، Web APIهایی که در نقش وب سرویس هستند از کلاس ApiController ارث می‌برند. اَعمال مورد نظر در قالب متدها در Controller تعریف می‌شوند. در مثال قبل، متد Get، یکی از اَعمال است.
نحوه‌ی برگشت یک مقدار از متدها در Web API، مانند WCF است. می‌توانید خروجی متد Get را با اجرای پروژه‌ی قبل در Visual Studio و تست آن با یک مرورگر ملاحظه کنید. دقت داشته باشید که یکی از اصولی که Web API به آن معتقد است این است که وب سرویس‌ها می‌توانند ساده باشند. در Web API، تست و دیباگ وب سرویس‌ها بسیار راحت است. با مرورگر Internet Explorer به آدرس http://localhost:{port}/api/values/3 بروید. پیش از آن، برنامه‌ی Fiddler را اجرا کنید. شکل ذیل، نتیجه را نشان می‌دهد.

در اینجا نتیجه، عبارت "You entered: 3" است که به صورت یک متن ساده برگشت داده شده است.

ایجاد یک پروژه‌ی Web API
در Visual Studio، مسیر ذیل را طی کنید.

File> New> Project> Installed Templates> Visual C#> Web> ASP.NET MVC 4 Web Application 

  نام پروژه را HelloWebAPI بگذارید و بر روی دکمه‌ی OK کلیک کنید (شکل ذیل)

در فرمی که باز می‌شود، گزینه‌ی Web API را انتخاب و بر روی دکمه‌ی OK کلیک کنید (شکل ذیل). البته دقت داشته باشید که ما همیشه مجبور به استفاده از قالب Web API برای ایجاد پروژه‌های خود نیستیم. می‌توان در هر نوع پروژه ای از Web API استفاده کرد.

اضافه کردن مدل
مدل، شی ای است که نمایانگر داده‌ها در برنامه است. Web API می‌تواند به طور خودکار، مدل را به فرمت JSON، XML یا فرمت دلخواهی که خود می‌توانید برای آن ایجاد کنید تبدیل و سپس داده‌های تبدیل شده را در بدنه‌ی پاسخ HTTP به Client ارسال کند. تا زمانی که Client بتواند فرمت دریافتی را بخواند، می‌تواند از آن استفاده کند. بیشتر Clientها می‌توانند فرمت JSON یا XML را پردازش کنند. به علاوه، Client می‌تواند نوع فرمت درخواستی از Server را با تنظیم مقدار هدر Accept در درخواست ارسالی تعیین کند. اجازه بدهید کار خود را با ایجاد یک مدل ساده که نمایانگر یک محصول است آغاز کنیم.
بر روی پوشه‌ی Models کلیک راست کرده و از منوی Add، گزینه‌ی Class را انتخاب کنید.

نام کلاس را Product گذاشته و کدهای ذیل را در آن بنویسید.

namespace HelloWebAPI.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}

مدل ما، چهار Property دارد که در کدهای قبل ملاحظه می‌کنید.

اضافه کردن Controller
در پروژه ای که با استفاده از قالب پیش فرض Web API ایجاد می‌شود، دو Controller نیز به طور خودکار در پروژه‌ی Controller قرار می‌گیرند:

  • HomeController: یک Controller معمول ASP.NET MVC است که ارتباطی با Web API ندارد.
  • ValuesController: یک Controller مختص Web API است که به عنوان یک مثال در پروژه قرار داده می‌شود.


توجه: Controllerها در Web API بسیار شبیه به Controllerها در ASP.NET MVC هستند، با این تفاوت که به جای کلاس Controller، از کلاس ApiController ارث می‌برند و بزرگترین تفاوتی که در نگاه اول در متدهای این نوع کلاس‌ها به چشم می‌خورد این است که به جای برگشت Viewها، داده برگشت می‌دهند.

کلاس ValuesController را حذف و یک Controller به پروژه اضافه کنید. بدین منظور، بر روی پوشه‌ی Controllers، کلیک راست کرده و از منوی Add، گزینه‌ی Controller را انتخاب کنید.

توجه: در ASP.NET MVC 4 می‌توانید بر روی هر پوشه‌ی دلخواه در پروژه کلیک راست کرده و از منوی Add، گزینه‌ی Controller را انتخاب کنید. پیشتر فقط با کلیک راست بر روی پوشه‌ی Controller، این گزینه در دسترس بود. حال می‌توان کلاس‌های مرتبط با Controllerهای معمول را در یک پوشه و Controllerهای مربوط به قابلیت Web API را در پوشه‌ی دیگری قرار داد.

نام Controller را ProductsController بگذارید، از قسمت Template، گزینه‌ی Empty API Controller را انتخاب و بر روی دکمه‌ی OK کلیک کنید (شکل ذیل).

فایلی با نام ProductsController.cs در پوشه‌ی Controllers قرار می‌گیرد. آن را باز کنید و کدهای ذیل را در آن قرار دهید. 

namespace HelloWebAPI.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    using HelloWebAPI.Models;

    public class ProductsController : ApiController
    {

        Product[] products = new Product[] 
        { 
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1.39M }, 
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } 
        };

        public IEnumerable<Product> GetAllProducts()
        {
            return products;
        }

        public Product GetProductById(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                var resp = new HttpResponseMessage(HttpStatusCode.NotFound);
                throw new HttpResponseException(resp);
            }
            return product;
        }

        public IEnumerable<Product> GetProductsByCategory(string category)
        {
            return products.Where(
                (p) => string.Equals(p.Category, category, 
                    StringComparison.OrdinalIgnoreCase));
        }
    }
}

برای ساده نگهداشتن مثال، لیستی از محصولات را در یک آرایه قرار داده ایم اما واضح است که در یک پروژه‌ی واقعی، این لیست از پایگاه داده بازیابی می‌شود. در مورد کلاس‌های HttpResponseMessage و HttpResponseException بعداً توضیح می‌دهیم.
در کدهای Controller قبل، سه متد تعریف شده اند: 

  • متد GetAllProducts که کل محصولات را در قالب نوع <IEnumerable<Product برگشت می‌دهد.
  • متد GetProductById که یک محصول را با استفاده از مشخصه‌ی آن (خصیصه‌ی Id) برگشت می‌دهد.
  • متد GetProductsByCategory که تمامی محصولات موجود در یک دسته‌ی خاص را برگشت می‌دهد.

تمام شد! حال شما یک وب سرویس با استفاده از Web API ایجاد کرده اید. هر یک از متدهای قبل در Controller، به یک آدرس به شرح ذیل تناظر دارند.

GetAllProducts به api/products/

GetProductById به api/products/id/

GetProductsByCategory به api/products/?category=category/

در آدرس‌های قبل، id و category، مقادیری هستند که همراه با آدرس وارد می‌شوند و در پارامترهای متناظر خود در متدهای مربوطه قرار می‌گیرند. یک Client می‌تواند هر یک از متدها را با ارسال یک درخواست از نوع GET اجرا کند.

در قسمت بعد، کار خود را با تست پروژه و نحوه‌ی تعامل jQuery با آن ادامه می‌دهیم.

نظرات مطالب
ایجاد سرویس چندلایه‎ی WCF با Entity Framework در قالب پروژه - 9
ممنون دوست عزیز
درضمن باید تنظیمات زیر روا هم اعمال کنید
Everywhere the problem to this solution was mentioned as re-registering aspNet by using aspnet_regiis.exe. But this did not work for me.
Though this is a valid solution (as explained beautifully here)
but it did not work with Windows 8.
For Windows 8 you need to Windows features and enable everything under ".Net Framework 3.5" and ".Net Framework 4.5 Advanced Services".