مطالب
آشنایی با مفاهیم شیء گرایی در جاوا اسکریپت #2
از آنجا که برای کار با جاوا اسکریپت نیاز به درک کاملی درباره‌ی مفهوم حوزه کارکرد متغیرها (Scope) می‌باشد و نحوه فراخوانی توابع نیز نقش اساسی در این مورد بازی می‌کند، در این قسمت با این موارد آشنا خواهیم شد:
جاوا اسکریپت از مفهومی به نام functional scope برای تعیین حوزه متغیرها استفاده می‌کند و به این معنی است که با تعریف توابع، حوزه عملکرد متغیر مشخص می‌شود. در واقع هر متغیری که در یک تابع تعریف می‌شود در کلیه قسمتهای آن تابع، از قبیل If statement – for loops و حتی nested function نیز در دسترس میباشد.
اجازه دهید با مثالی این موضوع را بررسی نماییم.
function testScope() {
var myTest = true;
if (true) {
var myTest = "I am changed!"
}
alert(myTest);
}
testScope(); // will alert "I am changed!"
همانگونه که میبینیم با اینکه در داخل بلاک if یک متغیر جدید تعریف شده، ولی در خارج از این بلاک نیز این متغیر قابل دسترسی میباشد. البته در مثال بالا اگر بخواهیم به متغیر myTest در خارج از function دسترسی داشته باشیم، با خطای undefined مواجه خواهیم شد. یعنی برای مثال در کد زیر:
function testScope() {
var myTest = true;
if (true) {
var myTest = "I am changed!"
}
alert(myTest);
}
testScope(); // will alert "I am changed!"
alert(myTest); // will throw a reference error, because it doesn't exist outside of the function
 برای حل این مشکل دو راه وجود دارد: 
1 – متغیر myTest را در بیرون بلاک testScope() تعریف کنیم
2 – هنگام تعریف متغیر myTest، کلمه کلیدی var را حذف کنیم که این موضوع باعث میشود این متغیر در کل window قابل دسترس باشد و یا به عبارتی متغیر global میشود.
قبل از پرداختن به ادامه بحث خواندن مقاله مربوط به Closure در جاوااسکریپت توصیه میگردد .
در پایان بحث Scope‌ها با یک مثال نسبتا جامع اکثر این حالات به همراه خروجی را نشان میدهیم :
<script type="text/javascript">
          // a globally-scoped variable
        var a = 1;
        // global scope
        function one()
        {
            alert(a);
        }
        // local scope
        function two(a)
        {
            alert(a);
        }
        // local scope again
        function three()
        {
            var a = 3;
            alert(a);
        }
        // Intermediate: no such thing as block scope in javascript
        function four()
        {
            if (true)
            {
                var a = 4;
            }
            alert(a); // alerts '4', not the global value of '1'
        }
        // Intermediate: object properties
        function Five()
        {
            this.a = 5;
        }
        // Advanced: closure
        var six = function ()
        {
            var foo = 6;
            return function ()
            {
                // javascript "closure" means I have access to foo in here, 
                // because it is defined in the function in which I was defined.
                alert(foo);
            }
        }()
        // Advanced: prototype-based scope resolution
        function Seven()
        {
            this.a = 7;
        }
        // [object].prototype.property loses to [object].property in the lookup chain
        Seven.prototype.a = -1; // won't get reached, because 'a' is set in the constructor above.
        Seven.prototype.b = 8; // Will get reached, even though 'b' is NOT set in the constructor.
        // These will print 1-8
        one();
        two(2);
        three();
        four();
        alert(new Five().a);
        six();
        alert(new Seven().a);
        alert(new Seven().b);
</Script>
برای مطالعه بیشتر به اینجا  مراجعه نمایید.

Function Invocation Patterns In JavaScript :
از آنجا که توابع در جاوااسکریپت به منظور 1 – ساخت اشیاء  و 2 – حوزه دسترسی متغیرها(Scope)  نقش اساسی ایفا می‌کنند بهتر است کمی درباره استفاده و نحوه فراخوانی آنها  (Function Invocation Patterns) در جاوااسکریپت بحث نماییم.
در جاوااسکریپت 4 مدل فراخوانی تابع داریم که به نامهای زیر مطرح هستند:
1. Method Invocation
2. Function Invocation
3. Constructor Invocation
4. Apply And Call Invocation
 در فراخوانی توابع به هر یک از روشهای بالا باید به این نکته توجه داشت که حوزه دسترسی متغیرها در جاوااسکریپت ابتدا و انتهای توابع هستند و اگر به عنوان مثال از توابع تو در تو استفاده کردیم ،حوزه شی this برای توابع داخلی تغییر خواهد کرد .این موضوع را در طی مثالهایی نشان خواهیم داد.
