نظرات مطالب
بار کردن ساعت و تاریخ فعلی سرور با JQuery Ajax
سلام
همونطور که جناب فتح اللهی فرمودند، بهتر هست که یک بار زمان را از سرور دریافت کنید و سپس بروزرسانی را بوسیله جاوا اسکریپت انجام دهید.
بنده در ارتباط با این بحث، یک کلاس ساده نوشتم که می‌تونه عملیات بروزرسانی را انجام بده.

var MyTime = function () {
    var date;
    var tag;

    var init = function (hour, minute, seconds, tagId) {
        var constructor = getConstructorString(hour, minute, seconds);
        date = new Date(constructor);
        tag = document.getElementById(tagId);
        //console.log('MyTime : Init(%s, %s, %s, %s)', hour, minute, seconds, tagId);
    };

    var run = function () {
        update();
        window.setInterval(update, 1000);
        //console.log('MyTime : Run');
    };

    var update = function updateClock() {
        var h = date.getHours();
        var m = date.getMinutes();
        var s = date.getSeconds();

        s++;
        if (s == 60) { m++; s = 0; };
        if (m == 60) { h++; m = 0; };
        if (h == 13) h = 1;

        var constructor = getConstructorString(h, m, s);
        date = new Date(constructor);

        h = (h < 10) ? ("0" + h) : h;
        m = (m < 10) ? ("0" + m) : m;
        s = (s < 10) ? ("0" + s) : s;

        tag.innerHTML = h + ":" + m + ":" + s;
        //console.log('MyTime : update');
    };

    var getConstructorString = function (hour, minute, seconds) {
        //console.log('MyTime : getConstructorString');
        return '01/01/2000 ' + hour + ':' + minute + ':' + seconds;
    };

    return {
        Init: init,
        Run: run
    };
}


روش کار به این صورت هست که شما یک بار متد Init را به همراه پارامترهای (ساعت، دقیقه، ثانیه، آی‌دی تگ) فراخوانی می‌کنید، در نهایت برای اجرای ساعت، یک بار هم متد Run را فراخوانی می‌کنید.

مثال :
myTime = new MyTime();
myTime.Init(12, 59, 50, 'clock');
myTime.Run();

امیدوارم مفید بوده باشه .
نظرات مطالب
باگ Directory Traversal در سایت
- این مورد چطور؟
var path = Server.MapPath("~/App_Data/../web.config");
حتما یکبار خروجی آن‌را دیباگ کنید؛ جالب است.
کاربر هم بجای مسیر یک تصویر یا فایل، مسیر زیر را وارد کرده:
../web.config

+ عرض کردم در راه‌حل‌های عنوان شده.
اولین بررسی دریافتی از کاربر باید این مورد باشد:
var fileName = Path.GetFileName("~/web.config");
و نه استفاده مستقیم از نام دریافتی از وب.
خروجی متد فوق (web.config خالی) دیگر به ریشه سایت و یا هیچ مسیری اشاره نخواهد کرد.
نظرات مطالب
تعریف نوع جنریک به صورت متغیر
موردی که من بهش برخورد کردم این است:
فرض کنید یک متد جنریک دارید که T آن باید به صورت متغیر ساخته شود. مثلا نوع آن EnumStringType of T است.
این T هم هر بار در زمان اجرا بر اساس Enum های تعریف شده در اسمبلی فرق می‌کنه. متد مورد نظر هم آرگومانی نداره. Map.Type EnumStringType of T است. اینجا است که نیاز  خواهید داشت مراحلی که عنوان شد طی شود. یک مرحله خاصیت جنریک پویا تولید شود. یک مرحله متد پویای جنریک تولید شود و بعد هم فراخوانی آن.
مطالب
وی‍‍ژگی های پیشرفته ی AutoMapper - قسمت اول
در پست قبلی مقدمه‌ای داشتیم بر AutoMapper؛ مثالی که در اون پست عنوان شد ساده‌ترین و پرکاربردترین روش استفاده از AutoMapper هست بنام Flattening که در واقع از یک شیء کل به یک شیء کوچکتر می‌رسیم.
همانطور که در قسمت اول گفتم AutoMapper کارش رو بر اساس قراردادها انجام میده یا همون Convention Base. یکی از قردادهای AutoMapper، نگاشت براساس نام اعضای اون شی هست؛ مثلا در مثال قبلی FirstName در مبداء، به خاصیتی با همین نام نگاشت شد و ...

