نظرات مطالب
MVC vs 3-Tier Pattern
درک من از معماری سه لایه یا N-Teir اینگونه است که
اصولا باید تقسیم بندی لایه‌ها به این صورت باشه که:
1-لایه زیرساخت که متشکل از DataLayer,ServiceLayer,domainclasses هست
2-لایه وب سرویس که می‌تواند یک سرویس دهنده باشد مثل WebApi,Wcf
3-لایه ui که هر نوع appی می‌تواند باشد .مانند Asp.Net Webforms,Asp.Net Mvc,Andriod ,Ios,Winphone و یا حتی php
در واقع لایه وب سرویس هست که لایه ui رو تغذیه میکند.
لایه ui با ارسال درخواست به لایه وب سرویس داده  مورد نظر خود را دریافت میکند و مهم نیست که این لایه از چه نوع تکنولوژی استفاده میکند.
اینگونه است که میتوان وابستگی لایه‌ها را تفکیک کرد و به یک معماری مستقل رسید.
اشتراک‌ها
پیوند دادن حساب گوگل پلاس با سایت یا وبلاگ برای افزایش رتبه‌ی SEO

افزایش رتبه‌ی SEO در موتورهای جستجو یکی از اهداف مهم صاحبان سایت‌ها و وبلاگ‌ها است. از طرف دیگر گوگل به عنوان محبوب‌ترین موتور جستجوی اینترنتی، از الگوریتم‌های گوناگونی برای رتبه‌بندی سایت‌ها استفاده می‌کند. هرچند این شرکت تلاش می‌کند تا الگوریتم‌های رتبه‌بندی خود را مخفی نگه دارد، با این حال برخی از معیارهای رتبه‌بندی به شیوه‌های گوناگون شناسایی شده‌اند.

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

پیوند دادن حساب گوگل پلاس با سایت یا وبلاگ برای افزایش رتبه‌ی SEO
اشتراک‌ها
بن کردن ip ها با استفاده از Middleware در asp.net core
هدف اینجا یک اتفاق سادست و اونم اینه که ما بتونیم برخی کاربر هارو بن (یا مسدود ) کنیم که توانایی دسترسی به وب سایت ما رو پس از این نداشته باشند و قراره بجای اینکه از دیتابیس استفاده کنیم(که خب ممکنه سربار بالایی هم برامون داشته باشه بدلیل اینکه هر بار که یک ریکوست از kestrel ، به middleware مربوطه ما میرسه ، باید یک بار به دیتابیس وصل بشه و چک کنه که ایا اون ip وجود داره یا ن)،از یک فایل json استفاده کنیم....
بن کردن ip ها با استفاده از Middleware در asp.net core
نظرات مطالب
مروری بر تاریخچه محدودیت حافظه مصرفی برنامه‌های ASP.NET در IIS
سلام؛ ما یه سایت داریم که در روز حدود 1000 تا کاربر داره. در قسمت admin، آپلود فایل هم زیاد داریم.
RAM وب سرور هم 8GB هست.
WinServer 2008 32bit - CPU: Xeon 5160 3GHz
IIS 7
تقریبا روزی یکی دوبار شاید هم هر دو سه روز یه بار نیاز به recycle داشته باشیم.
پیشنهاد می‌کنید Virtual Memory Usage و Private Memory Usage چند باشه تا کمترین نیاز رو برای recycle داشته باشیم؟
نظرات مطالب
اجرای وظایف زمان بندی شده با Quartz.NET - قسمت اول
سلام
یک کلاس با اسم Abzar وجود دارد میخواهم متدی که با اسم ADD() در این کلاس وجود دارد در هر پنج دقیقه یک بار اجرا شود.
توجه داشته باشید که در Page-Load نباید باشد.
و این برنامه برای یک وب سایت است   
کاربر هیچ کاری با این کلاس و متد ندارد و هیچ وقت در صفحه ای باز نمیشود. ولی این متد در طول شبانه روز در هر 5 دقیقه یک بار اجرا میشود
آیا با Quartz.NET میتوان این کار را انجام داد ؟
بازخوردهای پروژه‌ها
چگونگی ایجاد گزارش بدون اینکه تداخل داده به وجود آید
با سلام.

