مطالب
jQuery Ajax و نحوه صحیح ارسال مقادیر به یک وب سرویس

در مورد کار با jQuery Ajax و نحوه فراخوانی یک متد وب سرویس توسط آن، چند مطلب پیشتر ارائه شدند:
بررسی وجود نام کاربر با استفاده از jQuery Ajax در ASP.Net
و ...

تمام این مقالات یک ایراد مهم دارند که امروز با آن مواجه شدم و خلاصه آن به شرح زیر است:
پارامتر data متد Ajax جی‌کوئری را به صورت زیر در نظر بگیرید:
data: "{'username': '" + $('#<%= TextBox1.ClientID %>').val() + "'}",
این روش شاید با بسیاری از ورودی‌ها کار کند اما یک سری از کاراکترها زمانیکه با فرمت JSON ارسال می‌شوند باید اصطلاحا escape شوند که لیست آن‌ها به صورت زیر است:
\b  Backspace (ascii code 08)
\f Form feed (ascii code 0C)
\n New line
\r Carriage return
\t Tab
\v Vertical tab
' Apostrophe or single quote
" Double quote
\ Backslash caracter
برای حل این مشکل می‌توان از اسکریپت استاندارد json2.js که در سایت json.org معرفی شده، استفاده کرد.

ابتدا ارجاعی از این اسکریپت باید به صفحه اضافه شود:
<script src="js/json2.js" type="text/javascript"></script>
سپس مقدار پارامتر data را باید به شکل زیر اصلاح کرد:
 var jsonText = JSON.stringify({ username: $('#<%= TextBox1.ClientID %>').val() });
...

data: jsonText,
متد stringify تمام ملاحظات لازم را در مورد escape کاراکترهای یاد شده و بسیاری از موارد دیگر به صورت خودکار اعمال می‌کند. همچنین از این لحاظ که یک ساختار داده‌ای جاوا اسکریپتی را نیز می‌تواند به معادل متنی آن تبدیل کند، بسیار جالب توجه است.
به عنوان مثالی دیگر، اگر متد وب سرویس ما دو پارامتر داشت، jsonText به شکل زیر در خواهد آمد:
 var jsonText = JSON.stringify({ param1: val1, param2: val2 });
لازم به ذکر است که پشتیبانی از این متد در نگارش‌های آخر اکثر مرورگرهای امروزی در جهت سازگاری با آخرین استانداردهای مصوب جاوا اسکریپت به صورت بومی وجود دارد (از IE8 به بعد و فایرفاکس 3 و یک به بعد)، اما از آنجائیکه کاربران ممکن است هنوز از نگارش‌های قدیمی آن‌ها استفاده کنند، کمک گرفتن از فایل json2.js ضروری به نظر می‌رسد.

Vote on iDevCenter
نظرات مطالب
پیاده سازی Unobtrusive Ajax در ASP.NET Core 1.0
اگر فایل jquery-ajax-unobtrusive.js سه بار در صفحه بارگذاری شود، سه بار درخواست را به سمت سرور ارسال می‌کند. بنابراین بررسی کنید چندبار اسکریپت‌ها را به صفحه اضافه کرده‌اید و کدام قسمت‌ها در حال تزریق اسکریپت‌های اضافی به صفحه هستند؟
نظرات مطالب
نمایش رکوردها به ترتیب اولویت به کمک jQuery UI sortable در ASP.NET MVC
پیشنیازهای مطلب جاری:
- در مورد RenderSection : (^)
- مقدمه‌ای بر jQuery Ajax در MVC : (
^)
- db.SaveChanges : کل مباحث Entity framework سایت (
^)
- EmptyResult و کلا خروجی‌های اکشن متدها: (
^)
- علت استفاده از @Url.Action Sort در حین آدرس دهی: (
^)

