مطالب
چک لیست ارتقاء به HTTPS مخصوص یک برنامه‌ی ASP.NET MVC 5x
پس از فعالسازی HTTPS بر روی سایت خود، در جهت بهبود امنیت برنامه‌های ASP.NET MVC 5.x، می‌توان درخواست کوکی‌های صرفا ارسال شده‌ی از طریق اتصال‌های HTTPS، اجبار به استفاده‌ی از آدرس‌های HTTPS و هدایت خودکار به آدرس‌های HTTPS را نیز فعالسازی کرد.


کوکی‌هایی که باید HTTPS only شوند

کوکی‌های پیش‌فرض برنامه‌های ASP.NET به صورت HTTP Only به سمت کلاینت ارسال می‌شوند. این کوکی‌ها توسط اسکریپت‌ها قابل خوانده شدن نیستند و به همین جهت یکی از راه‌های مقاومت بیشتر در برابر حملات XSS به شمار می‌روند. پس از ارتقاء به HTTPS، این کوکی‌ها را هم می‌توان HTTPs Only کرد تا فقط به کلاینت‌هایی که از طریق آدرس HTTPS سایت به آن وارد شده‌اند، ارائه شود:
1) کوکی آنتی‌فورجری توکن
 AntiForgeryConfig.RequireSsl = true;
محل تنظیم در متد Application_Start
2) کوکی‌های حالت Forms Authentication
<configuration>
  <system.web>
    <authentication mode="Forms">
      <forms requireSSL="true" cookieless="UseCookies"/>
    </authentication>
  </system.web>
</configuration>

3) تمام httpCookies
<configuration>
  <system.web>
    <httpCookies httpOnlyCookies="true" requireSSL="true" />
  </system.web>
</configuration>

4) کوکی‌های Role manager
<configuration>
  <system.web>
    <roleManager cookieRequireSSL="true" />
  </system.web>
</configuration>
محل تنظیم این سه مورد در فایل web.config است.

5) کوکی‌های OWIN Authentication و ASP.NET Identity 2.x
var options = new CookieAuthenticationOptions()
{
    CookieHttpOnly = true,
    CookieSecure = CookieSecureOption.Always,
    ExpireTimeSpan = TimeSpan.FromMinutes(10)
};


فعالسازی اجبار به استفاده‌ی از HTTPS

با استفاده از فیلتر RequireHttps، دسترسی به تمام اکشن متدهای برنامه تنها به صورت HTTPS میسر خواهد شد:
 filters.Add(new RequireHttpsAttribute(permanent: true));
محل تنظیم در متد RegisterGlobalFilters فایل Global.asax.cs، و یا در کلاس FilterConfig به صورت زیر:
using System.Web.Mvc;
namespace MyWebsite
{
    internal static class FilterConfig
    {
        internal static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new RequireHttpsAttribute(permanent: true));
        }
    }
}
پارامتر permanent آن در چند به روز رسانی آخر MVC 5 به آن اضافه شده‌است (از نگارش 5.2.4 به بعد) و مخصوص موتورهای جستجو است؛ در جهت تصحیح خودکار آدرس‌های قدیمی سایت به آدرس‌های جدید.

همچنین در متد Application_BeginRequest نیز می‌توان بررسی کرد که آیا درخواست ارسالی یک درخواست HTTPS است یا خیر؟ اگر خیر، می‌توان کاربر را به صورت خودکار به نگارش HTTPS آن هدایت دائم کرد:
        protected void Application_BeginRequest(Object sender, EventArgs e)
        {
            if (!HttpContext.Current.Request.IsSecureConnection)
            {
                var builder = new UriBuilder
                {
                    Scheme = "https",
                    Host = Request.Url.Host,
                    // use the RawUrl since it works with URL Rewriting
                    Path = Request.RawUrl
                };
                Response.Status = "301 Moved Permanently";
                Response.AddHeader("Location", builder.ToString());
            }
        }
