‫۶ سال و ۱۲ ماه قبل، دوشنبه ۳ مهر ۱۳۹۶، ساعت ۱۴:۴۲
«... بدون نیاز به وب سرور ...»
به یک حداقل وب سروری نیاز دارد. برای مثال دستور ng serve -o یک وب سرور آزمایشی را بر روی پورت 4200 ایجاد می‌کند؛ برای اجرا و ارائه‌ی برنامه. اجرای مستقیم index.html بدون وب سرور، یعنی پروتکل //:file و این پروتکل دسترسی محدودی را برای اجرای هر نوع برنامه‌ی وب و یا بارگذاری فایل‌ها را در مرورگر دارد. به همین جهت به پروتکل //:http نیاز خواهید داشت و بله ... این مورد هیچ نوع وابستگی به نوع وب سرور ندارد. همینقدر که توانایی پردازش پروتکل http را داشته باشد کافی است.

«... مواردی مانند مسیریابی ...»
در این مورد مفصل در سری مسیریابی برنامه‌های Angular بحث شده‌است و دو قسمت تنظیمات سمت سرور و سمت کلاینت را به همراه دارد.
‫۷ سال قبل، دوشنبه ۲۷ شهریور ۱۳۹۶، ساعت ۱۵:۳۰
شما اگر در این بین نیاز به اطلاعات کاربر جاری داشتید، فقط باید از طریق usermanger و یافتن این کاربر به صورت مستقیم از بانک اطلاعاتی اقدام کنید. برای مثال بلافاصله پس از لاگین اطلاعات HttpContext.Current.User نال هست، چون هنوز درخواست بعدی نرسیده‌است تا این User از کوکی او خوانده شده و مقدار دهی شود. در اینجا فقط باید مستقیما از بانک اطلاعاتی کوئری بگیرید.
یک نکته‌ی تکمیلی: اهمیت دقت داشتن به امضای متد FromSql در EF Core 2.0

در EF Core 2.0، اگر از String Interpolation معرفی شده‌ی در C# 6.0 استفاده شود، متد FromSql این نوع متغیرها را به صورت خودکار تبدیل به پارامترهای کوئری‌های SQL می‌کند. برای مثال کوئری ذیل که در آن userName از طریق String Interpolation معرفی شده‌است:
var userName = "user 1";
var user = context.Users.FromSql($"select top 1 * from Users where name = {userName} ").FirstOrDefault();
if (user != null)
{
   Console.WriteLine(user.Name);
}
یک چنین خروجی SQL ایی را تولید می‌کند:
SELECT TOP(1) [u].[UserId], [u].[IsAdmin], [u].[Name]
FROM (
    select top 1 * from Users where name = @p0
) AS [u]
همانطور که ملاحظه می‌کنید پارامتر p0@ به صورت خودکار بجای {userName} درج شده‌است.

اما ... اگر این کوئری را به نحو ذیل اجرا کنیم:
var sql = $"select top 1 * from Users where name = {userName} ";
user = context.Users.FromSql(sql).FirstOrDefault();
if (user != null)
{
   Console.WriteLine(user.Name);
}
برنامه کرش می‌کند:
 .SqlException: Incorrect syntax near '1'
علت اینجا است که زمانیکه رشته‌ی Interpolation را مستقیما داخل متد FromSql درج می‌کنیم از overload زیر استفاده می‌کند:
 public static IQueryable<TEntity> FromSql<TEntity>(this IQueryable<TEntity> source, FormattableString sql) where TEntity : class;
در اینجا sql از نوع FormattableString معرفی شده‌است.

اما زمانیکه از var استفاده می‌کنیم، یعنی این رشته به نوع string تبدیل می‌شود. در این حالت دیگر از overload فوق استفاده نشده و عملیات تهیه‌ی کوئری‌های پارامتری انجام نخواهد شد. علت کرش برنامه هم همین مورد است. اگر در این حالت بخواهیم از userName استفاده کنیم، باید آن‌را داخل '' محصور کنیم:
 var sql = $"select top 1 * from Users where name = '{userName}' ";
و در نهایت کوئری تولید شده نیز پارامتری نیست:
SELECT TOP(1) [u].[UserId], [u].[IsAdmin], [u].[Name]
FROM (
   select top 1 * from Users where name = 'user 1'
) AS [u]
به عبارتی این نوع کوئری، مستعد به حملات تزریق اس کیوال است. چون بجای user 1 هر نوع ورودی دیگری را نیز می‌توان درج کرد و به علت پارامتری نبودن، این نوع ورودی‌ها می‌توانند ساختار عبارت SQL نوشته شده را تغییر دهند.
بنابراین در حین کار با متد FromSql به overload در حال استفاده دقت داشته باشید. فقط حالت FormattableString آن است که کار تبدیل String Interpolation را به کوئری‌های پارامتری انجام می‌دهد.
‫۷ سال قبل، چهارشنبه ۲۲ شهریور ۱۳۹۶، ساعت ۱۳:۵۷
شامل این موارد هست:
- تغییر نوع داده تاریخ به رشته (در جائیکه schema مربوط به DataSource تعریف می‌شود ):
"addDate": {
       type: "string", // use "date" if you want to use the built-in datapicker
       validation: { required: true }
}
- اتصال افزونه به تکست‌باکس‌های جستجو به صورت زیر هست (جائیکه ستون تاریخ تعریف می‌شود):
filterable: {
                     ui: function(element) {
                     var name = $(element[0]).data("bind").replace("[","").replace("]","").replace(".","").replace(" ","").replace(":","");
                     $(element[0])
                                  .addClass("k-input k-textbox")
                                  .attr("style", "width:100%")
                                  .attr("data-mddatetimepicker", "true")
                                  .attr("data-englishnumber", "true")
                                  .attr("data-trigger", "click")
                                  .attr("data-targetselector", "#" + name)
                                  .attr("data-fromdate", "true")
                                  .attr("data-enabletimepicker", "false")
                                  .attr("data-placement", "right")
                                  .attr("name", name)
                                  .attr("id", name);
                                EnableMdDateTimePickers();
                            }
                        }
- تا اینجا تاریخ شمسی بدون مشکل وارد می‌شود. اما هنگام ارسال به سرور هم شمسی است که پیش از ارسال نیاز به تغییر دارد:
                filter: function(args) {
                    console.log(args);
                    if(args.field === "addDate") {
                        for(var i = 0; i < args.filter.filters.length; i++) {
                            var filterValue = args.filter.filters[i].value;
                            if(filterValue) {
                               args.filter.filters[i].value = moment(filterValue, 'jYYYY/jMM/jDD').format('YYYY-MM-DD');
                            }
                        }
                    }
                },
خلاصه این تغییرات در اینجا ارسال شده‌است.