نظرات مطالب
افزونه جملات قصار jQuery
نکته‌ای در مورد بارگذاری آفلاین فایل xml وIE
http://stackoverflow.com/questions/436670/local-html-file-ajax-call-and-jquery-woes
مطالب
استفاده از Fluent Validation در برنامه‌های ASP.NET Core - قسمت چهارم - اعتبارسنجی Async سمت کلاینت و یا همان Remote Client Side Validation
در قسمت قبل با نحوه‌ی پیاده سازی اعتبارسنجی‌های سفارشی سمت کلاینت مخصوص کتابخانه‌ی Fluent Validation آشنا شدیم. در این قسمت، یک حالت خاص همان نوع اعتبارسنجی‌های سمت کلاینت را که remote validation نام دارد، بررسی می‌کنیم. در این حالت خاص، نیازی به کدنویسی جاوااسکریپتی خاصی نیست. چون زیرساخت آن به همراه unobtrusive jQuery Ajax خود ASP.NET Core ارائه می‌شود. در اینجا فقط نیاز است تا متادیتای خاص آن‌را تولید کنیم. به عبارتی اینبار هدف ما تنها تولید یک چنین تگ HTML ای است:
<input dir="ltr" class="form-control input-validation-error" 
type="email" 
data-val="true" 
data-val-email="'آدرس ایمیل' is not a valid email address." 
data-val-remote="این آدرس ایمیل هم اکنون مورد استفاده‌است" 
data-val-remote-url="/Home/ValidateUniqueEmail" 
data-val-required="'آدرس ایمیل' must not be empty." 
id="Email" 
name="Email" 
>
که به همراه ویژگی‌های data-val ، data-val-remote و data-val-remote-url است. همینقدر که این سه ویژگی وجود داشته باشند، مابقی منطق اعتبارسنجی سمت کلاینت آن توسط unobtrusive jQuery Ajax (ارسال خودکار Ajax ای مقدار ایمیل، به سمت سرور و دریافت پاسخ) و unobtrusive java script validation مدیریت خواهند شد.


افزودن آدرس ایمیل به مدل کاربران

به همان مدل قسمت قبل، قصد داریم خاصیت آدرس ایمیل را هم اضافه کنیم:
using System.ComponentModel.DataAnnotations;

namespace FluentValidationSample.Models
{
    public class UserModel
    {
        [Display(Name = "نام کاربری")]
        public string Username { get; set; }

        [Display(Name = "سن")]
        public int Age { get; set; }

        [Display(Name = "سابقه کار")]
        public int Experience { get; set; }

        [DataType(DataType.EmailAddress)]
        [Display(Name = "آدرس ایمیل")]
        public string Email { get; set; }
    }
}


ایجاد سرویسی برای بررسی منحصربفرد بودن آدرس ایمیل

در ادامه قصد داریم سرویسی را ایجاد کنیم که برای مثال با بانک اطلاعاتی ارتباط برقرار کرده (در اینجا جهت سهولت ارائه، از یک آرایه استفاده شده‌است) و مشخص می‌کند که آیا ایمیل دریافتی پیشتر استفاده شده‌است یا خیر:
using System.Linq;

namespace FluentValidationSample.Services
{
    public interface IUsersService
    {
        bool IsUniqueEmail(string emailAddress);
    }

    public class UsersService : IUsersService
    {
        public bool IsUniqueEmail(string emailAddress)
        {
            string[] registedEmails = {
                "email@site.com",
                "test@gmail.com"
            };
            return !registedEmails.Contains(emailAddress);
        }
    }
}
این سرویس را هم با طول عمر Scoped به برنامه معرفی می‌کنیم؛ چون طول عمر سرویس‌هایی که با بانک اطلاعاتی و DbContext کار می‌کنند، به همین نحو تعیین می‌شوند:
namespace FluentValidationSample.Web
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<IUsersService, UsersService>();


ایجاد اعتبارسنج سمت سرور بررسی منحصربفرد بودن آدرس ایمیل

در ادامه یک PropertyValidator جدید را ایجاد می‌کنیم تا بتوان توسط آن مقدار ایمیل دریافتی را در سمت سرور، تعیین اعتبار کرد:
using FluentValidation.Validators;
using FluentValidationSample.Services;

namespace FluentValidationSample.ModelsValidations
{
    public class UniqueEmailValidator : PropertyValidator
    {
        private readonly IUsersService _usersService;