جهت محکم کاری این قسمت می‌توان دو تنظیم تکمیلی ذیل را نیز به فایل web.config اضافه کرد:
فعالسازی HSTS جهت اطلاع به مرورگر که این سایت تنها از طریق HTTPS قابل دسترسی است و تمام درخواست‌های HTTP را به صورت خودکار از طریق HTTPS انجام بده:
<httpProtocol>
      <customHeaders>
        <add name="Strict-Transport-Security" value="max-age=16070400; includeSubDomains" />
و همچنین اگر ماژول URL Rewite بر روی سرور نصب است، کار هدایت خودکار به آدرس‌های HTTPS را نیز می‌توان توسط آن مدیریت کرد:
<rewrite>
    <rules>        
        <rule name="Redirect to HTTPS" stopProcessing="true">
          <match url="(.*)" />
          <conditions>
            <add input="{HTTPS}" pattern="off" ignoreCase="true" />
            <add input="{HTTP_HOST}" negate="true" pattern="localhost" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
        </rule>


اصلاح تمام آدرس‌های مطلقی که توسط برنامه تولید می‌شوند

اگر در برنامه‌ی خود از Url.Action برای تولید آدرس‌ها استفاده می‌کنید، با ذکر پارامتر protocol آن، آدرس تولیدی آن بجای یک مسیر نسبی، یک مسیر مطلق خواهد بود. اگر پیشتر این پروتکل را به صورت دستی به http تنظیم کرده‌اید، روش صحیح آن به صورت زیر است که با آدرس جدید HTTPS سایت هم سازگار است:
 var fullBaseUrl = Url.Action(result: MVC.Home.Index(), protocol: this.Request.Url.Scheme);


اصلاح تمام آدرس‌هایی که پیشتر توسط برنامه تولید شده‌اند

یک نمونه آن در مطلب «به روز رسانی تمام فیلدهای رشته‌ای تمام جداول بانک اطلاعاتی توسط Entity framework 6.x» بحث شده‌است.


اصلاح فایل robots.txt و درج آدرس HTTPS جدید

اگر در فایل robots.txt سایت، آدرس مطلق Sitemap را به صورت HTTP درج کرده بودید، آن‌را به HTTPS تغییر دهید:
User-agent: *
Sitemap: https://www.dntips.ir/Sitemap
مطالب
خودکار کردن تعاریف DbSetها در EF Code first
پیشنیاز:
تعریف نوع جنریک به صورت متغیر

مطلبی را چندی قبل در مورد نحوه خودکار کردن افزودن کلاس‌های EntityTypeConfiguration به modelBuilder در این سایت مطالعه کردید. در مطلب جاری به خودکار سازی تعاریف مرتبط با DbSetها خواهیم پرداخت.
ابتدا مثال کامل زیر را درنظر بگیرید:
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Reflection;

namespace MyNamespace
{
    public abstract class BaseEntity
    {
        public int Id { set; get; }
        public string CreatedBy { set; get; }
    }

    public class User : BaseEntity
    {
        public string Name { get; set; }
    }