من در یک وب سایت می‌خواهم از کتابخانه PdfRpt استفاده کنم ولی در تمام مثال‌ها که  فرمودید اطلاعات در یک فایل ذخیره می‌شوند که با توجه به این کار اگر چند کاربر به صورت همزمان از یک گزارش استفاده کنند (مثلاً هر مشتری فقط رکوردهای مربوط به خودش رو می‌بینه) در این صورت تداخل داده به وجود می‌آید. می‌خواستم بپرسم که برای این کار راحل چیست؟ آیا باید فایل را در حافظه ایجاد کنیم ؟ ممنون میشم راهنمایی کنید چون من وقتی که خواستم در حافظه ایجاد بکنم به مشکل برخوردم که این مشکل باعث شد که من ایجا این مسله رو مطرح کنم. ممنونم
نظرات مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 19 - بومی سازی
در این حالت آدرس دهی در مثال وقتی می‌خواهیم از سیستم اهراز هویت در متد Configure  استفاده کنیم
app.UseAuthentication();
بعد از اینکه کاربر لاگین کرد و اهراز هویت انجام شد گویا مشکلی ^ برای پر کردن Claim‌ها و null بود User.Identity.Name پیش میاد
البته راه حلی که که در ^ گفته شده در متد   ConfigureOptions قابل فعال سازی نبود به این دلیل که در آرایه RequestCultureProviders یک شی از کلاس RouteDataRequestCultureProvider برای آدرس دهی‌ها اضافه شده و با شی از کلاس CustomRequestCultureProvider که در راه حل گفته شده همخوانی نداره

 public static void ConfigureOptions(RequestLocalizationOptions options)
        {
            var supportedCultures = new List<CultureInfo>
                                {  new CultureInfo("fa"),
                                    new CultureInfo("en"),
                                    new CultureInfo("ar")
                                };

            options.DefaultRequestCulture = new RequestCulture(culture: "fa", uiCulture: "fa");
            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;
            options.RequestCultureProviders = new[] {
                new RouteDataRequestCultureProvider()
                {
                    Options = options,
                    RouteDataStringKey = "lang",
                    UIRouteDataStringKey = "lang"
                }
            }; 
        }
راه حلی برای رفع این مشکل وجود داره؟
مطالب
پیاده سازی برنامه‌های چند مستاجری در ASP.NET Core

سناریویی را در نظر بگیرید که یک برنامه وب نوشته شده، قرار است به چندین مستاجر (مشتری یا tenant) خدماتی را ارائه کند. در این حالت اطلاعات هر مشتری به صورت کاملا جدا شده از دیگر مشتریان در سیستم قرار دارد و فقط به همان قسمت‌ها دسترسی دارد.

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

 در معماری Multi-Tenancy، چندین کاربر می‌توانند از یک نمونه (Single Instance) از اپلیکیشن نرم‌افزاری استفاده کنند. یعنی این نمونه روی سرور اجرا می‌شود و به چندین کاربر سرویس می‌دهد. هر کاربر را یک Tenant می‌نامیم. می‌توان به Tenantها امکان تغییر و شخصی‌سازی بخشی از اپلیکیشن را داد؛ مثلا امکان تغییر رنگ رابط کاربری و یا قوانین کسب‌وکار، اما آنها نمی‌توانند کدهای اپلیکیشن را شخصی‌سازی کنند.

بدون داشتن دانش کافی، پیاده سازی معماری multi tenant می‌تواند تبدیل یه یک چالش بزرگ شود. مخصوصا در نسخه‌ی قبلی ASP.NET که یکپارچه نبودن فریم ورک‌های مختلف می‌توانست باعث ایجاد چندین پیاده سازی مختلف در برنامه شود. موضوع وقتی پیچیده‌تر می‌شد که شما قصد داشتید در یک برنامه چندین فریم ورک مختلف مثل SignalR, MVC, Web API را مورد استفاده قرار دهید.