        public UniqueEmailValidator(IUsersService usersService)
                : base("این آدرس ایمیل هم اکنون مورد استفاده‌است")
        {
            _usersService = usersService;
        }

        protected override bool IsValid(PropertyValidatorContext context)
        {
            return context.PropertyValue != null &&
                    _usersService.IsUniqueEmail((string)context.PropertyValue);
        }
    }
}
همانطور که مشاهده می‌کنید، در اینجا تزریق سرویس سفارشی IUsersService به سازنده‌ی کلاس اعتبارسنج، مجاز است و بدون مشکل کار می‌کند.
پس از آن جهت سهولت استفاده‌ی از آن، یک متد الحاقی جدید را نیز به نام UniqueEmail به نحو زیر تعریف می‌کنیم:
using FluentValidation;
using FluentValidationSample.Services;

namespace FluentValidationSample.ModelsValidations
{
    public static class CustomValidatorExtensions
    {
        public static IRuleBuilderOptions<T, string> UniqueEmail<T>(
            this IRuleBuilder<T, string> ruleBuilder, IUsersService usersService)
        {
            return ruleBuilder.SetValidator(new UniqueEmailValidator(usersService));
        }
    }
}

یک نکته: اگر دقت کرده باشید، فضای نام این اعتبارسنج در این قسمت FluentValidationSample.ModelsValidations شده‌است:


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


اعمال اعتبارسنجی منحصربفرد بودن ایمیل دریافتی به اعتبارسنج UserModel

پس از تهیه‌ی متد الحاقی UniqueEmail، آن‌را به RuleFor مخصوص خاصیت ایمیل اضافه می‌کنیم. در اینجا نیز تزریق وابستگی سرویس سفارشی IUsersService به سازنده‌ی کلاس اعتبارسنج مجاز است:
using FluentValidation;
using FluentValidationSample.Models;
using FluentValidationSample.Services;

namespace FluentValidationSample.ModelsValidations
{
    public class UserModelValidator : AbstractValidator<UserModel>
    {
        public UserModelValidator(IUsersService usersService)
        {
            RuleFor(x => x.Username).NotNull();
            RuleFor(x => x.Age).NotNull();
            RuleFor(x => x.Experience).LowerThan(nameof(UserModel.Age)).NotNull();
            RuleFor(x => x.Email).EmailAddress().NotNull().UniqueEmail(usersService);
        }
    }
}


ایجاد متادیتای مورد نیاز جهت unobtrusive java script validation در سمت سرور

در ادامه نیاز است ویژگی‌های data-val خاص unobtrusive java script validation را توسط FluentValidation ایجاد کنیم:
using FluentValidation;
using FluentValidation.AspNetCore;
using FluentValidation.Internal;
using FluentValidation.Resources;
using FluentValidation.Validators;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;

namespace FluentValidationSample.ModelsValidations
{
    public class RemoteClientValidator : ClientValidatorBase
    {
        public string RemoteUrl { set; get; }

        public RemoteClientValidator(PropertyRule rule, IPropertyValidator validator) :
            base(rule, validator)
        {
        }

        public override void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            MergeAttribute(context.Attributes, "data-val-remote", GetErrorMessage(context));
            MergeAttribute(context.Attributes, "data-val-remote-url", RemoteUrl);
        }

        private string GetErrorMessage(ClientModelValidationContext context)
        {
            var formatter = ValidatorOptions.MessageFormatterFactory().AppendPropertyName(Rule.GetDisplayName());
            string messageTemplate;
            try
            {
                messageTemplate = Validator.Options.ErrorMessageSource.GetString(null);
            }
            catch (FluentValidationMessageFormatException)
            {
                messageTemplate = ValidatorOptions.LanguageManager.GetStringForValidator<NotEmptyValidator>();
            }
            return formatter.BuildMessage(messageTemplate);
        }
    }
}
در این کدها، تنها قسمت مهم آن، متد AddValidation است که کار تعریف و افزودن متادیتاهای unobtrusive java script validation را انجام می‌دهد و برای مثال سبب رندر تگ HTML ای زیر می‌شود:
<input dir="ltr" class="form-control input-validation-error" 
type="email" 
data-val="true" 
data-val-email="'آدرس ایمیل' is not a valid email address." 
data-val-remote="این آدرس ایمیل هم اکنون مورد استفاده‌است" 
data-val-remote-url="/Home/ValidateUniqueEmail" 
data-val-required="'آدرس ایمیل' must not be empty." 
id="Email" 
name="Email" 
>
که به همراه ویژگی‌های data-val، data-val-remote و data-val-remote-url است تا unobtrusive jQuery Ajax validation را فعال کند.