    public class MyContext : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var asm = Assembly.GetExecutingAssembly();
            loadEntities(asm, modelBuilder, "MyNamespace");
        }

        void loadEntities(Assembly asm, DbModelBuilder modelBuilder, string nameSpace)
        {
            var entityTypes = asm.GetTypes()
                                    .Where(type => type.BaseType != null &&
                                           type.Namespace == nameSpace &&
                                           type.BaseType.IsAbstract &&
                                           type.BaseType == typeof(BaseEntity))
                                    .ToList();

            var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");
            entityTypes.ForEach(type =>
            {
                entityMethod.MakeGenericMethod(type).Invoke(modelBuilder, new object[] { });
            });
        }
    }

    public class Configuration : DbMigrationsConfiguration<MyContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }

        protected override void Seed(MyContext context)
        {
            context.Set<User>().Add(new User { Name = "name-1" });
            context.Set<User>().Add(new User { Name = "name-2" });
            context.Set<User>().Add(new User { Name = "name-3" });
            base.Seed(context);
        }
    }

    public static class Test
    {
        public static void RunTests()
        {
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());
            using (var context = new MyContext())
            {
                var user1 = context.Set<User>().Find(1);
                if (user1 != null)
                    Console.WriteLine(user1.Name);
            }
        }
    }
}
توضیحات:
همانطور که ملاحظه می‌کنید در این مثال خبری از تعاریف DbSetها نیست. به کمک Reflection تمام مدل‌های برنامه که از نوع کلاس پایه BaseEntity هستند (روشی مرسوم جهت مدیریت خواص تکراری مدل‌ها) یافت شده (در متد loadEntities) و سپس نتیجه حاصل به صورت پویا به متد جنریک Entity ارسال می‌شود. حاصل، افزوده شدن خودکار کلاس‌های مورد نظر به سیستم EF است.
البته در این حالت چون دیگر کلاس‌های مدل‌ها در MyContext به صورت صریح تعریف نمی‌شوند، نحوه استفاده از آن‌ها را توسط متد Set، در متدهای RunTests و یا Seed، ملاحظه می‌کنید. 
اشتراک‌ها
الگوی MVVM - تمرین

Let’s continue our journey to learn the MVVM pattern, applied to Universal Windows apps development. After we’ve learned the basic concepts in the previous post, now it’s time to start writing some code. As already mentioned in the previous post, we’re going to leverage MVVM Light as toolkit to help us implementing the pattern: since it’s the most flexible and simple to use, it will be easier to understand and apply the basic concepts we’ve learned so far.  

الگوی MVVM - تمرین
اشتراک‌ها
بررسی روش‌های مختلف انجام اعمال غیرهمزمان در جاوااسکریپت

# Which Approach Should You Use?

We had a look at four different approaches:-Callbacks with the danger of entering callback hell -Promises to escape callback hell-Observables to handle streams of data and apply operator magic -async/ await to write “synchronous” code with promises

 

بررسی روش‌های مختلف انجام اعمال غیرهمزمان در جاوااسکریپت
اشتراک‌ها
از پیاده سازی Repository Pattern با یک ORM پرهیز کنید!

For many years now I’ve advocated not using the repository pattern on top of an ORM such as Entity Framework. There are many reasons why that I’ll try and cover throughout this post based on ways that I’ve seen it implemented. Meaning, this post is talking about poorly implemented approaches or pitfalls that I’ve seen. 

از پیاده سازی Repository Pattern با یک ORM پرهیز کنید!
اشتراک‌ها
لیست فرمان های Nuget برای EF Migrations

Entity Framework Migrations are handled from the package manager console in Visual Studio. The usage is shown in various tutorials, but I haven’t found a complete list of the commands available and their usage, so I created my own. There are four available main commands 

لیست فرمان های Nuget برای EF Migrations
نظرات مطالب
EF Code First #4
ممنونم از راهنماییتون.
با این کار فایل Configuration ایجاد میشه ولی اون فایل دوم ایجاد نمیشه . وقتی بقیه دستورات رو هم اجرا میکنم(Update-datebase و ...) هم خطای 
An error occurred while getting provider information from the database. This can be caused by Entity Framework using an incorrect connection string. Check the inner exceptions for details and ensure that the connection string is correct. 
 رو میده .
تو فایل app.config ،هم Connection string رو اضافه کردم ولی باز هم همین خطا رو میده!
اشتراک‌ها
مقایسه EF Core 2.1 vs NHibernate 5.1

EF Core vs NHibernate – 3.5 : 6.8.

The EF Core team is putting a lot of effort, and EF Core is slowly approaching parity with NHibernate. But it’s still lights years behind, and I don’t even mention all other, non-DDD related features. 

مقایسه EF Core 2.1 vs NHibernate 5.1