اشتراک‌ها
مقایسه MVC و Flux پترن

A look at how Facebook’s Flux pattern solves things differently, especially in relation to the Model-View-Controller (MVC) pattern. 

مقایسه MVC و Flux پترن
نظرات مطالب
اعمال تزریق وابستگی‌ها به مثال رسمی ASP.NET Identity
سلام مجدد
یه سری Controller پیش فرض هستش که البته mvc هستن مثل AccountController میخواستم ببینم اینا رو با WebApiController هم میتونیم پیاده سازی کنیم.
و سوال دوم این که این AccountApiTestController دقیقا چه کاری انجام میده؟
نظرات مطالب
فعال سازی عملیات CRUD در Kendo UI Grid
کدهای « اصلی » مثال جاری را بازنویسی شده جهت ASP.NET MVC و بدون استفاده از Web API در اینجا می‌توانید مشاهده کنید. با این View و این Controller. کدهای سمت کلاینت و سمت سرور خودتان را با این دو فایل انطباق دهید. 
نظرات مطالب
ASP.NET MVC #9
به آدرس همین page توی آدرس بار که نگاه میکنم
https://www.dntips.ir/Post/812/asp-net-mvc-9
فکر میکنم Post باید action باشه ... درسته؟ پس تکلیف controller چی میشه...؟
 
نظرات مطالب
اعتبارسنجی در فرم‌های ASP.NET MVC با Remote Validation
با بررسی فیلد مورد نظر در خروجی html تولید شده، می‌توانید صحت عملکرد برنامه را بررسی کنید.
مثال زیر در این زمینه می‌باشد که مدل آن در یک class library دیگر است (البته در اینجا به جای استفاده از نام اکشن و نام کنترلر از نام روت استفاده شده است)
حالت اول: مدل برنامه در حالتی که فقط فیلد مورد نظر باید بررسی شود (ایجاد کاربر):
namespace Project.Models
{
    public class EmployeeCreateModel
    {
        [Required]
        [Display(Name = "آدرس ایمیل")]
        [EmailAddress(ErrorMessage = "لطفاً {0} معتبر وارد کنید.")]
        [Remote("UserExistByEmailValidation",
            HttpMethod = "POST",
            ErrorMessage = "ایمیل وارد شده هم اکنون توسط یکی از کاربران مورد استفاده است.‏")]
        public string Email { get; set; }
    
     ...

     }
}
- حالت دوم: مدل برنامه در حالتی که به جز فیلد مورد نظر باید یک فیلد دیگر نیز مورد بررسی قرار گیرد (ویرایش کاربر):
namespace Project.Models
{
    public class EmployeeEditModel
    {
        public int Id { get; set; }

        [Required]
        [Display(Name = "آدرس ایمیل")]
        [EmailAddress(ErrorMessage = "لطفاً {0} معتبر وارد کنید.")]
        [Remote("EmailExistForOtherUserValidation",
            AdditionalFields = "Id",
            HttpMethod = "POST",
            ErrorMessage = "ایمیل وارد شده هم اکنون توسط یکی از کاربران مورد استفاده است.‏")]
        public string Email { get; set; }

        ....

    }
}

کنترلر چک کننده (partial بودن کلاس و virtual بودن اکشن‌ها به دلیل استفاده از T4MVC است):
namespace Project.Web.Controllers
{
    [RoutePrefix("UserValidation")]
    [Route("{Action}")]
    [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
    public partial class UserValidationController : Controller
    {
        readonly IUserService<User> _userService;
        readonly IUnitOfWork _uow;

        public UserValidationController(IUnitOfWork uow, IUserService<User> userService)
        {
            _userService = userService;
            _uow = uow;
        }

        [HttpPost]
        [Route("~/CheckEmail", Name = "UserExistByEmailValidation")]
        public virtual JsonResult CheckEmail(string email)
        {
            return Json(!_userService.UserExistsByEmail(email));
        }

        [HttpPost]
        [Route("~/CheckEmailForOtherUser", Name = "EmailExistForOtherUserValidation")]
        public virtual JsonResult CheckEmailForOtherUser(string email, int id)
        {
            return Json(!_userService.EmailExistForOtherUser(email, id));
        }
    }
}
 فیلد مورد نظر در خروجی Html  تولید شده، باید به صورت زیر باشد:
- حالت اول:

remote validation

- حالت دوم (فیلد Id هم ارسال می‌گردد):

remote validation + additional fields