Method Invocation :
وقتی یک تابع قسمتی از یک شی باشد به آن متد میگوییم به عنوان مثال :
var obj = {
    value: 0,
    increment: function() {
        this.value+=1;
    }
};
obj.increment(); //Method invocation
در اینحالت this به شی (Object) اشاره میکند که متد در آن فراخوانی شده است و در زمان اجرا نیز به عناصر شی Bind میشود ،در مثال بالا حوزه  this شی obj خواهد شد و به همین منظور به متغیر value دسترسی داریم.
Function Invocation:
در اینحالت که از () برای فراخوانی تابع استفاده میگردد ،This به شی سراسری (global object ) اشاره می‌کند؛ منظور اینکه this به اجزای تابعی که فراخوانی آن انجام شده اشاره نمی‌کند. اجازه دهید با مثالی این موضوع را روشن کنیم
<script type="text/javascript">
var value = 500; //Global variable
var obj = {
    value: 0,
    increment: function() {
        this.value++;
        var innerFunction = function() {
            alert(this.value);
        }
        innerFunction(); //Function invocation pattern
    }
}
obj.increment(); //Method invocation pattern
<script type="text/javascript">
Result : 500
از آنجا که  () innerFunction به شکل  Function invocation pattern فراخوانی شده است به متغیر value در داخل تابع increment دسترسی نداریم و حوزه دسترسی global میشود و اگر در حوزه global نیز این متغیر تعریف نشده بود به خطای undefined میرسیدیم .
برای حل این گونه مشکلات ساختار کد نویسی ما بایستی به شکل زیر باشد :
<script type="text/javascript">
var value = 500; //Global variable
var obj = {
    value: 0,
    increment: function() {
        var that = this;
        that.value++;
        var innerFunction = function() {
            alert(that.value);
        }
        innerFunction(); //Function invocation pattern
    }
}
obj.increment();
<script type="text/javascript">
Result : 1
در واقع با تعریف یک متغیر با نام مثلا that و انتساب شی  this به آن میتوان در توابع بعدی که به شکل   Function invocation pattern فراخوانی میگردند به این متغیر دسترسی داشت .
Constructor Invocation :
در این روش برای فراخوانی تابع از کلمه new استفاده میکنیم. در این حالت یک شیء مجزا ایجاد شده و به متغیر دلخواه ما اختصاص پیدا می‌کند. به عنوان مثال داریم :
 var Dog = function(name) {   
  //this == brand new object ({});    
    this.name = name;    
    this.age = (Math.random() * 5) + 1;
};
var myDog = new Dog('Spike');
//myDog.name == 'Spike'
//myDog.age == 2
var yourDog = new Dog('Spot');
//yourDog.name == 'Spot'
//yourDog.age == 4
در این مورد با استفاده از New باعث میشویم همه خواص و متدهای تابع function برای هر نمونه از آن که ساخته میشود ( از طریق مفهوم Prototype که قبلا درباره آن بحث شد) بطور مجزا اختصاص یابد. در مثال بالا شی mydog چون حاوی یک نمونه از تابع dog بصورت  Constructor Invocation میباشد، در نتیجه به خواص تابع dog از قبیل name  و age دسترسی داریم. در اینجا اگر کلمه new استفاده نشود به این خواص دسترسی نداریم؛ در واقع با اینکار، this به mydog اختصاص پیدا میکند.
اگر از new استفاده نشود متغیر myDog ،undefined میشود.
یک مثال دیگر :
var createCallBack = function(init) { //First function
    return new function() { //Second function by Constructor Invocation
        var that = this;
        this.message = init;
        return function() { //Third function
            alert(that.message);
        }
    }
}
window.addEventListener('load', createCallBack("First Message"));
window.addEventListener('load', createCallBack("Second Message"));
در مثال بالا از مفهوم closure  نیز در مثالمان استفاده کرده ایم .
Apply And Call Invocation:
تمامی توابع جاوااسکریپت دارای دو متد توکار apply() و call() هستند که توسط این متدها میتوان این توابع را با context دلخواه فراخوانی کرد.
نحوه فراخوانی به شکل مقابل است :
myFunction.apply(thisContext, arrArgs);
myFunction.call(thisContext, arg1, arg2, arg3, ..., argN);
که thisContext به حوزه اجرایی (execution context) تابع اشاره میکند. تفاوت دو متد apply() و call() در نحوه فرستادن آرگومانها به تابع میباشد که در اولی توسط آرایه اینکار انجام میشود و در دومی همه آرگومانها را بطور صریح نوشته و با کاما از هم جدا میکنیم .
مثال :
var contextObject = {
testContext: 10
}
var otherContextObject = {
testContext: "Hello World!"
}
var testContext = 15; // Global variable
function testFunction() {
alert(this.testContext);
}
testFunction(); // This will alert 15
testFunction.call(contextObject); // Will alert 10
testFunction.apply(otherContextObject); // Will alert "Hello World”
در این مثال دو شی متفاوت با خواص همنام تعریف کرده و یک متغیر global نیز تعریف میکنیم. در انتها یک تابع تعریف میکنیم که مقدار this.testContext را نمایش میدهد. در ابتدا حوزه اجرایی تابع (this) کل window جاری میباشد و وقتی testFunction() اجرا شود مقدار متغیر global نمایش داده میشود. در اجرای دوم this به contextObject اشاره کرده و حوزه اجرایی عوض میشود و در نتیجه مقدار testContext مربوطه که در این حالت 10 میباشد نمایش داده میشود و برای فراخوانی سوم نیز به همین شکل .
یک مثال کاملتر :
var o = {
  i : 0,
  F : function() {
    var a = function() { this.i = 42; };
    a();
    document.write(this.i);
  }
};
o.F();
Result :0
خط o.f() تابع f را به شکل Method invocation اجرا میکند. در داخل تابع f یک تابع دیگر به شکل function invocation اجرا میشود که در اینحال this به global object اشاره میکند و باعث میشود مقدار i در خروجی 0 چاپ شود .
برای حل این مشکل 2 راه وجود دارد  
راه اول :
var p = {
  i : 0,
  F : function() {
    var a = function() { this.i = 42; };
    a.apply(this);
    document.write(this.i);
  }
};
 p.F();
Result :42
با اینکار this را موقع اجرای تابع درونی برایش فرستاده تا حوزه اجرای تابع عوض شود و به i دسترسی پیدا کنیم .
یا اینکه همانند مثالهای قبلی :
var q = {
  i: 0,
  F: function F() {
    var that = this;
    var a = function () {
      that.i = 42;
    }
    a();
    document.write(this.i);
  }
}
 q.F();

منابع :
Javascript programmer,s refrence
 
مطالب
طراحی افزونه پذیر با ASP.NET MVC 4.x/5.x - قسمت دوم
در مطلب «طراحی افزونه پذیر با ASP.NET MVC 4.x/5.x - قسمت اول» با ساختار کلی یک پروژه‌ی افزونه‌ی پذیر ASP.NET MVC آشنا شدیم. پس از راه اندازی آن و مدتی کار کردن با این نوع پروژه‌ها، این سؤال پیش خواهد آمد که ... خوب، اگر هر افزونه تصاویر یا فایل‌های CSS و JS اختصاصی خودش را بخواهد داشته باشد، چطور؟ موارد عمومی مانند بوت استرپ و جی‌کوئری را می‌توان در پروژه‌ی پایه قرار داد تا تمام افزونه‌ها به صورت یکسانی از آن‌ها استفاده کنند، اما هدف، ماژولار شدن برنامه است و جدا کردن فایل‌های ویژه‌ی هر پروژه، از پروژ‌ه‌ای دیگر و همچنین بالا بردن سهولت کار تیمی، با شکستن اجزای یک پروژه به صورت افزونه‌هایی مختلف، بین اعضای یک تیم. در این قسمت نحوه‌ی مدفون سازی انواع فایل‌های استاتیک افزونه‌ها را درون فایل‌های DLL آن‌ها بررسی خواهیم کرد. به این ترتیب دیگر نیازی به ارائه‌ی مجزای آن‌ها و یا کپی کردن آن‌ها در پوشه‌های پروژه‌ی اصلی نخواهد بود.


مدفون سازی فایل‌های CSS و JS هر افزونه درون فایل DLL آن

به solution جاری، یک class library جدید را به نام MvcPluginMasterApp.Common اضافه کنید. از آن جهت قرار دادن کلاس‌های عمومی و مشترک بین افزونه‌ها استفاده خواهیم کرد. برای مثال قصد نداریم کلاس‌های سفارشی و عمومی ذیل را هربار به صورت مستقیم در افزونه‌ای جدید کپی کنیم. کتابخانه‌ی Common، امکان استفاده‌ی مجدد از یک سری کدهای تکراری را در بین افزونه‌ها میسر می‌کند.
این پروژه برای کامپایل شدن نیاز به بسته‌ی نیوگت ذیل دارد:
 PM> install-package Microsoft.AspNet.Web.Optimization
همچنین باید به صورت دستی، در قسمت ارجاعات پروژه، ارجاعی را به اسمبلی استاندارد System.Web نیز به آن اضافه نمائید.
پس از این مقدمات، کلاس ذیل را به این پروژه‌ی class library جدید اضافه کنید:
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Web.Optimization;
 
namespace MvcPluginMasterApp.Common.WebToolkit
{
    public class EmbeddedResourceTransform : IBundleTransform
    {
        private readonly IList<string> _resourceFiles;
        private readonly string _contentType;
        private readonly Assembly _assembly;
 