Projection
روش استفاده بعدی که به اون Projection (معنی فارسی خوب برا Projection چیه ؟) میگن برای مواقعی هست که اعضای یک شیء در مبداء، همتایی در مقصد ندارد (از نظر نام) و در واقع می‌خواهیم یک شیء رو به یک شیء دیگه تغییر شکل بدیم.
مدل زیر رو در نظر بگیرید:
  public class Person
    {
        public int Id { get; set; }

        public string FirstName { get; set; }       

        public string LastName { get; set; }

    }

  که قرار است به مدل PersonDTO نگاشت بشه.
  public class PersonDTO
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public string Family { get; set; }

public string FullName { get; set; }

        public string Email { get; set; }
    }
همنطور که می‌بینید در مقصد خاصیت‌هایی داریم که در مبداء همتایی ندارند. برای نگاشت چنین اشیایی، از متد ForMember  استفاده و نگاشت‌های شی‌های موردنظر رو Custom می‌کنیم.
 Mapper.CreateMap<Person, PersonDTO>().ForMember(des => des.Name, op => op.MapFrom(src => src.FirstName)).
                ForMember(des => des.FullName, op => op.MapFrom(src => src.FirstName + " " + src.LastName)).ForMember(
                    des => des.Email, op => op.Ignore());
متد ForMember  از یک Action Delegate  برای کانفیگ کردن هر عضو استفاده میکنه. در مثال بالا ما از MapFrom برای اعمال نگاشت Custom  استفاده کردیم.
AutoMapper.IMappingExpression<TSource,TDestination>.ForMember(System.Linq.Expressions.Expression<System.Func<TDestination,object>>, System.Action<AutoMapper.IMemberConfigurationExpression<TSource>>)

نکته:برای تست کردن اینکه آیا نگاشت ما Exception  داره یا نه میتوان از متد زیر استفاده کرد.
Mapper.AssertConfigurationIsValid();

نکته
: همیشه موقع نگاشت، اعضای شیء مقصد برای AutoMapper  مهمن؛ مثلا در مثال بالا خاصیت LastName در مبداء به هیچ عضوی در مقصد نگاشت نشده (به صورت مستقیم) و این تولید Exception  نمیکنه ولی برعکس اون باعث تولید Exception میشه؛ مثلا اگه خاصیت Email  رو که در مبداء همتایی نداره رو کانفیگ نکنیم، باعث تولید Exception میشه.
 
نحوه استفاده
var person = new Person
                {
                    Id = 1,
                    FirstName = "Mohammad",
                    LastName = "Saheb",
                    
                };
var personDTO = Mapper.Map<Person, PersonDTO>(person);
خروجی به شکل زیر میشه


Collection
بعد از نوشتن کانفیگ نگاشت‌ها، بدون نیاز به تنظیمات خاصی میتونیم مجموعه ای از شی‌های مبداء رو به مقصد نگاشت کنیم. مجموعه‌های پشتیبانی شده به شرح زیرن.
IEnumerable, IEnumerable<T>, ICollection, ICollection<T>, IList, IList<T>, List<T>.
و البته آرایه ها.
مثال
var persons = new[]
                {
                    new Person { Id = 1, FirstName = "Mohammad", LastName = "Saheb" },
                    new Person { Id = 2, FirstName = "Babak", LastName = "Saheb" }
                };