 در صورتی که خروجی درست بود، باید script‌ها را مورد بررسی قرار دهید که یکی از متدوال‌ترین آن‌ها
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
می‌باشد.
نظرات مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 18 - کار با ASP.NET Web API
ارتقاء به ASP.NET Core 7x

تغییر غیرسازگاری با نگارش‌های قبلی، در ASP.NET Core 7x رخ خواهد که در آن ویژگی [FromServices] که در مطلب جاری بحث شد، پیش‌فرض شده‌است؛ یعنی حتی اگر آن‌را ذکر هم نکردید، مهم نیست و به صورت پیش‌فرض در بین سرویس‌های ثبت شده نیز به دنبال پارامتر اکشن متد مدنظر شما می‌گردد:
Services.AddScoped<SomeCustomType>();

[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
    // Binding from the services
    [HttpPost]
    public ActionResult Post(SomeCustomType service) => Ok();
}
در این مثال، نوع SomeCustomType به صورت یک سرویس، در ابتدای برنامه ثبت شده‌است و همانطور که مشاهده می‌کنید، بدون نیاز به ذکر صریح ویژگی [FromServices]، در اکشن متد Post، مورد استفاده قرار گرفته‌است.
اگر علاقمند به استفاده‌ی از این حالت پیش‌فرض نیستند، روش غیرفعال کردن آن به صورت زیر است:
services.Configure<ApiBehaviorOptions>(options =>
{
     options.DisableImplicitFromServicesParameters = true;
});
نظرات مطالب
جایگزین کردن jQuery با JavaScript خالص - قسمت پنجم - درخواست‌های Ajax

یک نکته‌ی تکمیلی: روش لغو صف درخواست‌های مکرر fetch ارسالی به سمت سرور

ورودی جستجوی بالای صفحه‌ را درنظر بگیرید که به‌ازای هربار ورود حرفی، یک درخواست fetch جدید را به سمت سرور ارسال می‌کند تا نتایج جستجوی حاصل را دریافت کند. مشکل اینجاست که ما تنها به آخرین درخواست fetch ارسال شده‌ی به سمت سرور نیاز داریم و نه به تمام درخواست‌های دیگری که صادر شده‌اند. به همین جهت این صف درخواست‌های fetch قبلی، غیربهینه بوده و ترافیک بالایی را سبب می‌شوند. یک روش مواجه شدن با این مساله، استفاده از مفهومی به نام debounce است که در پشت صحنه، از یک تایمر استفاده می‌کند و فقط هر چند ثانیه یکبار، یک درخواست جدید را به همراه آخرین متن ورودی، به سمت سرور ارسال خواهد کرد. راه دیگری هم برای مواجه شدن با این مشکل، در مرورگرهای جدید پیش‌بینی شده‌است که AbortController نام دارد. با استفاده از آن می‌توان «سیگنالی» را به صف درخواست‌های پرتعداد fetch قبلی حاصل از ورود اطلاعات کاربر ارسال کنیم که ... «لغو شوید» و به سمت سرور ارسال نشوید.

برای توضیح بهتر آن، به مثال زیر دقت کنید:

<!DOCTYPE html>
<html>
  <body>
    <input id="search" type="number" />
    <script>
      const results = [];
      const search = document.getElementById("search");

      let controller = new AbortController();
      let signal = controller.signal;