        public EmbeddedResourceTransform(IList<string> resourceFiles, string contentType, Assembly assembly)
        {
            _resourceFiles = resourceFiles;
            _contentType = contentType;
            _assembly = assembly;
        }
 
        public void Process(BundleContext context, BundleResponse response)
        {
            var result = new StringBuilder();
 
            foreach (var resource in _resourceFiles)
            {
                using (var stream = _assembly.GetManifestResourceStream(resource))
                {
                    if (stream == null)
                    {
                        throw new KeyNotFoundException(string.Format("Embedded resource key: '{0}' not found in the '{1}' assembly.", resource, _assembly.FullName));
                    }
 
                    using (var reader = new StreamReader(stream))
                    {
                        result.Append(reader.ReadToEnd());
                    }
                }
            }
 
            response.ContentType = _contentType;
            response.Content = result.ToString();
        }
    }
}
اگر با سیستم bundling & minification کار کرده باشید، با تعاریفی مانند ("new Bundle("~/Plugin1/Scripts آشنا هستید. سازنده‌ی کلاس Bundle، پارامتر دومی را نیز می‌پذیرد که از نوع IBundleTransform است. با پیاده سازی اینترفیس IBundleTransform می‌توان محل ارائه‌ی فایل‌های استاتیک CSS و JS را بجای فایل سیستم متداول و پیش فرض، به منابع مدفون شده‌ی در اسمبلی جاری هدایت و تنظیم کرد.
کلاس فوق در اسمبلی معرفی شده به آن، توسط متد GetManifestResourceStream به دنبال فایل‌ها و منابع مدفون شده گشته و سپس محتوای آن‌ها را بازگشت می‌دهد.
اکنون برای استفاده‌ی از آن، به پروژه‌ی MvcPluginMasterApp.Plugin1 مراجعه کرده و ارجاعی را به پروژه‌ی MvcPluginMasterApp.Common فوق اضافه نمائید. سپس در فایل Plugin1.cs، متد RegisterBundles آن‌را به نحو ذیل تکمیل کنید:
namespace MvcPluginMasterApp.Plugin1
{
    public class Plugin1 : IPlugin
    {
        public EfBootstrapper GetEfBootstrapper()
        {
            return null;
        }
 
        public MenuItem GetMenuItem(RequestContext requestContext)
        {
            return new MenuItem
            {
                Name = "Plugin 1",
                Url = new UrlHelper(requestContext).Action("Index", "Home", new { area = "NewsArea" })
            };
        }
 
        public void RegisterBundles(BundleCollection bundles)
        {
            var executingAssembly = Assembly.GetExecutingAssembly();
            // Mostly the default namespace and assembly name are the same
            var assemblyNameSpace = executingAssembly.GetName().Name;
            var scriptsBundle = new Bundle("~/Plugin1/Scripts",
                new EmbeddedResourceTransform(new List<string>
                {
                    assemblyNameSpace + ".Scripts.test1.js"
                }, "application/javascript", executingAssembly));
            if (!HttpContext.Current.IsDebuggingEnabled)
            {
                scriptsBundle.Transforms.Add(new JsMinify());
            }
            bundles.Add(scriptsBundle);
            var cssBundle = new Bundle("~/Plugin1/Content",
                new EmbeddedResourceTransform(new List<string>
                {
                    assemblyNameSpace + ".Content.test1.css"
                }, "text/css", executingAssembly));
            if (!HttpContext.Current.IsDebuggingEnabled)
            {
                cssBundle.Transforms.Add(new CssMinify());
            }
            bundles.Add(cssBundle);
            BundleTable.EnableOptimizations = true;
        }
 
        public void RegisterRoutes(RouteCollection routes)
        {
        }
 
        public void RegisterServices(IContainer container)
        {
        }
    }
}
در اینجا نحوه‌ی کار با کلاس سفارشی EmbeddedResourceTransform را مشاهده می‌کنید. ابتدا فایل‌های js و سپس فایل‌های css برنامه به سیستم Bundling برنامه اضافه شده‌اند.
این فایل‌ها به صورت ذیل در پروژه تعریف گردیده‌اند:


همانطور که مشاهده می‌کنید، باید به خواص هر کدام مراجعه کرد و سپس Build action آن‌ها را به embedded resource تغییر داد، تا در حین کامپایل، به صورت خودکار در قسمت منابع اسمبلی ذخیره شوند.

یک نکته‌ی مهم
اینبار برای مسیردهی منابع، باید بجای / فایل سیستم، از «نقطه» استفاده کرد. زیرا منابع با نام‌هایی مانند namespace.folder.name در قسمت resources یک اسمبلی ذخیره می‌شوند:



مدفون سازی تصاویر ثابت هر افزونه درون فایل DLL آن

مجددا به اسمبلی مشترک MvcPluginMasterApp.Common مراجعه کرده و اینبار کلاس جدید ذیل را به آن اضافه کنید:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Web;
using System.Web.Routing;
 
namespace MvcPluginMasterApp.Common.WebToolkit
{
    public class EmbeddedResourceRouteHandler : IRouteHandler
    {
        private readonly Assembly _assembly;
        private readonly string _resourcePath;
        private readonly TimeSpan _cacheDuration;
 
        public EmbeddedResourceRouteHandler(Assembly assembly, string resourcePath, TimeSpan cacheDuration)
        {
            _assembly = assembly;
            _resourcePath = resourcePath;
            _cacheDuration = cacheDuration;
        }
 
        IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
        {
            return new EmbeddedResourceHttpHandler(requestContext.RouteData, _assembly, _resourcePath, _cacheDuration);
        }
    }
 
    public class EmbeddedResourceHttpHandler : IHttpHandler
    {
        private readonly RouteData _routeData;
        private readonly Assembly _assembly;
        private readonly string _resourcePath;
        private readonly TimeSpan _cacheDuration;
 
        public EmbeddedResourceHttpHandler(
            RouteData routeData, Assembly assembly, string resourcePath, TimeSpan cacheDuration)
        {
            _routeData = routeData;
            _assembly = assembly;
            _resourcePath = resourcePath;
            _cacheDuration = cacheDuration;
        }
 
        public bool IsReusable
        {
            get { return false; }
        }
 
        public void ProcessRequest(HttpContext context)
        {
            var routeDataValues = _routeData.Values;
            var fileName = routeDataValues["file"].ToString();
            var fileExtension = routeDataValues["extension"].ToString();
 
            var manifestResourceName = string.Format("{0}.{1}.{2}", _resourcePath, fileName, fileExtension);
            var stream = _assembly.GetManifestResourceStream(manifestResourceName);
            if (stream == null)
            {
                throw new KeyNotFoundException(string.Format("Embedded resource key: '{0}' not found in the '{1}' assembly.", manifestResourceName, _assembly.FullName));
            }
 
            context.Response.Clear();
            context.Response.ContentType = "application/octet-stream";
            cacheIt(context.Response, _cacheDuration);
            stream.CopyTo(context.Response.OutputStream);
        }
 
        private static void cacheIt(HttpResponse response, TimeSpan duration)
        {
            var cache = response.Cache;
 
            var maxAgeField = cache.GetType().GetField("_maxAge", BindingFlags.Instance | BindingFlags.NonPublic);
            if (maxAgeField != null) maxAgeField.SetValue(cache, duration);
 
            cache.SetCacheability(HttpCacheability.Public);
            cache.SetExpires(DateTime.Now.Add(duration));
            cache.SetMaxAge(duration);
            cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
        }
    }
}
تصاویر پروژه‌ی افزونه نیز به صورت embedded resource در اسمبلی آن قرار خواهند گرفت. به همین جهت باید سیستم مسیریابی را پس درخواست رسیده‌ی جهت نمایش تصاویر، به منابع ذخیره شده‌ی در اسمبلی آن هدایت نمود. اینکار را با پیاده سازی یک IRouteHandler سفارشی، می‌توان به نحو فوق مدیریت کرد.
این IRouteHandler، نام و پسوند فایل را دریافت کرده و سپس به قسمت منابع اسمبلی رجوع، فایل مرتبط را استخراج و سپس بازگشت می‌دهد. همچنین برای کاهش سربار سیستم، امکان کش شدن منابع استاتیک نیز در آن درنظر گرفته شده‌است و هدرهای خاص caching را به صورت خودکار اضافه می‌کند.
سیستم bundling نیز هدرهای کش کردن را به صورت خودکار و توکار اضافه می‌کند.

اکنون به تعاریف Plugin1 مراجعه کنید و سپس این IRouteHandler سفارشی را به نحو ذیل به آن معرفی نمائید:
namespace MvcPluginMasterApp.Plugin1
{
    public class Plugin1 : IPlugin
    { 
        public void RegisterRoutes(RouteCollection routes)
        {
            //todo: add custom routes.
 
            var assembly = Assembly.GetExecutingAssembly();
            // Mostly the default namespace and assembly name are the same
            var nameSpace = assembly.GetName().Name;
            var resourcePath = string.Format("{0}.Images", nameSpace);
 
            routes.Insert(0,
                new Route("NewsArea/Images/{file}.{extension}",
                    new RouteValueDictionary(new { }),
                    new RouteValueDictionary(new { extension = "png|jpg" }),
                    new EmbeddedResourceRouteHandler(assembly, resourcePath, cacheDuration: TimeSpan.FromDays(30))
                ));
        } 
    }
}
در مسیریابی تعریف شده، تمام درخواست‌های رسیده‌ی به مسیر NewsArea/Images به EmbeddedResourceRouteHandler هدایت می‌شوند.
مطابق تعریف آن، file و extension به صورت خودکار جدا شده و توسط routeData.Values در متد ProcessRequest کلاس EmbeddedResourceHttpHandler قابل دسترسی خواهند شد.
پسوندهایی که توسط آن بررسی می‌شوند از نوع png یا jpg تعریف شده‌اند. همچنین مدت زمان کش کردن هر منبع استاتیک تصویری به یک ماه تنظیم شده‌است.


استفاده‌ی نهایی از تنظیمات فوق در یک View افزونه

پس از اینکه تصاویر و فایل‌های css و js را به صورت embedded resource تعریف کردیم و همچنین تنظیمات مسیریابی و bundling خاص آن‌ها را نیز مشخص نمودیم، اکنون نوبت به استفاده‌ی از آن‌ها در یک View است:
@{
    ViewBag.Title = "From Plugin 1";
}
@Styles.Render("~/Plugin1/Content")
 
<h2>@ViewBag.Message</h2>
 
<div class="row">
    Embedded image:
    <img src="@Url.Content("~/NewsArea/Images/chart.png")" alt="clock" />
</div>
 
@section scripts
{
    @Scripts.Render("~/Plugin1/Scripts")
}
در اینجا نحوه‌ی تعریف فایل‌های CSS و JS ارائه شده‌ی توسط سیستم Bundling را مشاهده می‌کنید.
همچنین مسیر تصویر مشخص شده‌ی در آن، اینبار یک NewsArea اضافه‌تر دارد. فایل اصلی تصویر، در مسیر Images/chart.png قرار گرفته‌است اما می‌خواهیم این درخواست‌ها را به مسیریابی جدید {NewsArea/Images/{file}.{extension هدایت کنیم. بنابراین نیاز است به این نکته نیز دقت داشت.

اینبار اگر برنامه را اجرا کنیم، می‌توان به سه نکته در آن دقت داشت:


الف) alert اجرا شده از فایل js مدفون شده خوانده شده‌است.
ب) رنگ قرمز متن (تگ h2) از فایل css مدفون شده، گرفته شده‌است.
ج) تصویر نمایش داده شده، همان تصویر مدفون شده‌ی در فایل DLL برنامه است.
و هیچکدام از این فایل‌ها، به پوشه‌های پروژه‌ی اصلی برنامه، کپی نشده‌اند.