var personDTOs = Mapper.Map<Person[], List<PersonDTO>>(persons);
خروجی به شکل زیر میشه

Nested Mappings
برای نگاشت کلاس‌های تو در تو از این روش استفاده می‌کنیم و ...
فرض کنید در کلاس Person خاصیتی از نوع Address داریم و در کلاس PersonDTO  خاصیتی از نوع AddressDTO.
public class Address
    {
        public string Ad1 { get; set; }
        public string Ad2 { get; set; }
    }


public class AddressDTO
    {
        public string Ad1 { get; set; }
        public string Ad2 { get; set; }
    }
برای نگاشت‌هایی از این دست باید تنظیمات نگاشت مربوط به نوع‌های تودرتو را صریحا معین کنیم.
Mapper.CreateMap<Address, AddressDTO>();
نکته: هرچند منطقی‌تر بنظر میرسه که تعریف نگاشت‌های داخلی ابتدا بیاد، ولی فرقی نمیکنه که تعریف این نگاشت قبل یا بعد از نگاشت اصلی باشه.
ادامه دارد...
نظرات مطالب
نحوه استفاده از ViewModel در ASP.NET MVC
شما اگر که از Automapper استفاده می‌کنی باید ابتدا یک Map ایجاد کنی و بهتر است که این کار در متد Application_Start  انجام بگیرد.به طور مثال:

protected void Application_Start()
        {
          //مپ کردن مدل به ویومدل
          Mapper.CreateMap<DomainClasses.Product, ProductListVM>();
          //مپ کردن ویومدل به مدل  
          Mapper.CreateMap<ProductCreateVM,DomainClasses.Product>();
        }
حال فرض بگیر دیتایی داری که میخوای انتصاب بدی به ViewModel به این شکل عمل میکنی:
public ActionResult ShowList()
{
var productList = _cotext.Products.ToList();
//انتصاب
 var viewmodel = Mapper.Map<List<domain.Products>, List<ProductListVM>>(productList);
 return View(viewmodel);
}
حال برعکس میخوای ViewModel انتصاب بدی به Model :
[HttpPost]
        public virtual ActionResult Create(ProductCreateVM product)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var model = Mapper.Map<ProductCreateVM, domain.Product>(product);
                    _cotext.Products.Add(model);
                    _cotext.SaveChanges();
                    return RedirectToAction(ShowList);
                }
                return View(product);
            }
            catch
            {
                
            }
        }
امیدوارم به درد بخوره.قبل از هر چیز مطالب مربوط به AutoMapper سایت را مطالعه کن مثل:
اگرم خواستی میتونی دستی این انتصاب‌ها را انجام بدی البته من پیشنهاد نمیکنم.
مطالب دوره‌ها
مثال - نمایش بلادرنگ میزان مصرف CPU و حافظه سرور بر روی کلیه کلاینت‌های متصل توسط SignalR
یکی از کاربردهای جالب SignalR می‌تواند به روز رسانی مداوم صفحه نمایش کاربران، توسط اطلاعات ارسالی از طرف سرور باشد. در ادامه قصد داریم به عنوان منبع داده، آمار کارآیی سرور را به کلاینت‌ها ارسال کنیم و سپس به تصویری همانند شکل ذیل برسیم:


در اینجا از Smoothie Charts برای ترسیم نمودارهای بلادرنگ سازگار با Canvas مخصوص HTML5 استفاده شده است.


پیشنیازها
پیشنیازهای این مطلب با مطلب «مثال - نمایش درصد پیشرفت عملیات توسط SignalR» یکی است. برای مثال، نحوه دریافت وابستگی‌ها، تنظیمات فایل global.asax و افزودن اسکریپت‌ها، تفاوتی با مثال قبلی ندارند.