افزودن اعتبارسنج‌های تعریف شده به تنظیمات برنامه

پس از تعریف UniqueEmailValidator و RemoteClientValidator، روش افزودن آن‌ها به تنظیمات FluentValidation به صورت زیر است:
namespace FluentValidationSample.Web
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<IUsersService, UsersService>();

            services.AddControllersWithViews().AddFluentValidation(
                fv =>
                {
                    fv.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly());
                    fv.RegisterValidatorsFromAssemblyContaining<RegisterModelValidator>();
                    fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;

                    fv.ConfigureClientsideValidation(clientSideValidation =>
                    {
                        // ...

                        clientSideValidation.Add(
                            validatorType: typeof(UniqueEmailValidator),
                            factory: (context, rule, validator) =>
                                        new RemoteClientValidator(rule, validator)
                                        {
                                            RemoteUrl = "/Home/ValidateUniqueEmail"
                                        });
                    });
                }
            );
        }
در اینجا یک RemoteUrl را هم مشاهده می‌کنید که به صورت زیر باید تعریف شود:
namespace FluentValidationSample.Web.Controllers
{
    public class HomeController : Controller
    {
        private readonly IUsersService _usersService;

        public HomeController(IUsersService usersService)
        {
            _usersService = usersService;
        }

         // ...

        public IActionResult ValidateUniqueEmail(string email)
        {
            return Ok(_usersService.IsUniqueEmail(email));
        }
    }
}
زمانیکه اعتبارسنجی سمت کلاینت رخ می‌دهد، آدرس ایمیل، به اکشن متد فوق ارسال شده و یک true و یا false را دریافت می‌کند که بیانگر موفقیت آمیز بودن و یا شکست اعتبارسنجی از راه دور است.


تعریف کدهای جاوا اسکریپتی مورد نیاز

پیش از هرکاری، اسکریپت‌های فایل layout برنامه باید چنین تعریفی را داشته باشند:
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
در اینجا مداخل jquery، سپس jquery.validate و بعد از آن jquery.validate.unobtrusive را مشاهده می‌کنید. در ادامه نیازی به تکمیل فایل js/site.js جهت افزودن کدهای remote client validation نیست و این کدها جزئی از کتابخانه‌ی jquery.validate.unobtrusive هستند.


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

View این قسمت نیز همانند قسمت قبل است که فقط یک آدرس ایمیل به آن اضافه شده‌است:


برای آزمایش آن اگر برای مثال یکی از آدرس‌های ایمیل از پیش تعریف شده‌ی در متد IsUniqueEmail سرویس کاربران را وارد کنیم، با خطای اعتبارسنجی سمت کلاینت فوق روبرو خواهیم شد.


کدهای کامل این سری را تا این قسمت از اینجا می‌توانید دریافت کنید: FluentValidationSample-part04.zip
نظرات مطالب
افزودن هدرهای Content Security Policy به برنامه‌های ASP.NET
ممنون از پاسخ تون.
یه سری از کد‌ها را میشه توی فایل خارجی قرار داد.
ولی کد‌های جاوایی که گریدویو تولید میکنه،چی کار میشه کرد؟
با استفاده از این روش رویدادهایی مثل SelectedIndexChanged  در dropdownlist ،
RowCommand در گریدویو  ، updatepanel و scriptmanager از کار می‌افته.آیا راهی برای این مشکل وجود داره؟
با تشکر


اشتراک‌ها
جاوا اسکریپت، اجکس، جی کوئری، انگیولار و نود چیستند و کاربرد هر کدام چیست؟