کدهای کامل این قسمت را از اینجا می‌توانید دریافت کنید:
 MvcPluginMasterApp-Part2.zip
مطالب
دو تنظیم ضروری VS.NET جهت کار با WPF و Silverlight

تنظیم اول: تغییر نحوه‌ی نمایش پیش فرض فایل‌های XAML

اگر فایل XAML شما اندکی حجیم شود نمایش آن در VS.NET کمی طولانی خواهد شد و حالت پیش فرض نمایش در VS.NET هم split view mode است (نمایش XAML و پیش نمایش آن با هم). این مورد هم پس از مدتی تبدیل به عذاب می‌شود. برای رفع آن می‌توان حالت پیش فرض نمایش یک فایل XAML را به XAML View تنها تغییر داد.
برای این منظور به منوی Tools ، گزینه‌ی Options و سپس قسمت تنظیمات Text editor مراجعه کنید. در اینجا در قسمت XAML ، گزینه‌ی Miscellaneous را انتخاب کرده و سپس "Always open documents in full XAML view" را تیک بزنید.



حتی ممکن است این مورد هم رضایت بخش نباشد. در این حالت می‌توان ویرایشگر پیش فرض را کلا تغییر داد. Design tab را در پایین صفحه از دست می‌دهیم اما هنوز intellisense کار می‌کند و اگر نیاز به designer بود فقط کافی است کلیک راست کرده و گزینه‌ی View designer را انتخاب کرد:
روی یک فایل XAML دلخواه کلیک راست کرده و گزینه‌ی Open with را انتخاب کنید. سپس "Source Code (Text) Editor" را انتخاب کرده و روی دکمه‌ی Set as Default کلیک کنید. تمام!
هر چند Blend این مشکلات را ندارد و با فایل‌های حجیم XAML به خوبی کاری می‌کند.


تنظیم دوم: تغییر نحوه‌ی نمایش مشکلات ناشی از Binding

عموما اگر مشکلاتی در حین عملیات Binding در WPF یا Silverlight وجود داشته باشند، خطاها در Debugger Output Window نمایش داده می‌شوند. حالت پیش فرض هم فقط روی Error تنظیم شده است به این معنا که warning ها را مشاهده نخواهید کرد. برای تغییر این مورد باید به صورت زیر عمل کرد:
به منوی Tools ، گزینه‌ی Options و سپس قسمت تنظیمات Debugging مراجعه کنید. گزینه‌ی Output Window -> WPF Trace Settings را انتخاب نمائید. سپس در اینجا قسمت WPF trace settings را یافته و مقدار پیش فرض Data binding را که به Error تنظیم شده است، به Warning تنظیم نمائید.