تهیه منبع داده اطلاعات نمایشی

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace SignalR04.Common
{
    public class Counter
    {
        public string Name { set; get; }
        public float Value { set; get; }
    }

    public class PerformanceCounterProvider
    {
        private readonly List<PerformanceCounter> _counters = new List<PerformanceCounter>();

        public PerformanceCounterProvider()
        {
            _counters.Add(new PerformanceCounter("Processor", "% Processor Time", "_Total", readOnly: true));
            _counters.Add(new PerformanceCounter("Memory", "Pages/sec", readOnly: true));
            _counters.Add(new PerformanceCounter("PhysicalDisk", "% Disk Time", "_Total", readOnly: true));
        }

        public IList<Counter> GetResults()
        {
            return _counters.Select(c => new Counter
                                        {
                                            Name = c.CategoryName, 
                                            Value = c.NextValue() 
                                        }).ToList();
        }
    }
}
کلاس PerformanceCounterProvider، سه مؤلفه کارآیی سرور را بررسی کرده و هربار توسط متد GetResults، آن‌ها را بازگشت می‌دهد. از این منبع داده، در هاب برنامه استفاده خواهیم کرد.


تهیه هاب ارسال داده‌ها به کلاینت‌ها

using System.Threading;
using Microsoft.AspNet.SignalR;
using ThreadTimer = System.Threading.Timer;

namespace SignalR04.Common
{
    public class PerformanceCounterHub : Hub
    {
        private ThreadTimer _threadTimer; //keep it alive   
        private readonly PerformanceCounterProvider _perfService = new PerformanceCounterProvider();

        public PerformanceCounterHub()
        {
            _threadTimer = new ThreadTimer(timerCallback, null, Timeout.Infinite, 1000);
            _threadTimer.Change(dueTime: 1000, period: 2000);
        }

        private void timerCallback(object state)
        {
            var results = _perfService.GetResults();
            this.Clients.All.newCounters(results);
        }        
    }
}
در این هاب، یک thread timer ایجاد شده است که هر دو ثانیه یکبار، اطلاعات را از PerformanceCounterProvider دریافت و سپس با فراخوانی this.Clients.All.newCounters، آن‌ها را به کلیه کلاینت‌های متصل ارسال می‌کند.
این هاب به صورت خودکار با اولین بار وهله سازی، پس از فراخوانی متد connection.hub.start در سمت کلاینت، شروع به کار می‌کند.


کدهای سمت کلاینت نمایش نمودارها

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.signalR-1.1.3.min.js" type="text/javascript"></script>
    <script type="text/javascript" src='<%= ResolveClientUrl("~/signalr/hubs") %>'></script>
    <script src="Scripts/smoothie.js" type="text/javascript"></script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div>
            <h2>Processor</h2>
            <canvas id="Processor" width="800" height="100"></canvas>
        </div>
        <div>
            <h2>Memory</h2>
            <canvas id="Memory" width="800" height="100"></canvas>
        </div>
        <div>
            <h2>PhysicalDisk</h2>
            <canvas id="PhysicalDisk" width="800" height="100"></canvas>
        </div>
    </div>
    </form>
    <script type="text/javascript">
        var ChartEntry = function (name) {
            var self = this;
            self.name = name;
            self.chart = new SmoothieChart({ millisPerPixel: 50, labels: { fontSize: 15} });
            self.timeSeries = new TimeSeries();
            self.chart.addTimeSeries(self.timeSeries, { lineWidth: 3, strokeStyle: "#00ff00" });
        };

        ChartEntry.prototype = {
            addValue: function (value) {
                var self = this;
                self.timeSeries.append(new Date().getTime(), value);
            },

            start: function () {
                var self = this;
                self.canvas = document.getElementById(self.name);
                self.chart.streamTo(self.canvas);
            }
        };

        $(function () {
            $.connection.hub.logging = true;
            var performanceCounterHub = $.connection.performanceCounterHub;
            var charts = [];
            performanceCounterHub.client.newCounters = function (updatedCounters) {                
                $.each(updatedCounters, function (index, updateCounter) {
                    var entry;
                    $.each(charts, function (idx, chart) {                        
                        if (chart.name == updateCounter.Name) {
                            entry = chart;
                            return;
                        }
                    });

                    if (!entry) {
                        entry = new ChartEntry(updateCounter.Name);
                        charts.push(entry);
                        entry.start();                        
                    }
                    entry.addValue(updateCounter.Value);
                });
            };
            $.connection.hub.start();
        });
    </script>