Summary

JavaScript is a language written for websites to run in the client’s browser.

AJAX is a way for JavaScript to request data from a server without refreshing the page or blocking the application.

jQuery is a JavaScript library built to automate and simplify common web tasks like AJAX or animation.

Angular is a hip JavaScript framework which is made for building large, single-page web applications.

Node.js allows JavaScript to be run without a browser, and is commonly used to run web servers. 

جاوا اسکریپت، اجکس، جی کوئری، انگیولار و نود چیستند و کاربرد هر کدام چیست؟
مطالب
استفاده از WCF Data Services در برنامه های وب به کمک JQuery
در مطالب قبلی با پروتکل OData و WCF Data Service  و قرارداد‌های کوئری نویسی آن آشنا شدید. حال می‌خواهیم با استفاده از Jquery به داده‌های وب سرویس WCF Data Service دسترسی یابیم. اما پیش نیاز‌های لازم است 

پیش نیاز اول : دسترسی به خروجی Json وب سرویس WCF Data

خروجی پیش فرش وب سرویس WCF Data Services ساختار Xml دارد پس می‌بایست وب سرویس را متوجه سازیم که ما با خروجی Json نیاز داریم. از نسخه 5 به بعد اگر MaxProtocolVersion را بر روی V3 قرار دهیم دیگر با Accept Header برابر application/json کار نخواهد کرد و می‌بایست از  application/json;odata=verbose استفاده نمود یا نسخه پروتکل را بر روی V2 یا پایین‌تر تنطیم کنید. علاوه بر آن کتابخانه‌های و قطعه کد‌های تهیه شده است که با پارامتر format$ این کار را برای ما انجام می‌دهد در زیر آدرس دو نمونه آورده شده است.

  1. DataServicesJSONP
  2. WCF Data Services Toolkit 
قطعه کد اول یک Attribute است که با اضافه کردن آن به بالای کلاس WebService  و استفاده از پارامتر format=json$ در آدرس وب سرویس این کار را برای ما انجام می‌دهد.
[JSONPSupportBehavior]
public class Northwind : DataService<NorthwindEntities>
و نمونه آدرس
http://localhost:8358/Northwind.svc/Products?$format=json
دومی کتابخانه ای است که مانند روش اول عمل می‌کند اما به جای ارث برای از کلاس DataService می‌بایست از کلاس ODataService استفاده نماییم.
نکته: در صورتی که بخواهیم از نسخه V3 استفاده نماییم Accept Header را باید به  application/json;odata=verbose تغییر دهیم
public class Northwind : ODataService<NorthwindEntities>

استفاده از WCF Data Services به کمک Jquery
تابع getJSON  مخصوص درخواست‌های است خروجی بصورت json برگردانده می‌شود اما با نسخه V3 سازگار نمی‌باشد و از روش پارامتر format$ می‌توان استفاده نمود
$.getJSON("Northwind.svc/Products?$format=json", function (data) {
                $.each(data.d, function (i, item) {
                    $("<p/>").html(item.Product_Name + " " + item.Unit_Price).appendTo("#products");
                });
            });

همچنین از تابع Ajax که امکاتات بیشتری را در اختیارمان قرار می‌دهد به راحتی می‌توان استفاده نمود به مثال زیر دقت کنید:
 $.ajax('Northwind.svc/Products', {
                dataType: "json",
                beforeSend: function (xhr) {
                    xhr.setRequestHeader("Accept", "application/json;odata=verbose");
                    xhr.setRequestHeader("MaxDataServiceVersion", "3.0");
                },
                success: function (data) {
                    $.each(data.d, function (i, item) {
                        $("<p/>").html(item.Product_Name + " " + item.Unit_Price).appendTo("#products");
                    });
                }
            });
با اسفاده از beforeSend مقدار Accept Header  و MaxDataServiceVersion را تعیین نموده ایم. 
بنابراین به کمک قرارداده‌های کوئری نویسی که در مطالب قبلی گفته شد می‌توان با استفاده از Url تابع Ajax به داده مورد نظر خود رسید.