خوشبختانه اوضاع با وجود OWIN بهتر شده و ما در این مطلب قصد استفاده از یک تولکیت را به نام SaasKit، برای پیاده سازی این معماری در ASP.NET Core داریم. هدف از این toolkit، ساده‌تر کردن هر چه بیشتر ساخت برنامه‌های SaaS (Software as a Service) هست. با استفاده از OWIN ما قادریم که بدون در نظر گرفتن فریم ورک مورد استفاده، رفتار مورد نظر خودمان را مستقیما در یک چرخه درخواست HTTP پیاده سازی کنیم و البته به لطف طراحی خاص ASP.NET Core 1.0 و استفاده از میان افزار‌هایی مشابه OWIN در برنامه، کار ما با SaasKit باز هم راحت‌تر خواهد بود.

شروع کار 

یک پروژه ASP.NET Core جدید را ایجاد کنید و سپس ارجاعی را به فضای نام SaasKit.Multitenancy  (موجود در Nuget) بدهید. 
PM> Install-Package SaasKit.Multitenancy
بعد از اینکار ما باید به SaasKit اطلاع دهیم که چطور مستاجر‌های ما را شناسایی کند.

شناسایی مستاجر (tenant) 

اولین جنبه در معماری multi-tenant، شناسایی مستاجر بر اساس اطلاعات درخواست جاری می‌باشد که می‌تواند از hostname ، کاربر جاری یا یک HTTP header باشد.
ابتدا به تعریف کلاس مستاجر می‌پردازیم: 
    public class AppTenant
    {
        public string Name { get; set; }
        public string[] Hostnames { get; set; }
    }
سپس از طریق پیاده سازی اینترفیس ITenantResolver  و نوشتن یک tenant resolver به SaasKit اطلاع می‌دهیم که چطور مستاجر جاری را بر اساس اطلاعات درخواست جاری شناسایی کند و در صورتیکه موفق به شناسایی شود، یک وهله از نوع <TenantContext<TTenant را بازگشت خواهد داد. 
    public class AppTenantResolver : ITenantResolver<AppTenant>
    {
        IEnumerable<AppTenant> tenants = new List<AppTenant>(new[]
        {
            new AppTenant {
                Name = "Tenant 1",
                Hostnames = new[] { "localhost:6000", "localhost:6001" }
            },
            new AppTenant {
                Name = "Tenant 2",
                Hostnames = new[] { "localhost:6002" }
            }
        });
        public async Task<TenantContext<AppTenant>> ResolveAsync(HttpContext context)
        {
            TenantContext<AppTenant> tenantContext = null;
            var tenant = tenants.FirstOrDefault(t =>
                t.Hostnames.Any(h => h.Equals(context.Request.Host.Value.ToLower())));
            if (tenant != null)
            {
                tenantContext = new TenantContext<AppTenant>(tenant);
            }
            return tenantContext;
        }
    }
در نظر داشته باشید که اینجا ما اطلاعات مستاجر را از روی hostname استخراج کردیم؛ اما از آنجا که شما به شیء HttpContext دسترسی کاملی دارید، می‌توانید از هر چیزی که مایل باشید استفاده کنید؛ مثل URL، اطلاعات کاربر، هدر‌های HTTP و غیره. در اینجا فعلا مشخصات مستاجر‌های خودمان را در کد نوشتیم. اما شما می‌توانید در برنامه خودتان این اطلاعات را از فایل تنظیمات برنامه و یا یک بانک اطلاعاتی دریافت کنید.
 

سیم کشی کردن 

بعد از پیاده سازی این اینترفیس نوبت به سیم کشی‌های SaasKit میرسد. من در اینجا سعی کردم که مثل الگوی برنامه‌های ASP.NET Core عمل کنم. ابتدا نیاز داریم که وابستگی‌های SaasKit را ثبت کنیم. فایل startups.cs  را باز کنید و کدهای زیر را در متد ConfigureServices اضافه نمایید: 
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMultitenancy<AppTenant, AppTenantResolver>();
    }
سپس باید میان افزار SaasKit را ثبت کنیم. کدهای زیر را به متد Configure اضافه کنید:
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // after .UseStaticFiles()
        app.UseMultitenancy<AppTenant>();
        // before .UseMvc()
    }


دریافت مستاجر جاری 

حالا هر جا که نیاز به وهله‌ای از شیء مستاجر جاری داشتید، می‌توانید به روش زیر عمل کنید: 
    public class HomeController : Controller
    {
        private AppTenant tenant;
        public HomeController(AppTenant tenant)
        {
            this.tenant = tenant;
        }
    }