</body>
</html>
- در ابتدا سه canvas بر روی صفحه قرار گرفته‌اند که معرف سه PerformanceCounter دریافتی از سرور هستند.
- id هر canavs به Name اطلاعات دریافتی از سرور تنظیم شده است تا نمودارها در جای صحیحی ترسیم شوند.
- سپس نحوه کپسوله سازی SmoothieChart را مشاهده می‌کنید؛ چطور می‌توان از آن یک شیء جاوا اسکریپتی ایجاد کرد و چطور اطلاعات را به آن اضافه نمود.
- نهایتا کار هاب را آغاز می‌کنیم. Callback ایی به نام performanceCounterHub.client.newCounters دقیقا متصل است به فراخوانی  this.Clients.All.newCounters سمت سرور. در اینجا updatedCounters دریافتی، یک آرایه جاوا اسکریپتی است که هر عضو آن دارای Name و Value است. بر این اساس، تنها کافی است این مقادیر را که هر دو ثانیه یکبار به روز می‌شوند، به SmoothieChart برای ترسیم ارسال کنیم.


کدهای کامل این مثال را از اینجا نیز می‌توانید دریافت کنید:
SignalR04.zip
 
نظرات مطالب
آزمایش Web APIs توسط Postman - قسمت ششم - اعتبارسنجی مبتنی بر JWT
بله حرف شما درسته؛ من از ورژن 3 استفاده میکنم. ولی در پروژه ای که دارم از تابع : 
        [HttpPost("[action]")]
        public async Task<IActionResult> RefreshToken([FromBody]JToken jsonBody)
        {
            var refreshTokenValue = jsonBody.Value<string>("refreshToken");
  استفاده میکنم، و اگر بخواهم معادل را در System.Text. Json استفاده کنم باید به چه صورتی کار کنم؟ (معادل JToken)
اشتراک‌ها
ارسال Request ها به صورت Parallel در ASP.NET CORE
    public async Task<IEnumerable<UserDto>> GetUsersInParallelInWithBatches(IEnumerable<int> userIds)
    {
        var tasks = new List<Task<IEnumerable<UserDto>>>();
        var batchSize = 100;
        int numberOfBatches = (int)Math.Ceiling((double)userIds.Count() / batchSize);

        for (int i = 0; i < numberOfBatches; i++)
        {
            var currentIds = userIds.Skip(i * batchSize).Take(batchSize);
            tasks.Add(client.GetUsers(currentIds));
        }
            
        return (await Task.WhenAll(tasks)).SelectMany(u => u);
    }




ارسال Request ها به صورت Parallel در ASP.NET CORE
نظرات مطالب
ASP.NET MVC #8
سورس کامل مثال‌های این سری رو دریافت کنید: MVC_Samples  
جایی که وهله‌ای از اشیاء به View متناظر ارسال می‌شود در اکشن متد مشخص شده است (return View):
public ActionResult Index()
{
    var products = new Products();
    return View(products);  
}
نظرات مطالب
آشنایی با NHibernate - قسمت هشتم
با تشکر از تذکر شما.ولی کد زیر هم در صورت بروز خطا چیزی را برنمی گرداند. یعنی متد Delete چه با موفقیت به پایان برسد یا خطایی در حذف رکورد رخ دهد باز ;return true اجرا می شود.!؟
using(var repository = new Repository())
{
repository.Delete(myClass);
return true;
}