مطالب
سایت‌های مهمی که از ASP.NET MVC استفاده می‌کنند

عموما استفاده وسیع از نگارش‌های مختلف ASP.NET مربوط به اینترانت‌های شرکت‌های خصوصی و دولتی است. برنامه‌هایی که هیچ وقت رنگ آسمان را هم نخواهند دید و کسی از آمار یا وجود آن‌ها مطلع نخواهد شد. اما در این بین هستند سایت‌های عمومی که از این فناوری‌ها استفاده می‌کنند. مهم‌ترین و پرترافیک‌ترین سایت‌هایی که در حال حاضر از ASP.NET MVC کمک می‌گیرند شامل موارد زیر هستند:
جالب اینجا است که اخیرا سایت msnbc استفاده وسیعی از RavenDB را هم شروع کرده است.

سایر منابع:

سؤال: چگونه تشخیص دهیم یک سایت از ASP.NET MVC استفاده می‌کند؟

ابتدا افزونه Server Spy را نصب کنید. این افزونه می‌تواند وب سروری را که یک سایت هم اکنون مورد استفاده قرار داده، تشخیص دهد. اگر IIS بود، یعنی این سایت از یکی از مشتقات ASP یا ASP.NET استفاده می‌کند. اگر پسوند صفحات به asp ختم شده بود، ASP‌ کلاسیک دهه نود است. در غیراینصورت یا Web forms است یا MVC. در این حالت به سورس صفحه مراجعه کنید. اگر از ViewState خبری نبود یعنی ASP.NET MVC است.
البته این روش در 90 درصد موارد جواب می‌دهد. می‌شود هدر ارسالی وب سرور را کلا تغییر داد. یعنی ضرورتی ندارد که یک سایت استفاده کننده از IIS حتما اعلام کند که از این وب سرور خاص استفاده می‌کند. یا در ASP.NET Web forms می‌شود ViewState را با ترفندهایی حذف کرد. اما ... این مسایل همه گیر نیست و روش‌ ذکر شده شناسایی، در اکثر موارد جواب می‌دهد.

مطالب
بومی سازی منابع در پروژه‌های ASP.NET Core Web API
اگر پروژه‌ی ما فقط از یک Web API تشکیل شده و نیاز است در قسمت‌های مختلف آن، مانند کنترلرها، سرویس‌ها، اعتبارسنج‌ها و غیره از منابع بومی شده استفاده شود، می‌توان از یک راه حل ساده‌ی «SharedResource» استفاده کرد؛ با این مزایا و شرایط:
 - تمام تعاریف بومی سازی مورد نیاز برنامه در یک تک فایل SharedResource.fa.resx قرار می‌گیرند. این فایل نیز در یک اسمبلی مستقل از برنامه‌ی اصلی اضافه می‌شود.
 - با استفاده از تزریق سرویس IStringLocalizer می‌توان به کلیدهای فایل SharedResource.fa.resx در هر قسمتی از برنامه‌ی Web API دسترسی یافت.
 - در این بین اگر کلیدی یافت نشد، خطایی با ذکر دقیق جزئیات منبع جستجو شده، لاگ می‌شود.
 - کلیدهای بومی سازی data annotations نیز قابل دریافت از فایل SharedResource.fa.resx می‌باشند.
 
در ادامه روش پیاده سازی یک چنین امکاناتی را بررسی می‌کنیم.
 
 
قرار دادن فایل منبع اشتراکی در اسمبلی ExternalResources

پس از ایجاد پروژه‌ی ابتدایی Web API به نام Core3xSharedResource.WebApi، یک اسمبلی جدید را برای مثال به نام Core3xSharedResource.ExternalResources تعریف کرده و در داخل آن پوشه‌ی جدید Resources را تعریف می‌کنیم. به این پوشه، فایل منبع جدیدی را به نام SharedResource.fa.resx اضافه می‌کنیم. در کنار آن باید یک کلاس خالی به نام SharedResource.cs نیز وجود داشته باشد.

کار با ین فایل (و یا فایل‌های دیگری مانند SharedResource.en.resx) همانند تمام فایل‌های منبع استاندارد است و نکته‌ی خاصی را به همراه ندارد.


معرفی فایل منبع اشتراکی به سرویس‌های بومی سازی برنامه