مطالب
امکانات جدید Entity Framework Designer در VS 2012
ویرایش 2012 ابزار Visual Studio جهت کار با EF امکانات جدیدی دارد که سعی دارم به طور خلاصه چند مورد آنرا توضیح دهم.

پشتیبانی از Enum
در نسخه‌های قبل از EF 5 پیشتیبانی توکاری از Enum‌ها وجود نداشت و برنامه نویس برای استفاده از آن‌ها مجبور بود از روش‌های دیگری استفاده کند؛ مانند ^ استفاده کند. در نسخه 5 این امکان براحتی قابل اعمال است. بدین منظور کافی است:
1- در Designer بر روی خصوصیتی که قصد تبدیل آنرا به enum دارید راست کلیک کرده و گزینه Convert to enum را انتخاب کنید.

2- در پنجره Add enum ابتدا در قسمت Underlying type نوع Int32 را انتخاب کنید سپس می‌توان نام enum و اعضای آنرا و تعیین کرد.

3- دکمه ok را کلیک کنید و سپس پروژه را Build کنید.
در ادامه به راحتی می‌توان از آن در برنامه به صورت زیر استفاده کرد:
var department = (from d in context.Departments
                        where d.Name == DepartmentNames.English
                        select d).FirstOrDefault();

تقسیم یک مدل در Entity Framework به چند دیاگرام 
هنگامی که یک دیاگرام جدید ایجاد می‌کنید این دیاگرام به طور پیش فرض با نام Diagram1 به پوشه Diagrams اضافه می‌شود. اطلاعات مربوط به ظاهر موجودیت مانند رنگ و شکل و روابط آنها نیز در فایلی با پسوند edmx.diagram قرار می‌گیرند. شما بصورت دستی نمی‌توانید این فایل را تغییر دهید چون اطلاعات آن دوباره توسط جنریتور رونویسی می‌شود. لذا تغییر در دیاگرام به روش دستی مورد اطمینان نیست!

 
حتما برای کسانیکه از EF ِDesigner استفاده می‌کنند پیش آمده که بخواهند مدل موجویت هایشان را بجای یک فایل در چند فایل قرار دهند. اینکار مخصوصا زمانی که تعداد موجودیت‌ها زیاد است لازم به نظر می‌رسد بعلاوه اینکه مدیریت و مرور موجودیت‌ها را در پروژهای بزرگ آسانتر می‌کند. خوشبختانه این امکان در Visual Studio 2012 ایجاد شده است. 
بدین منظور در دیاگرام برنامه موجودیت هایی را که می‌خواهید به دیاگرام دیگری انتقال دهید با کلیک و شیفت انتخاب کنید. سپس راست کلیک کرده و گزینه Move to new Diagram را انتخاب کنید. دیاگرام جدیدی ایجاد شده و موجودیت انتخاب شده به آنجا انتقال داده می‌شود. بهتر است موجودیت هایی که برای انتقال انتخاب کرده اید به صورت یک گروه مستقل باشند یعنی با موجودیت‌های دیگر رابطه نداشته باشند.
کار انتقال به یک دیاگرام جدید را می‌توان به کمک کلیدهای Ctrl+C و Ctrl+X نیز انجام داد، باید توجه داشت در حالتی که موجودیت را کپی می‌کنید، نام موجودیت جدید با اضافه شدن یک عدد از موجودیت موجود جدا می‌شود.

تغییر رنگ موجودیت
روش دیگری که جهت متمایز و جدا کردن موجودیت‌ها می‌توان از آن استفاده کرد، تغییر رنگ آنهاست. بدین منظور پس از انتخاب موجودیت‌ها می‌توانید با تغییر مقدار Fill Color در پنجره Properties رنگ موجودیت‌های انتخاب شده را تغییر داد.

 
مطالب
بستن یک پنجره از طریق ViewModel با استفاده از خصوصیت های پیوست شده هنگام استفاده از الگوی MVVM
 در نظر بگیرید که یک پروژه WPF را با الگوی MVVM پیاده سازی کرده اید و نیاز پیدا می‌کنید تا یک پنجره را از طریق کد ببندید. از آنجایی که به کنترل Window درون ViewModel دسترسی ندارید، نمی‌توانید از متد Close آن برای اینکار استفاده کنید. راه‌های مختلفی برای اینکار وجود دارند، مثلا اگر از MVVM Light Toolkit استفاده می‌کنید با ارسال یک Message و نوشتن یک تکه کد در CodeBehind پنجره می‌توانید اینکار را انجام بدهید.
اما برای اینکار یک راه حل ساده‌تری بدون نیاز به نوشتن کد در CodeBehind و استفاده از Toolkit خاصی وجود دارد و آن استفاده ازخاصیت‌های پیوست شده یا Attached Properties است. برای اینکار یک خاصیت از نوع Boolean مانند زیر تعریف می‌کنیم و آن را به پنجره ای که می‌خواهیم Colse شود پیوست می‌کنیم.
namespace TestProject.XamlServices
{
    public class CloseBehavior
    {
        public static readonly DependencyProperty CloseProperty = 
DependencyProperty.RegisterAttached("Close", typeof(bool), typeof(CloseBehavior), new UIPropertyMetadata(false, OnClose));

        private static void OnClose(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (!(e.NewValue is bool) || !((bool) e.NewValue)) return;
            var win = GetWindow(sender);
            if (win != null)
                win.Close();
        }

        private static Window GetWindow(DependencyObject sender)
        {
            Window w = null;
            if (sender is Window)
                w = (Window)sender;
            return w ?? (w = Window.GetWindow(sender));
        }

        public static bool GetClose(Window target)
        {
            return (bool)target.GetValue(CloseProperty);
        }

        public static void SetClose(DependencyObject target, bool value)
        {
            target.SetValue(CloseProperty, value);
        }
    }
} 
در تکه کد بالا یک خصوصیت از نوع  Boolean  ایجاد کردیم که می‌تواند به هر پنجره ای که قرار است از طریق کد بسته شود، پیوست شود. خصوصیت‌های پیوست شده یک  Callback مربوط به تغییر مقدار دارند که یک  متداستاتیک است و مقدار جدید، از طریق  EventArg و   شیءایی که این خاصیت به آن پیوست شده نیز بعنوان Source  به آن  ارسال می‌شود. هر وقت مقدار خصوصیت، تغییر کند این متد فراخوانی می‌گردد. در کد بالا متد OnClose ایجاد شده است و زمانی که مقدار این خصوصیت برابر true می‌شود پنجره close خواهد شد.
برای استفاده از این خصوصیت و اتصال آن باید یک خصوصیت از نوع Boolean  نیز در ViewModel مربوط به Window ایجاد کنید:  
 private bool _isClose;
 public bool IsClose
   {
      get { return _isClose; }
      set
      {
       _isClose = value;
      OnClosed();
      RaisePropertyChanged("IsClose");
      }
}
و آن را به صورت زیر Bind کنید:  
<Window x:Class="TestProject.TestView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:xamlServices="clr-namespace:TestProject.XamlServices;assembly=TestProject.XamlServices"
       xamlServices:CloseBehavior.Close="{Binding IsClose}">
       ...