به عنوان مثال قصد داریم نام مستاجر را در عنوان سایت نمایش دهیم. برای اینکار ما از قابلیت جدید MVC Core یعنی تزریق سرویس‌ها به View استفاده خواهیم کرد.  در فایل Layout.cshtml_ تکه کد زیر را به بالای صفحه اضافه کنید:
    @inject AppTenant Tenant;
این کد، AppTenant را برای ما در تمامی View‌ها از طریق شی Tenant قابل دسترس می‌کند. حالا می‌توانیم در View خود از جزییات مستاجر به شکل زیر استفاده کنیم: 
    <a asp-controller="Home" asp-action="Index">@Tenant.Name</a>


اجرای نمونه مثال 

فایل project.json را باز کنید و مقدار web را به شکل زیر مقدار دهی کنید: (در اینجا برای سایت خود 3 آدرس را نگاشت کردیم) 
    "commands": {
      "web": "Microsoft.AspNet.Server.Kestrel --server.urls=http://localhost:6000;http://localhost:6001;http://localhost:6002",
    },
سپس کنسول را در محل ریشه پروژه باز نموده و دستور زیر را اجرا کنید: 
    dotnet run
حال اگر در مرورگر خود آدرس http://localhost:6000 را وارد کنیم، مستاجر 1 را خواهیم دید:


و اگر آدرس http://localhost:6002 را وارد کنیم، مستاجر 2 را مشاهده می‌کنیم:


قابل پیکربندی کردن مستاجر ها 

از آنجائیکه نوشتن مشخصات مستاجر‌ها در کد زیاد جالب نیست، برای همین تصمیم داریم که این مشخصات را با استفاده از قابلیت‌های ASP.NET Core از فایل appsettings.json دریافت کنیم. تنظیمات مستاجر‌ها را مطابق اطلاعات زیر به این فایل اضافه کنید:

    "Multitenancy": {
      "Tenants": [
        {
          "Name": "Tenant 1",
          "Hostnames": [
            "localhost:6000",
            "localhost:6001"
          ]
        },
        {
          "Name": "Tenant 2",
          "Hostnames": [
            "localhost:6002"
          ]
        }
      ]
    }
سپس کلاسی را که بیانگر تنظیمات چند مستاجری باشد، می‌نویسیم: 
    public class MultitenancyOptions
    {
        public Collection<AppTenant> Tenants { get; set; }
    }
حالا نیاز داریم که به برنامه اعلام کنیم تا تنظیمات مورد نیاز خود را از فایل appsettings.json بخواند. کد زیر را به ConfigureServices اضافه کنید: 
    services.Configure<MultitenancyOptions>(Configuration.GetSection("Multitenancy"));
سپس کدهای resolver خود را جهت دریافت اطلاعات از MultitenancyOptions مطابق زیر تغییر می‌دهیم: 
    public class AppTenantResolver : ITenantResolver<AppTenant>
    {
        private readonly IEnumerable<AppTenant> tenants;
        public AppTenantResolver(IOptions<MultitenancyOptions> options)
        {
            this.tenants = options.Value.Tenants;
        }
        public async Task<TenantContext<AppTenant>> ResolveAsync(HttpContext context)
        {
            TenantContext<AppTenant> tenantContext = null;
            var tenant = tenants.FirstOrDefault(t => 
                t.Hostnames.Any(h => h.Equals(context.Request.Host.Value.ToLower())));
            if (tenant != null)
            {
                tenantContext = new TenantContext<AppTenant>(tenant);
            }
            return Task.FromResult(tenantContext);
        }
    }
برنامه را یکبار re-build کرده و اجرا کنید . 


در آخر 

اولین قدم در پیاده سازی یک معماری multi-tenant، تصمیم گیری درباره این موضوع است که شما چطور مستاجر خود را شناسایی کنید. به محض این شناسایی شما می‌توانید عملیات‌های بعدی خود را مثل تفکیک بخشی از برنامه، فیلتر کردن داده‌ای، نمایش یک view خاص برای هر مستاجر و یا بازنویسی قسمت‌های مختلف برنامه بر اساس هر مستاجر، انجام دهید.

_ سورس مثال بالا در گیت هاب قابل دریافت می‌باشد.

_ منبع: اینجا