پس از ایجاد و تکمیل فایل منبع اشتراکی، برای معرفی آن به برنامه، ابتدا کلاس جدید LocalizationConfig را تعریف کرده و در آن متد جدید AddCustomLocalization را به صورت زیر معرفی می‌کنیم:
    public static class LocalizationConfig
    {
        public static IMvcBuilder AddCustomLocalization(this IMvcBuilder mvcBuilder, IServiceCollection services)
        {
            mvcBuilder.AddDataAnnotationsLocalization(options =>
                    {
                        const string resourcesPath = "Resources";
                        string baseName = $"{resourcesPath}.{nameof(SharedResource)}";
                        var location = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName).Name;

                        options.DataAnnotationLocalizerProvider = (type, factory) =>
                        {
                            // to use `SharedResource.fa.resx` file
                            return factory.Create(baseName, location);
                        };
                    });

            services.AddLocalization();
            services.AddScoped<IStringLocalizer>(provider =>
                            provider.GetRequiredService<IStringLocalizer<SharedResource>>());

            services.AddScoped<ISharedResourceService, SharedResourceService>();
            return mvcBuilder;
        }
    }
- در اینجا در ابتدا توسط متد AddDataAnnotationsLocalization، کار معرفی اسمبلی ثالثی که باید تعاریف بومی سازی را از آن دریافت کرد، صورت گرفته‌است.
- سپس با استفاده از متد AddLocalization، سرویس‌های پایه‌ی بومی سازی ASP.NET Core به برنامه اضافه می‌شوند. برای مثال پس از این تعریف اگر در هر جائی از برنامه سرویس <IStringLocalizer<SharedResource را تزریق کنید، می‌توان به مداخل فایل منبع اشتراکی، دسترسی یافت.
- در ادامه امکان تزریق سرویس غیرجنریک IStringLocalizer را نیز میسر کرده‌ایم که تعاریف خودش را از همان سرویس توکار <IStringLocalizer<SharedResource دریافت می‌کند. مزیت اینکار، فراهم شدن امکانات بومی سازی، برای مثال در کتابخانه‌هایی مانند Fluent Validation است که دقیقا از سرویس غیرجنریک IStringLocalizer برای دریافت منابع استفاده می‌کنند.
- در آخر تعریف یک سرویس سفارشی را نیز مشاهده می‌کنید که در ادامه‌ی بحث تکمیل خواهد شد.

هدف از متد AddCustomLocalization فوق، خلوت کردن فایل startup برنامه است. این متد به صورت زیر مورد استفاده قرار می‌گیرد:
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpContextAccessor();
            services.AddControllers().AddCustomLocalization(services);
        }

پس از آن نیاز است میان‌افزار بومی سازی را نیز فعال کرد. متد UseCustomRequestLocalization زیر، اینکار را انجام می‌دهد:
    public static class LocalizationConfig
    {
        public static IApplicationBuilder UseCustomRequestLocalization(this IApplicationBuilder app)
        {
            var requestLocalizationOptions = new RequestLocalizationOptions
            {
                DefaultRequestCulture = new RequestCulture(new CultureInfo("fa-IR")),
                SupportedCultures = new[]
                {
                    new CultureInfo("en-US"),
                    new CultureInfo("fa-IR")
                },
                SupportedUICultures = new[]
                {
                    new CultureInfo("en-US"),
                    new CultureInfo("fa-IR")
                }
            };
            app.UseRequestLocalization(requestLocalizationOptions);
            return app;
        }
    }
محل قرارگیری متد UseCustomRequestLocalization فوق در فایل آغازین برنامه، باید به صورت زیر باید باشد:
    public class Startup
    {
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseCustomRequestLocalization();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }


تعریف مدل برنامه به همراه ویژگی‌های بومی سازی شده

در اینجا تعریف RegisterModel را مشاهده می‌کنید که ErrorMessage‌های آن هرچند به ظاهر یک رشته‌ی معمولی هستند، اما در عمل از فایل منبع اشتراکی خوانده می‌شوند:
using System.ComponentModel.DataAnnotations;

namespace Core3xSharedResource.Models.Account
{
    public class RegisterModel
    {
        [Required(ErrorMessage = "Please enter an email address")] // -->> from the shared resources
        [EmailAddress(ErrorMessage = "Please enter a valid email address")] // -->> from the shared resources
        public string Email { get; set; }
    }
}