</Window>
پس از انجام اتصالات فوق، کافیست   هر جایی از ViewModel که نیاز است پنجره بسته شود،مقدار این خصوصیت برابر False بشود.
مطالب
بررسی چک لیست امنیتی web.config
در مقاله چک لیست امنیتی web.config متوجه شدیم که تنظیم یک سری مقادیر، باعث افزایش ضریب ایمنی وب سایت می‌شود. در این نوشتار قصد داریم به بررسی این چک لیست امنیتی بپردازیم.
اولین مورد لیست در رابطه با وضعیت session هاست؛ هر چند که توصیه میشود تا جای ممکن استفاده از session‌ها کنار گذاشته شود یا اینکه محدود شود .
  
SessionState
تگ sessionstate حاوی خصوصیتی به نام cookieless میباشد که در نسخه‌ی یک دات نت به صورت دو ارزشی پیاده سازی شده بود و با دادن مقدار false باعث میشد که سشن‌ها از طریق کوکی‌ها شناسایی شوند و در صورت true شدن، استفاده کوکی مسدود و از طریق url کنترل میشد. در نسخه دو دات نت، گزینه‌های این خصوصیت گسترده‌تر شد و مقادیر مختلفی اضافه شدند؛ مانند: شناسایی خودکار (در صورت عدم پشتیبانی مرورگر از کوکی) ، استفاده از کوکی و استفاده از URL.
استفاده در حالت url باعث میشود تا عبارات نامفومی که ما به آن sessionId می‌گوییم در بخشی از url به شکل زیر گنجانده شود:
https://www.dntips.ir/(xxxxxx)/page.aspx
استفاده از این حالت باعث مشکلات متعددی است؛ چه از لحاظ امنیتی و سایر موارد.
1- به دلیل تنوع لینکی که توسط این sessionID‌ها به ازای هر کاربر ایجاد میشوند، در نظر موتورهای جست و جو لینک‌هایی متفاوت محسوب شده و باعث کاهش جایگاه میگردد.
2- در صورتیکه آدرس دهی‌های شما بدون ذکر sessionID باشند، سرور کاربر مورد نظر را شناسایی نکرده و برای او session جدید صادر خواهد کرد. برای افزودن sessionID به لینک‌ها و اصلاح آن‌ها میتوان از متد زیر استفاده کرد:
Response.ApplyAppPathModifier
3- در صورت embed کردن sessionID در آدرس فایل‌های استاتیک، عملیات کش کردن نیز با مشکل مواجه خواهد شد.
4- در صورتی که session  معتبر باشد و لینکی از آن ارسال شود، کاربری دیگر، همان کاربر مبداء در نظر گرفته خواهد شد. نمونه این مسئله برای من اتفاق افتاده بود که در آن یکی از دوستان، لینکی از یکی از سازمان‌های دولتی را برای من ارسال کرده بود که حاوی sessionId بود تا قادر باشم وجه مورد نظر را به صورت آنلاین پرداخت کنم. بعد از اینکه من لاگین کردم، session او با کد کاربری من پر شد و در همان حین دوست من با یک refresh به جای اطلاعات خودش ، اطلاعات پرداختی‌های من را مشاهده میکرد.
در صورتی که از session استفاده نمیکنید، بهترین حالت غیرفعال کردن این گزینه میباشد.
  
HttpOnly Cookie
httpOnly برای کوکی‌ها، در واقع یک فلگ است که از سوی مایکروسافت معرفی شده و در حال حاضر اکثر مرورگرها از این گزینه پشتیبانی میکنند. این فلگ باعث میشود که کوکی در مرورگر دیگر از طریق اسکریپت‌های سمت کلاینت در دسترس نبوده و تنها از طریق ارتباط با سرور در دسترس قرار گیرد. نحوه افزودن این فلگ را در دستور زیر مشاهده میکنید:
Set-Cookie: <name>=<value>[; <Max-Age>=<age>]
[; expires=<date>][; domain=<domain_name>]
[; path=<some_path>][; secure][; HttpOnly]
با افزودن این فلگ، دامنه حملات سمت کلاینت به خصوص XSS کاهش پیدا کرده و امکان جابجایی کوکی بین مرورگرها از بین خواهد رفت. طبق گفته‌ی مایکل هوارد، یکی از مدیران امنیتی خانواده ویندوز، بیشتر این نوع حملات، صرف کوکی‌های سشن میباشد. در صورتیکه کوکی به فلگ httponly مزین شده باشد، حمله کننده قادر نخواهد بود از طریق کلاینت، دیتای داخل کوکی را بخواند و بجای آن، یک رشته‌ی خالی را تحویل گرفته و به سمت حمله کننده ارسال خواهد کرد.
در دات نت دو، این امکان برای forms Authentication  و همچنین session Id به طور خودکار لحاظ میگردد و این امکان از طریق وب کانفیگ در دسترس است:
<httpCookies httpOnlyCookies="true" …>
همچنین به شکل زیر از طریق کدنویسی امکان اعمال این فلگ بر روی کوکی‌ها امکان پذیر میباشد:
HttpCookie myCookie = new HttpCookie("myCookie");
myCookie.HttpOnly = true;
Response.AppendCookie(myCookie);
در نگارش‌های ماقبل دات نت دو باید این مورد را دستی به کوکی اضافه کرد که آقای هانسلمن در  وبلاگش این مورد را به طور کامل ذکر کرده است.
  
Custom Errors Mode
این مورد برای مشخص شدن وضعیت نمایش خطاها ایجاد شده است. در صورت خاموش کردن (Off) این گزینه، چه بر روی لوکال و چه بر روی سرور میزبان، خطاهای صفحه زرد رنگ به کاربران نمایش داده خواهد شد و از آنجا که این صفحه اطلاعات حیاتی و مهمی برای نمایش دارند، بهتر است که این صفحه از دید کابران نهایی مخفی شده و با ست کردن این گزینه روی On، صفحات خاصی که برای خطا مشخص کرده‌ایم نمایش پیدا می‌کنند و در صورتی که remoteOnly باشد، باعث می‌شود صفحه زرد رنگ تنها در حالت لوکال به نمایش در بیاید؛ ولی بر روی سرور تنها صفحات نهایی خطا نمایش داده میشوند که برای پروژه‌های در حالت توسعه بسیار مفید میباشد.
در نسخه IIS7 تگ دیگری به نام httperrors هم نیز اضافه شده است؛ ولی برای استفاده در نسخه‌های پیشین و همچنین IIS express موجود در ویژوال استودیو از همان Custom error استفاده نمایید.
  
Trace
trace کردن در دات نت یکی از قابلیت‌های مهم در سیستم دیباگینگ به شمار میرود که در دو حالت (در سطح اپلیکیشن) و همچنین (در سطح صفحه) اجرا میشود. این اطلاعات شامل اطلاعات مهمی چون درخواست‌ها و پارامترها، توکن سشن‌ها و... میباشد که در انتهای صفحه یا در پنجره مخصوص به خود به کاربر نمایش میدهد. بدیهی است که برای انتشار نهایی برنامه، این گزینه باید غیرفعال باشد تا این اطلاعات دیده نشوند.
  