      const onChange = () => {
        const value = search.value;
        if (value) {
          controller.abort();
          controller = new AbortController();
          signal = controller.signal;
          getPost(value, signal);
        }
      };
      search.onkeyup = onChange;
    </script>
  </body>
</html>

- در اینجا یک input box را داریم که ابتدا، یافت شده و سپس به رخ‌داد onkeyup آن، متد onChange نسبت داده شده‌است تا هربار که کاربر، اطلاعاتی را وارد می‌کند، فراخوانی شود.

- در ابتدای اسکریپت هم نحوه‌ی نمونه سازی شیء استاندارد جاوااسکریپتی AbortController و دسترسی به شیء signal آن‌را مشاهده می‌کنید.

- در متد onChange، ابتدا مقدار جدید ورودی کاربر، دریافت می‌شود، سپس این AbortController، لغو می‌شود و بعد یک نمونه‌ی جدید از آن ایجاد شده و مجددا به شیء signal آن دسترسی پیدا می‌کنیم تا آن‌را به متد getPost ارسال کنیم. این متد هم چنین پیاده سازی را دارد:

const getPost = (value, signal) => {
          fetch(
            `https://site.com/search/${value}`,
            { signal }
          );          
      };

همانطور که مشاهده می‌کنید، تابع fetch، قابلیت پذیرش شیء signal را هم دارد. زمانیکه با هربار تایپ کاربر، متد ()controller.abort فراخوانی می‌شود، سیگنالی را به fetch «قبلی» متصل به آن ارسال می‌کند که ... دیگر به سمت سرور ارسال نشو و متوقف شو. با اینکار فقط آخرین ورودی کاربر، سبب بروز یک fetch موفق می‌شود و ترافیک ارسالی به سمت سرور کاهش پیدا می‌کند (چون تمام fetchهای قبلی، سیگنال abort را دریافت کرده‌اند)؛ مانند مثال زیر که کاربر، 5 بار حروفی را وارد کرده و به ازای هربار ورود حرفی، یک درخواست fetch جدید، ایجاد شده، اما ... فقط آخرین درخواست ارسالی او موفق بوده و نتیجه‌ای را بازگشت داده و مابقی درخواست‌ها ... abort شده‌اند. این عملیات abort، در سمت کاربر اعمال می‌شود؛ یعنی اصلا درخواستی به سمت سرور ارسال نمی‌شود و این لغو درخواست، توسط برنامه‌ی سمت سرور انجام نشده‌است.

نظرات مطالب
فعال سازی و پردازش صفحات پویای افزودن، ویرایش و حذف رکوردهای jqGrid در ASP.NET MVC
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
جالب اینجاست ویرایش خطی کار میکنه و وارد متد مربوطه میشه اما حذف خطی وارد متد مربوطه نمیشه.
من نوعش از هم از حالت Get به Post تغییر دادم بازم خطا میداد.
 [HttpPost]
        public ActionResult EditProductData(string oper, string title,string groupTitle,string shopTitle,int AvailableCount,int Priority, int? id)
        {
            if (oper == "add")
            {
                var product = new Product()
                {
                    Title = title,
                    
                };
                db.Products.Add(product);
                db.SaveChanges();
                return Content("true");
            }
            else if (oper == "del")
            {
                var product = db.Products.Find(id);
                db.Products.Remove(product);
                return Content("true");
            }
            else if (oper == "edit")
            {
                var product = db.Products.Find(id);
                product.Title = title;
                product.GroupId = int.Parse(groupTitle);
                product.ShopId = int.Parse(shopTitle);
                product.AvailableCount = AvailableCount;
                product.Priority = Priority;
                db.SaveChanges();
                return Content("true");
            }
            return Content("false");
        }

اشتراک‌ها
ترکیب HttpPost و ValidateAntiForgeryToken

I’ve been kicking around the idea of combining [HttpPost] and [ValidateAntiForgeryToken] in an application using authentication cookies. Both attributes typically appear together to prevent cross-site request forgeries in MVC applications using cookie based authentication. The result looks like the following.  

ترکیب HttpPost و  ValidateAntiForgeryToken