فایل resx ما دارای یک چنین کلیدهایی است:
<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="&lt;b&gt;Hello&lt;/b&gt;&lt;i&gt; {0}&lt;/i&gt;" xml:space="preserve">
    <value>&lt;b&gt;سلام&lt;/b&gt;&lt;i&gt; {0}&lt;/i&gt;</value>
  </data>
  <data name="About Title" xml:space="preserve">
    <value>درباره</value>
  </data>
  <data name="DNT" xml:space="preserve">
    <value>.NET Tips</value>
  </data>
  <data name="SiteName" xml:space="preserve">
    <value>DNT</value>
  </data>
  <data name="Please enter an email address" xml:space="preserve">
    <value>لطفا ایمیلی را وارد کنید</value>
  </data>
  <data name="Please enter a valid email address" xml:space="preserve">
    <value>لطفا ایمیل معتبری را وارد کنید</value>
  </data>
</root>
یک نکته: در اینجا بهتر است کلیدها را به صورت جملات کامل انگلیسی وارد کرد، تا اگر منبع فارسی معادل آن‌ها یافت نشدند، دقیقا از همان کلید، به عنوان مقدار خروجی سیستم بومی سازی استفاده کند.


آزمایش برنامه

اکنون برنامه‌ی Web API، ‌برای آزمایش آماده‌است. برای مثال در کنترلر زیر، سرویس عمومی IStringLocalizer به سازنده‌ی کلاس تزریق شده‌است و سپس قصد بازگشت مقدار کلید «About Title» را دارد. همچنین خطاهای بومی شده‌ی مدل برنامه را نیز بررسی می‌کنیم:
using Core3xSharedResource.Models.Account;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;

namespace Core3xSharedResource.WebApi.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class NormalIStringLocalizerController : ControllerBase
    {
        private readonly IStringLocalizer _localizer;

        public NormalIStringLocalizerController(IStringLocalizer localizer)
        {
            _localizer = localizer;
        }

        [HttpGet]
        public ActionResult<string> Get()
        {
            var localizedString = _localizer["About Title"];
            if (localizedString.ResourceNotFound)
            {
                return NotFound($"The localization resource with ID:`{localizedString.Name}` not found. SearchedLocation: `{localizedString.SearchedLocation}`.");
            }
            return localizedString.Value;
        }

        [HttpPost]
        public ActionResult<RegisterModel> Post(RegisterModel model)
        {
            return model;
        }
    }
}


حالت get را در تصویر فوق مشاهده می‌کنید. در Web API برای تنظیم زبان مورد استفاده می‌توان از هدری به نام Accept-Language استفاده کرد که برای مثال در اینجا به fa تنظیم شده‌است و نتیجه‌ی آن مراجعه به فایل SharedResource.fa.resx خواهد بود. اگر en-us وارد شود، نیاز خواهد بود تا فایل منبع اشتراکی دیگری را تعریف کنید. البته اگر این هدر تنظیم نشود، با توجه به تنظیمات متد UseCustomRequestLocalization، مقدار پیش‌فرض آن همان fa-IR خواهد بود.

حالت post را نیز در تصویر زیر می‌توان مشاهده کرد:


در اینجا چون ایمیل وارد نشده، هر دو خطای تنظیم شده‌ی در مدل برنامه را دریافت کرده‌ایم و این خطاها نیز فارسی هستند. به این معنا که بومی سازی data annotations نیز به درستی کار می‌کند.


تعریف یک سرویس عمومی برای محصور سازی قابلیت‌های بومی سازی، در برنامه‌های Web API

در ادامه تعریف سرویس SharedResourceService را مشاهده می‌کنید که ثبت آن‌را پیشتر انجام دادیم:
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;

namespace Core3xSharedResource.Services
{
    public interface ISharedResourceService
    {
        string this[string index] { get; }

        IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures);
        string GetString(string name, params object[] arguments);
        string GetString(string name);
    }

    public class SharedResourceService : ISharedResourceService
    {
        private readonly IStringLocalizer _sharedLocalizer;
        private readonly ILogger<SharedResourceService> _logger;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public SharedResourceService(
            IStringLocalizer sharedHtmlLocalizer,
            IHttpContextAccessor httpContextAccessor,
            ILogger<SharedResourceService> logger
            )
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _sharedLocalizer = sharedHtmlLocalizer ?? throw new ArgumentNullException(nameof(sharedHtmlLocalizer));
            _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
        }

        public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures)
        {
            return _sharedLocalizer.GetAllStrings(includeParentCultures);
        }

        public string this[string index] => GetString(index);

        public string GetString(string name, params object[] arguments)
        {
            var result = _sharedLocalizer.GetString(name, arguments);
            logError(name, result);
            return result;
        }

        private void logError(string name, LocalizedString result)
        {
            if (result.ResourceNotFound)
            {
                var acceptLanguage = _httpContextAccessor?.HttpContext?.Request?.Headers["Accept-Language"];
                _logger.LogError($"The localization resource with Accept-Language:`{acceptLanguage}` & ID:`{name}` not found. SearchedLocation: `{result.SearchedLocation}`.");
            }
        }

        public string GetString(string name)
        {
            var result = _sharedLocalizer.GetString(name);
            logError(name, result);
            return result;
        }
    }
}
این سرویس نه فقط دسترسی به IStringLocalizer را محصور می‌کند، بلکه در متد logError آن اینبار خطای بسیار مفیدی جهت دیباگ کردن سیستم بومی سازی لاگ خواهد شد. اگر کلیدی یافت نشود، فایلی یافت نشود و یا زبان ارسالی تنظیمی یافت نشود، خطای آن‌را در لاگ‌های برنامه می‌توانید مشاهده کنید که در حالت عادی کار با IStringLocalizer، لاگ نمی‌شوند و همچنین هیچ خطا و یا استثنائی را نیز سبب نمی‌شوند. به همین جهت دیباگ کردن سیستم بومی سازی بدون این لاگ‌ها، تقریبا غیرممکن است. برای مثال مقدار baseNameهایی را که در کدهای این مطلب مشاهده می‌کنید، بر اساس همین لاگ‌ها تشخیص داده شدند و بدون آن‌ها تشکیل این مقادیر غیرممکن بودند.


کدهای کامل این مطلب را از اینجا می‌توانید دریافت کنید: Core3xSharedResource.zip
نظرات مطالب
ASP.NET Web API - قسمت اول
من فکر کنم مطلب این دوستمون رو این جوری مطرح کنم بهتره
وقتی شما از WCF Data Services استفاده می‌کنید، WCF Data Services Client دارید، که به شما امکان نوشتن کوئری‌های Linq در سمت کلاینت، Change Tracking و Merge و ... رو می‌ده
اما من همچین آیتمی رو برای Web API پیدا نکردم، بهترین چیزی که دیدم Http Client بوده که در حد مثال زدن خوبه، ولی به درد پروژه نویسی نمی‌خوره، این که شما یک کلاینت قوی داشته باشید، خیلی مهمه، Http Client تفاوت مفهومی زیادی با ajax.$ نداره 
حتی در JayData هم همین طور هستش، و شما پشتیبانی خیلی بهتری از WCF Data Services می‌بینید تا از Web API، همین طور در Breeze.js
در اندروید و iOS هم شما پشتیبانی WCF Dat Services Client رو دارید، ولی Web API خیر
موفق باشید
اشتراک‌ها
کار با WebP در ASP.Net MVC
کار با WebP در ASP.Net MVC و نکات مربوط به پشتیبانی مرورگر‌ها از این فرمت و همچنین کش کردن آن
کار با WebP در ASP.Net MVC
مطالب
کار با Kendo UI DataSource
Kendo UI DataSource جهت تامین داده‌های سمت کلاینت ویجت‌های مختلف KendoUI طراحی شده‌است و به عنوان یک اینترفیس استاندارد قابل استفاده توسط تمام کنترل‌های داده‌ای Kendo UI کاربرد دارد. Kendo UI DataSource امکان کار با منابع داده محلی، مانند اشیاء و آرایه‌های جاوا اسکریپتی و همچنین منابع تامین شده از راه دور، مانند JSON، JSONP و XML را دارد. به علاوه توسط آن می‌توان اعمال ثبت، ویرایش و حذف اطلاعات، به همراه صفحه بندی، گروه بندی و مرتب سازی داده‌ها را کنترل کرد.