compilation debug 
با true شدن این گزینه در محیط اجرایی، مشکلات زیادی برای سیستم ASP.Net رخ میدهد که در زیر آن‌ها را بررسی میکنیم:
1- باعث افزایش حجم شاخه temp خواهد شد.
2- timeout شدن صفحات با مشکل مواجه خواهند شد و ممکن است این timeout شدن اصلا رخ ندهد.
3- Batch Compilation که در همین تگ قابلیت true و false شدن را دارد، به کل نادیده گرفته شده و طوری با آن رفتار خواهد شد همانند حالتیکه مقدارش به false تنظیم شده‌است. این گزینه این امکان را به ما میدهد در صورتیکه درخواست صفحه‌ای در یک پوشه‌ی خاص داده شد، بقیه صفحات در آن محل نیز پردازش شوند تا در صورت درخواست صفحات همسایه، سرعت بالاتری در لود آن داشته باشیم. البته ناگفته نماند در صورتیکه در همان لحظه زمانی، سرور بار سنگینی را داشته باشد، این فرایند کنسل خواهد شد.
4- همه کتابخانه‌های جاوااسکرپیتی و فایلهای استاتیکی که از طریق فایل  axd قابل دسترس هستند، قابلیت کش شدن را از دست داده و سرعت کندی خواهند داشت. همچنین در صورتیکه این گزینه با false مقداردهی شود، امکان فشرده سازی نیز اضافه خواهد شد.
5- واضح است که با فعال سازی این گزینه، امکان دیباگینگ فعال شده و همه موارد را برای دیباگر مهیا میکند تا بتواند تا حد ممکن، همه مباحث مانیتور شوند و این مورد بر کارآیی نهایی تاثیرگذار خواهد بود.
نظرات اشتراک‌ها
فرم ساز JQuery
برای پیاده سازی آنچنان دانشی نیاز ندارد
اول مثال این صفحه‌ها را پیاده سازی کنید (بعد از کلیک بر روی دکمه ذخیره. پیش نمایش فرم را به شما نمایش میده)
json خروجی این المان را در جایی ذخیره کنید.
و در زمان نمایش فرم این مثال استفاده کنید(مثال از xml به JSON تغییر بدید) و دیتا ذخیره شده در قسمت قبل در این جا ست کنید.
زمانی هم که کاربر دکمه سابمیت(شما باید این دکمه را درست کنید به همراه تگ form) زد. شما مقدار Request در Action باید چک کنید آن هم به صورت داینامیک(با زدن حلقه For و...)
بعد خروجی حاصل برای کاربر ادمین به شکل
name="ابراهیم حمزه" - age="24"- و به همین ترتیب تا به آخر.
حداقل این روش برای فرم‌های ارتباط با ما جواب میدهد(در وردپرس هم پلاگین‌های بسیاری از این روش بهره میبرند و نتیجه را برای کاربر ادمین ایمیل میکنند- با همین فرمتی که من نمایش دادم.)
مطالب
نمایش ای‌جکسی یک partial view در popover بوت استرپ 3
فرض کنید بخواهیم نمایش رای دهنده‌های یک مطلب را با popover بوت استرپ 3 نمایش دهیم:

Popover بوت استرپ برای کار با منابع remote طراحی نشده‌است و نیاز است توابع API آن‌را به همراه jQuery Ajax ترکیب کرد تا به تصویر فوق رسید.


مرحله‌ی اول: اکشن متدی که یک partial view را باز می‌گرداند

فرض کنید اکشن متدی که لیست کاربران رای داده‌ی به یک مطلب را باز می‌گرداند، چنین شکلی را دارد:
        public ActionResult RenderResults(string param1)
        {
            var users = new[]
            {
                new User{ Id = 1, Name = "Test 1", Rating = 3},
                new User{ Id = 2, Name = "Test 2", Rating = 4},
                new User{ Id = 3, Name = "Test 3", Rating = 5}
            };
            return PartialView("_RenderResults", model: users);
        }
در اینجا لیستی دریافت و سپس به partial view ارسال می‌شود. در ادامه این Partial view نیز به صورت ذیل اطلاعات را رندر می‌کند:
@using RemotePopOver.Models
@model IList<User>

<ul id="ratings1" data-title="Ratings" class="list-unstyled">
    @foreach (var user in Model)
    {
        <li>
            @user.Name
            <span class="badge pull-right">@user.Rating</span>
        </li>
    }
</ul>
در اینجا از یک ویژگی سفارشی data-* به نام data-title نیز استفاده کرده‌ایم. متنی که در آن قرار می‌گیرد، به صورت عنوان popover ظاهر خواهد شد.


مرحله‌ی دوم: دریافت اطلاعات partial view با استفاده از jQuery Ajax و سپس درج آن در یک popover

می‌خواهیم با حرکت ماوس بر روی دکمه‌ی سفارشی ذیل، یک popover ظاهر شده و محتوای خودش را از اکشن متد فوق تامین کند.
<span id="remotePopover1"
      aria-hidden="true"
      data-param1="test"
      data-popover-content-url="@Url.Action("RenderResults", "Home")"
      class="glyphicon glyphicon-info-sign btn btn-info"></span>
در این مثال، چند ویژگی سفارشی data-* دیگر را نیز تعریف کرده‌ایم تا نیازی به تعریف سراسری متغیرهای جاوا اسکریپتی نباشد. برای مثال data-param1 یک پارامتر دلخواه است و data-popover-content-url به آدرس اکشن متدی اشاره می‌کند که قرار است partial view مدنظر را رندر کند.
در ادامه نحوه‌ی استفاده‌ی از این ویژگی‌ها را در jQuery Ajax مشاهده می‌کنید:
@section Scripts
{
    <script type="text/javascript">
        $(document).ready(function () {
            $('body').on('mouseenter', 'span[data-popover-content-url]', function () {
                var el = $(this);
                $.ajax({
                    type: "POST",
                    url: $(this).data("popover-content-url"),
                    data: JSON.stringify({ param1: $(this).data("param1") }),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    // controller is returning a simple text, not json
                    complete: function (xhr, status) {
                        var data = xhr.responseText;
                        if (status === 'error' || !data) {
                            el.popover({
                                content: 'Error connecting server!',
                                trigger: 'focus',
                                html: true,
                                container: 'body',
                                placement: 'auto',
                                title: 'Error!'
                            }).popover('show');
                        }
                        else {
                            el.popover({
                                content: data,
                                trigger: 'focus',
                                html: true,
                                container: 'body',
                                placement: 'auto',
                                title: $('<html />').html(data).find('#ratings1:first').data('title')
                            }).popover('show');
                        }
                    }
                });
            }).on('mouseleave', 'span[data-popover-content-url]', function () {
                $(this).popover('hide');
            });
        });
    </script>
}
در این مثال تمام المان‌هایی که دارای data-popover-content-url هستند، تحت نظر قرار می‌گیرند. سپس اگر ماوس به محدوده‌ی آن‌ها وارد شد، مقدار ("this).data("popover-content-url)$ مساوی آدرسی است که قرار است اطلاعات را از سرور دریافت کند. به همین جهت از آن برای استفاده‌ی در متد ajax کمک گرفته شده‌است.
خروجی partial view به صورت json نیست. بنابراین باید اطلاعات نهایی آن‌را در callback ویژه‌ی complete دریافت کرد. مقدار data دریافتی، معادل اطلاعات رندر شده‌ی partial view است. به همین جهت آن‌را به خاصیت content متد popver ارسال می‌کنیم. همچنین چون خروجی patrtial view به همراه html است، نیاز است خاصیت html متد popover نیز به true تنظیم شود. در خاصیت title، نحوه‌ی دسترسی به مقدار data-title تنظیم شده‌ی در partial view را مشاهده می‌کنید.