استفاده از منابع داده محلی
در ادامه مثالی را از نحوه‌ی استفاده از یک منبع داده محلی جاوا اسکریپتی، مشاهده می‌کنید:
    <script type="text/javascript">
        $(function () {
            var cars = [
                { "Year": 2000, "Make": "Hyundai", "Model": "Elantra" },
                { "Year": 2001, "Make": "Hyundai", "Model": "Sonata" },
                { "Year": 2002, "Make": "Toyota", "Model": "Corolla" },
                { "Year": 2003, "Make": "Toyota", "Model": "Yaris" },
                { "Year": 2004, "Make": "Honda", "Model": "CRV" },
                { "Year": 2005, "Make": "Honda", "Model": "Accord" },
                { "Year": 2000, "Make": "Honda", "Model": "Accord" },
                { "Year": 2002, "Make": "Kia", "Model": "Sedona" },
                { "Year": 2004, "Make": "Fiat", "Model": "One" },
                { "Year": 2005, "Make": "BMW", "Model": "M3" },
                { "Year": 2008, "Make": "BMW", "Model": "X5" }
            ];

            var carsDataSource = new kendo.data.DataSource({
                data: cars
            });

            carsDataSource.read();
            alert(carsDataSource.total());
        });
    </script>
در اینجا cars آرایه‌ای از اشیاء جاوا اسکریپتی بیانگر ساختار یک خودرو است. سپس برای معرفی آن به Kendo UI، کار با مقدار دهی خاصیت data مربوط به new kendo.data.DataSource شروع می‌شود.
ذکر new kendo.data.DataSource به تنهایی به معنای مقدار دهی اولیه است و در این حالت منبع داده مورد نظر، استفاده نخواهد شد. برای مثال اگر متد total آن‌را جهت یافتن تعداد عناصر موجود در آن فراخوانی کنید، صفر را بازگشت می‌دهد. برای شروع به کار با آن، نیاز است ابتدا متد read را بر روی این منبع داده مقدار دهی شده، فراخوانی کرد.


استفاده از منابع داده راه دور

در برنامه‌های کاربردی، عموما نیاز است تا منبع داده را از یک وب سرور تامین کرد. در اینجا نحوه‌ی خواندن اطلاعات JSON بازگشت داده شده از جستجوی توئیتر را مشاهده می‌کنید:
    <script type="text/javascript">
        $(function () {
            var twitterDataSource = new kendo.data.DataSource({
                transport: {
                    read: {
                        url: "http://search.twitter.com/search.json",
                        dataType: "jsonp",
                        contentType: 'application/json; charset=utf-8',
                        type: 'GET',
                        data: { q: "#kendoui" }
                    },
                    schema: { data: "results" }
                },
                error: function (e) {
                    alert(e.errorThrown.stack);
                }
            });
        });
    </script>
در قسمت transport، جزئیات تبادل اطلاعات با سرور راه دور مشخص می‌شود؛ برای مثال url ارائه دهنده‌ی سرویس، dataType بیانگر نوع داده مورد انتظار و data کار مقدار دهی پارامتر مورد انتظار توسط سرویس توئیتر را انجام می‌دهد. در اینجا چون صرفا عملیات خواندن اطلاعات صورت می‌گیرد، خاصیت read مقدار دهی شده‌است.
در قسمت schema مشخص می‌کنیم که اطلاعات JSON بازگشت داده شده توسط توئیتر، در فیلد results آن قرار دارد.


کار با منابع داده OData

علاوه بر فرمت‌های یاد شده، Kendo UI DataSource امکان کار با اطلاعاتی از نوع OData را نیز دارا است که تنظیمات ابتدایی آن به صورت ذیل است:
    <script type="text/javascript">
            var moviesDataSource = new kendo.data.DataSource({
                type: "odata",
                transport: {
                    read: "http://demos.kendoui.com/service/Northwind.svc/Orders"
                },
                error: function (e) {
                    alert(e.errorThrown.stack);
                }
            });
        });
    </script>
همانطور که ملاحظه می‌کنید، تنظیمات ابتدایی آن اندکی با حالت remote data پیشین متفاوت است. در اینجا ابتدا نوع داده‌ی بازگشتی مشخص می‌شود و در قسمت transport، خاصیت read آن، آدرس سرویس را دریافت می‌کند.


یک مثال: دریافت اطلاعات از ASP.NET Web API

یک پروژه‌ی جدید ASP.NET را آغاز کنید. تفاوتی نمی‌کند که Web forms باشد یا MVC؛ از این جهت که مباحث Web API در هر دو یکسان است.
سپس یک کنترلر جدید Web API را به نام ProductsController با محتوای زیر ایجاد کنید:
using System.Collections.Generic;
using System.Web.Http;

namespace KendoUI02
{
    public class Product
    {
        public int Id { set; get; }
        public string Name { set; get; }
    }

    public class ProductsController : ApiController
    {
        public IEnumerable<Product> Get()
        {
            var products = new List<Product>();
            for (var i = 1; i <= 100; i++)
            {
                products.Add(new Product { Id = i, Name = "Product " + i });
            }
            return products;
        }
    }
}
در این مثال، هدف صرفا ارائه یک خروجی ساده JSON از طرف سرور است.
در ادامه نیاز است تعریف مسیریابی ذیل نیز به فایل Global.asax.cs برنامه اضافه شود تا بتوان به آدرس api/products در سایت، دسترسی یافت:
using System;
using System.Web.Http;
using System.Web.Routing;

namespace KendoUI02
{
    public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            RouteTable.Routes.MapHttpRoute(
               name: "DefaultApi",
               routeTemplate: "api/{controller}/{id}",
               defaults: new { id = RouteParameter.Optional }
               );
        }
    }
}

در ادامه فایلی را به نام Index.html (یا در یک View و یا یک فایل aspx دلخواه)، محتوای ذیل را اضافه کنید:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Kendo UI: Implemeting the Grid</title>

    <link href="styles/kendo.common.min.css" rel="stylesheet" type="text/css" />
    <link href="styles/kendo.default.min.css" rel="stylesheet" type="text/css" />
    <script src="js/jquery.min.js" type="text/javascript"></script>
    <script src="js/kendo.all.min.js" type="text/javascript"></script>
</head>
<body>

    <div id="report-grid"></div>
    <script type="text/javascript">
        $(function () {
            var productsDataSource = new kendo.data.DataSource({
                transport: {
                    read: {
                        url: "api/products",
                        dataType: "json",
                        contentType: 'application/json; charset=utf-8',
                        type: 'GET'
                    }
                },
                error: function (e) {
                    alert(e.errorThrown.stack);
                },
                pageSize: 5,
                sort: { field: "Id", dir: "desc" }
            });

            $("#report-grid").kendoGrid({
                dataSource: productsDataSource,
                autoBind: true,
                scrollable: false,
                pageable: true,
                sortable: true,
                columns: [
                    { field: "Id", title: "#" },
                    { field: "Name", title: "Product" }
                ]
            });
        });
    </script>
</body>
</html>
- ابتدا فایل‌های اسکریپت و CSS مورد نیاز Kendo UI اضافه شده‌اند.
- گرید صفحه، در محل div ایی با id مساوی report-grid تشکیل خواهد شد.
- سپس DataSource ایی که به آدرس api/products اشاره می‌کند، تعریف شده و در آخر productsDataSource را توسط یک kendoGrid نمایش داده‌ایم.
- نحوه‌ی تعریف productsDataSource، در قسمت استفاده از منابع داده راه دور ابتدای بحث توضیح داده شد. در اینجا فقط دو خاصیت pageSize و sort نیز به آن اضافه شده‌اند. این دو خاصیت بر روی نحوه‌ی نمایش گرید نهایی تاثیر گذار هستند. pageSize تعداد رکورد هر صفحه را مشخص می‌کند و sort نحوه‌ی مرتب سازی را بر اساس فیلد Id و در حالت نزولی قرار می‌دهد.
- در ادامه، ابتدایی‌ترین حالت کار با kendoGrid را ملاحظه می‌کنید.
- تنظیم dataSource و autoBind: true (حالت پیش فرض)، سبب خواهند شد تا به صورت خودکار، اطلاعات JSON از مسیر api/products خوانده شوند.
- سه خاصیت بعدی صفحه بندی و مرتب سازی خودکار ستون‌ها را فعال می‌کنند.
- در آخر هم دو ستون گرید، بر اساس نام‌های خواص کلاس Product تعریف شده‌اند.


سورس کامل این قسمت را از اینجا می‌توانید دریافت کنید:
KendoUI02.zip
 
بازخوردهای دوره
تزریق خودکار وابستگی‌ها در ASP.NET Web API به همراه رها سازی خودکار منابع IDisposable
در حین استفاده از این نکته با خطای زیر برخورد کردم، لطفا راهنمایی بفرمایید:
Bi-directional dependency relationship detected!
البته وابستگی هایی که تزریق میشوند کلاسهای uow و اینترفیس‌های business لازم برای کنترلرAPI هستند. که تنها وجه مشترک این Web API با بقیه استفاده از uow برای DbContext است.