کدهای کامل این مثال را از اینجا می‌توانید دریافت کنید:
RemotePopOver.zip
مطالب
فشرده سازی اطلاعات در SQL server 2008

علاوه بر فشرده سازی خودکار بک آپ‌ها که پیشتر در مورد آن‌ها صحبت شد، اس کیوال سرور 2008 دو نوع فشرده سازی دیگر را نیز پشتیبانی می‌کند:

Row Compression :

حالت row compression نحوه‌ی ذخیره سازی فیزیکی داده‌ها را تغییر می‌دهد. فعال سازی آن اثرات زیر را خواهد داشت:
الف) متادیتای هر رکورد را حداقل می‌کند (منظور از متادیتا اطلاعاتی مانند اطلاعات ستون‌ها، طول و آفست و غیره است)
ب) داده‌های عددی و رشته‌هایی با طول ثابت، به صورت اطلاعاتی با طول متغیر ذخیره خواهند شد، درست مانند varchar ها.

برای ایجاد جدولی که row compression در آن به صورت پیش‌فرض فعال است، می‌توان مانند مثال زیر عمل کرد:
CREATE TABLE MyTable
(
ID int identity Primary key,
Name char(100),
Email char(100)
)
WITH (DATA_COMPRESSION = Row);

GO
و اگر جدول موجودی را می‌خواهید تغییر داده و این خاصیت را بر روی آن فعال نمائید، روش زیر را اعمال کنید:
Alter TABLE MyTable REBUILD WITH (DATA_COMPRESSION=Row, MAXDOP=2);
در اینجا MAXDOP مشخص می‌کند که از چند CPU باید برای فشرده سازی استفاده شود. (اگر جدولی حجیم دارید، به این صورت می‌توان عملیات فشرده سازی را سریعتر به پایان رساند)


Page Compression :

در روش دوم فشرده سازی اطلاعات در اس‌کیوال سرور 2008 ، که مهم‌ترین حالت موجود نیز می‌باشد، اطلاعات مشترک، بین سطرهای یک صفحه به اشتراک گذاشته می‌شوند. این روش از فناوری‌های زیر استفاده می‌کند:
الف) روش row compression که در مورد آن صحبت شد جزئی از این روش است.
ب) Prefix Compression : به ازای هر ستون در یک صفحه، Prefix های تکراری یافت شده و در هدر مخصوص فشرده سازی ذخیره می‌شوند (محل این هدر پس از هدر صفحه است). سپس هرجایی که به این Prefix ها اشاره شده‌باشد، عدد منحصربفرد شناسایی کننده آن‌ها نسبت داده می‌شود.
ج) Dictionary Compression : در این حالت مقادیر تکراری یک صفحه جستجو شده و در هدر فشرده سازی صفحه ذخیره می‌شوند. حالت Prefix Compression فقط به یک ستون منحصر می‌شود اما Dictionary Compression به کل صفحه اعمال می‌گردد.

برای فعال سازی آن در یک جدول جدید به روش زیر می‌توان عمل نمود:
CREATE TABLE MyTable
(
ID int identity Primary key,
Name char(100),
Email char(100)
)
WITH (DATA_COMPRESSION = Page);
و برای اعمال آن به جدولی موجود از روش زیر می‌توان استفاده کرد:

Alter TABLE MyTable REBUILD WITH (DATA_COMPRESSION=Page, MAXDOP=2);
یک سری رویه‌های ذخیره شده سیستمی جدید نیز برای محاسبه حجم جداول، پیش و پس از فشرده سازی (بدون فشرده سازی واقعی) نیز در این نگارش گنجانده شده‌اند که به شرح زیر هستند:
-- بررسی اینکه چه میزان فضا با اعمال فشرده سازی صفحات قابل صرفه جویی خواهد بود
EXEC sp_estimate_data_compression_savings 'schemaname', 'TableName', NULL, NULL, 'PAGE';

-- بررسی اینکه چه میزان فضا با اعمال فشرده سازی ردیف‌ها قابل صرفه جویی خواهد بود
EXEC sp_estimate_data_compression_savings 'schemaname', 'TableName', NULL, NULL, 'ROW';

بنابراین قبل از اینکه فشرده سازی را فعال نمائید، ابتدا بررسی کنید آیا واقعا میزان قابل توجهی اطلاعات فشرده خواهند شد و نتیجه حاصل رضایت بخش است یا خیر. همچنین باید درنظر داشت که جداول و یا ایندکس‌هایی که read و write بالایی دارند برای این منظور مناسب نیستند. برای یافتن آن‌ها کوئری زیر را اجرا کنید:

USE dbName;
SELECT objectname = OBJECT_NAME(s.object_id),
indexname = i.name,
i.index_id,
reads = range_scan_count + singleton_lookup_count,
'leaf_writes' = leaf_insert_count + leaf_update_count + leaf_delete_count,
'leaf_page_splits' = leaf_allocation_count,
'nonleaf_writes' = nonleaf_insert_count + nonleaf_update_count +
nonleaf_delete_count,
'nonleaf_page_splits' = nonleaf_allocation_count
FROM sys.dm_db_index_operational_stats (DB_ID(), NULL, NULL, NULL) AS s
INNER JOIN sys.indexes AS i
ON i.object_id = s.object_id
WHERE OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1
AND i.index_id = s.index_id
ORDER BY
leaf_writes DESC,
nonleaf_writes DESC

و جهت تکمیل مبحث می‌توان به مقاله بسیار جامع زیر که اخیرا توسط مایکروسافت منتشر شده است رجوع نمود:



نظرات مطالب
ساخت DropDownList های مرتبط به کمک jQuery Ajax در MVC
یک تجربه : 
این سلکتور $(this).attr('value')
برای کار با value در Option نال برمیگردوند و من من اینجوری استفاده کردم
 $('#Cities').change(function () {                
                jQuery.getJSON('@Url.Action("SelectTown")', { id: $(this).val() }, function (data) {
                    $('#Towns').empty();
                    jQuery.each(data, function (i) {
                        var option = $('<option></option>').val(data[i].ID).text(data[i].Name);
                        $("#Towns").append(option);
                    });
                });
            });
منظورم استفاده از .val به جای  .attr('value') هستش.
نمیدونم شاید بخاطر نسخه جدیدتر Jquery هست.