CheckBoxList در ASP.NET MVC
زحمات بسیاری در رابطه با آموزش کشیدید متشکر. امکانش هست که مثالی از نحوه فراخوانی اطلاعات از دیتابیس بوسیله Entity Framework در mvc نیز بیاورید
متشکرم
- ضمنا یک Visual NHibernate تجاری هم موجود است:
Visual NHibernate
نکته : آشنایی با کد نویسی و مفاهیم #F برای درک بهتر مطالب توصیه میشود.
معرفی پروژه FSharpX
این قسمتها عبارتند از :
FSharpx.Core : شامل مجموعه ای کامل از توابع عمومی، پرکاربرد و ساختاری است که برای این زبان توسعه داده شده اند و با تمام زبانهای دات نت سازگاری دارند؛
FSharpx.Http : استفاده از #F در برنامه نویسی مدل Http؛
FSharpx.TypeProvider : این پروژه خود شامل چندین بخش است که در این جا چند مورد از آنها را عنوان میکنم:
- FSharpx.TypeProviders.AppSetting : متد خواندن و نوشتن (setter و getter) را برای فایلهای تنظیمان پروژه (Application Setting File) فراهم میکند.
- FSharpx.TypeProviders.Vector : برای محاسبات با ساختارهای برداری استفاده میشود.
- FSharpx.TypeProviders.Machine : برای دسترسی و اعمال تغییرات در رجیستری و فایلهای سیستمی استفاده میشود.
- FSharpx.TypeProviders.Xaml : با استفاده از این افزونه میتوانیم از فایلهای Xaml، در پروژههای #F استفاده کنیم و WPF Designer نرم افزار VS.Net هم برای این زبان قابل استفاده خواهد شد.
- FSharpx.TypeProviders.Regex : امکان استفاده از عبارات با قاعده را در این پروژه فراهم میکند.
یک مثال از عبارات با قاعده:
type PhoneRegex = Regex< @"(?<AreaCode>^\d{3})-(?<PhoneNumber>\d{3}-\d{4}$)"> PhoneRegex.IsMatch "425-123-2345" |> should equal true PhoneRegex().Match("425-123-2345").CompleteMatch.Value |> should equal "425-123-2345" PhoneRegex().Match("425-123-2345").PhoneNumber.Value |> should equal "123-2345"
ایتدا یک پروژه از نوع F# Console Application ایجاد کنید. از قسمت Project Properties (بر روی پروژه کلیک راست کنید و گزینه Properties را انتخاب کنید) نوع پروژه را به Windows Application تغییر دهید(قسمت Out Put Type). اسمبلیهای زیر را به پروژه ارجاع دهید:
- PresentationCore
- PresentationFramework
- WindowBase
- System.Xaml
با استفاده از پنجره Package Manager Console دستور نصب زیر را اجرا کنید(آخرین نسخه این پکیج 1.8.31 و حجم آن کمتر از یک مگابایت است):
PM> Install-Package FSharpx.TypeProviders.Xaml
حال یک فایل Xaml به پروژه اضافه کنید و کدهای زیر را در آن کپی کنید:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WPF F# Sample By Masoud Pakdel" Height="350" Width="525"> <Grid Name="MainGrid"> <StackPanel Name="StackPanel1" Margin="50"> <Button Name="Button1">Who are you?</Button> </StackPanel> </Grid> </Window>
open System open System.Windows open System.Windows.Controls open FSharpx type MainWindow = XAML<"MainWindow.xaml"> let loadWindow() = let window = MainWindow() window.Button1.Click.Add(fun _ -> MessageBox.Show("Masoud Pakdel") |> ignore) window.Root [<STAThread>] (new Application()).Run(loadWindow()) |> ignore
در تابع loadWindow یک نمونه از کلاس MainWindow ساخته میشود و برای button1 آن رویداد کلیک تعریف میکنیم. دستورات زیر معادل دستورات شروع برنامه در فایل program پروژههای #C است.
[<STAThread>] (new Application()).Run(loadWindow()) |> ignore
پروژه را اجرا کنید و بر روی تنهای Button موجود در صفحه، کلیک کنید و پیغام مورد نظر را مشاهده خواهید کرد. به صورت زیر:
وبلاگها و سایتهای ایرانی
- میز کاری مجازی در ویندوز ویستا (البته روی XP هم کار کرد)
ASP. Net
طراحی وب
به روز رسانیها
ابزارها
سیشارپ
عمومی دات نت
دلفی
ویندوز
متفرقه
- کدام سایتها مطالب شما را کپی کردهاند؟! (البته شبیه به این کار را با Google alerts هم میشود انجام داد. فقط کافی است آدرس سایت خودتان را در گوگل alert اضافه کنید. هر جایی لینکی به شما داده شود یا امثال آن، یک ایمیل آنی یا روزانه بسته به تنظیمات برای شما ارسال خواهد کرد.)
با ASP.MVC چه مزایایی را به دست خواهیم آورد
- باز هم در وب سایتهای عمومی کمتر از سیلورلایت استفاده میشود چون مانند فلش، کل فایلهای باینری آن قابل دریافت و آنالیز است. همین مورد برای برنامههای به شدت امن قابل قبول نیست. اما در یک شبکه داخلی شاید این مساله اهمیتی نداشته باشد.
- تیم مونو اخیرا پشتیبانی از سیلورلایت رو متوقف کرده. بنابراین سازگاری با پلتفرمهای غیر ویندوزی آن را در نگارشهای جدید سیلورلایت فراموش کنید.
- خود مایکروسافت چند وقت قبل اعلام کرد که در وب تغییر جهت دادیم به HTML5 . هرچند بعدش تکذبیه صادر شد اما الان تمام کسانی رو که قبلا فقط در مورد سیلورلایت مطلب مینوشتند (اعضای سابق این تیم)، صرفا در مورد فریم ورکهای جدید js و برنامههای تک صفحهای وب مطلب مینویسند (با رویکرد MVC4).
و ... کسانیکه سیلورلایت را فراگرفتند چیزی رو از دست ندادند، چون معماری برنامههای WinRT و ویندوز 8، بسیار بسیار شبیه است به سیلورلایت. تا این حد که دورههای XAML و سی شارپ ویندوز 8 مدام به مقایسه سیلورلایت و WPF با این معماری جدید میپردازند.
شاید مهمترین اصل در سیستمهای توزیع شده، تقسیم وظایف در سخت افزارهای جداگانه و نحوه مدیریت ارتباط بین این وظایف باشد. مدیریتی که بدون آن، زمانیکه تعداد وظایف سیستم شما زیاد میشود، سیستم را با مشکلات جدی روبرو میکند. به احتمال زیاد شما نیز تاکنون با چنین مشکلاتی مواجه شدهاید، آن هم زمانیکه تعداد Applicationهای سیستمهایتان زیاد میشود و به تدریج وابستگیها و ارتباطات بین آنها نیز افزایش پیدا کرده و بدلیل اینکه شما از قبل زیرساختی برای مدیریت این ارتباطات ایجاد نکردهاید، کم کم کنترل این ارتباطات از دست شما خارج شدهاست. به همین دلیل من نیز میخواهم پیاده سازی سیستمهای توزیع شده را از نحوه مدیریت ارتباطات و وابستگیهای قسمتهای مختلف یک سیستم آغاز کنم تا بتوانیم از ابتدای ایجاد سیستم توزیع شده، زیرساخت درستی نیز برای مدیریت وابستگیها و ارتباطات قسمتهای مختلف آن داشته باشیم. پس بیایید با ارائه مثالی که به احتمال زیاد شما هم تابحال با آن روبرو شدهاید، با هم ببینیم که چگونه داشتن یک روش واحد و انعطاف پذیر برای مدیریت ارتباط بین سیستمهای مختلف میتواند به ما در تقسیم بندی وظایف، یکپارچگی سیستم، بالا بردن کارآیی و مدیریت بهتر کل سیستم کمک کند.
فرض
کنید ما چندین سیستم بزرگ مرتبط یا غیر مرتبط به هم داریم که هر کدامشان از چندین
زیر سیستم تشکیل شدهاند. ارتباط و وابستگی این سیستمها به این صورت است که یا از سیستمهای دیگر سرویسهایی را دریافت میکنند، یا دادههای مورد استفاده در آنها توسط سیستمهای دیگر تولید میشوند و آنها در بازه زمانی مشخصی این دادهها را در سیستمهای خودشان بروزرسانی میکنند.
همانطور که میبینید کل سیستم ما از همکاری تعدادی سیستم بزرگ تشکیل شدهاست که هرکدام از این سیستمهای بزرگ نیز از همکاری دو نوع زیر سیستم تشکیل شدهاند. نوع اول این زیرسیستمها که با عبارت Sub System مشخص شدهاند، زیر سیستمهایی هستند که تنها در همان سیستم استفاده میشوند و نوع دوم که با عبارت Common Sub System مشخص شدهاند و ما نیز زیاد با آنها روبرو میشویم، زیرسیستمهایی هستند که بصورت مشترک بین دو یا چند سیستم بزرگ مورد استفاده قرار میگیرند. بعنوان مثال میتوان زیرسیستم ارسال پیامک، ارسال ایمیل، مدیریت Log، زیر سیستم پرداخت و هر نوع زیرسیستم دیگری را که در سیستمهای مختلف بصورت مشترک استفاده میشود، نام برد.
به احتمال زیاد همه کسانیکه در سیستمهای رو به رشد و بزرگ کار کردهاند خوب میدانند که با بزرگتر شدن سیستمها و افزایش تعداد سیستمهای مرتبط و وابسته به هم، در صورت نبود یک روش واحد و انعطاف پذیر برای مدیریت ارتباط بین سیستمهای مختلف، چه مشکلاتی برای کل سیستم بوجود میآید. مشکلاتیکه در ابتدای شروع سیستم به هیچ وجه به چشم نمیآمدند، اما با توسعه و رشد سیستم، برایمان جدی میشوند.
بطور مثال زمانیکه اطلاعات پایه سیستم شما توسط یک یا چند سیستم تولید میشوند و سایر سیستمها بخاطر پایین نیامدن کارآیی سیستم خودشان مجبورند دادههای سیستم پایه را در سیستم خودشان Replicate کنند، شما چه روشی را برای بروز رسانی دادههای سایر سیستمها ارائه میدهید؟ شاید سادهترین و اولین روشی که به ذهنمان برسد، ایجاد یک Job باشد که با اجرا شدن در بازه زمانی مشخصی (مثلا شبانه) عملیات بروزرسانی را انجام دهد. این روش دو مشکل اساسی دارد: اول اینکه بصورت RealTime نیست. یعنی از زمانیکه داده وارد سیستم پایه میشود، تا زمانیکه Job اجرا شود، سیستمهای دیگر نمیتوانند از داده جدید استفاده کنند و دوم اینکه با اضافه شدن به تعداد سیستمهای وابسته شما مجبورید یا یک Job جدید را برای آن پیاده سازی کنید، یا قبلی را تغییر دهید. شاید شما با پیاده سازی چند سرویس در سیستمهای پایه و وابسته بتوانید مشکل RealTime نبودن بروز رسانی داده را حل کنید، اما این روش نیز بدون مشکل نیست. شاید اولین مشکل این روش این باشد، در صورتیکه در زمان فراخوانی، یکی از طرفین در دسترس نباشد، دادهها بروز رسانی نشوند و حل این مشکل پیچیدگی زیادی را برای شما بوجود بیاورد و دومین مشکل این است که در این روش نیز مانند روش قبل، با اضافه شدن به تعداد سیستمهای وابسته شما مجبورید یا سرویسهای جدیدی را برای این کار ایجاد کنید، یا سرویسهای قبلی را تغییر دهید. تکرار این روال باعث میشود شما پس از مدتی با انبوهی از سرویسهای مختلف رو برو شوید که مدیریت آنها برای شما بسیار دشوار است.
یکی دیگر از مشکلاتیکه ممکن است بوجود بیاید این است که با بزرگتر شدن و افزایش تعداد سیستمها، تعداد زیر سیستمهای تکراری نیز افزایش پیدا میکند که این خود ممکن است باعث شود یکپارچگی سیستم ما از بین برود. بنظر شما بهتر نبود زیرسیستمهای تکراری را اینقدر در سیستمهای مختلف تکرار نکنیم و با درنظر گرفتن آنها بعنوان یک یا چند زیرسیستم مستقل، کارآیی، یکپارچگی و مدیریت کل سیستم را افزایش دهیم؟
وجود مشکلات فوق و سایر مشکلاتی که ممکن است با بزرگتر شدن سیستم و افزایش تعداد آنها بوجود بیایند (که باتوجه به تجربه شما بنظرم نیازی به ذکر آنها نیست) با مرور زمان پیچیدگیهای بسیار زیای را در سیستم ما بوجود میآورد که شاید حل کردن آن امکان پذیر نباشد یا حداقل نیاز به صرف زمان و هزینه زیادی داشته باشد. پس شاید بهتر باشد در ابتدای پیاده سازی سیستم، زیرساخت درستی را برای ارتباط بین سیستمهای مختلف ایجاد کنیم.
اما چگونه میتوانیم این مجموعه سیستم را با هم ادغام کنیم و برای همه آنها یک هدف را مشخص کنیم و به آنها اجازه بدهیم با استفاده از یک روش واحد، انعطاف پذیر و کم هزینه، با یکدیگر در ارتباط باشند؟
باید بگویم که این مشکل با استفاده از Message Broker حل میشود .
یک Message Broker یک کامپوننت فیزیکی است که ارتباطات بین سیستمهای مختلف را مدیریت میکند و درواقع برای حل مشکلات مرتبط با نحوه مدیریت ارتباطات و وابستگیهای بین سیستمهای مختلف طراحی شده است. با استفاده از Message Broker بجای اینکه سیستمهای مختلف بصورت مستقیم با یکدیگر در ارتباط باشند، تنها با Message Broker در ارتباط اند و در اینجا Message Broker نقش یک Interface را بصورتی ایفا میکند که وظیفه آن به حداقل رساندن وابستگیهای مستقیم بین سیستمهای مختلف است. همچنین نحوه ارتباط قسمتهای مختلف هم به این صورت است که یک سیستم با ارائه مشخصات گیرنده یا گیرندگان، یک Message را برای Message Broker ارسال میکند و سپس Message Broker با روشها و الگوریتمهایی که در اختیار دارد و با جستجو در بین سیستمهایی که با آن مشخصات در آن ثبت شدهاند، Message را برای آنها ارسال میکند.
ارتباط بین Application ها تنها شامل ارسال کننده و Message broker و گیرندههای مشخص شدهاست و سایر سیستمها در آن دخیل نیستند. همچنین بدلیل اینکه Message Brokerها از یک صف انتقال اطلاعات استفاده میکنند، احتمال از دست رفتن Messageها به حداقل ممکن میرسد. یعنی زمانیکه یک سیستم، Messageی را برای Message Broker ارسال میکند، Message Broker تا زمانیکه دریافت کنندگان Message، آن را دریافت نکنند، آن Message را از صف انتقال حذف نمیکند. پس زمانیکه یک ارسال کننده Messageی را برای Message Broker ارسال میکند، حتی در صورتیکه دریافت کننده یا دریافت کنندگان در دسترس نیز نباشند، Message Broker این قابلیت را دارد تا زمانیکه دوباره دریافت کنندگان در دسترس باشند، Messageها را نگهداری کند. زیرا از دیدگاه کنترل جریان، Message Brokerها محدودیتی در تعداد سیستمهای متصل به خودشان و زمان اتصال آنها ندارند. یعنی Message Brokerها این قابلیت را دارند حتی در زمان اجرا نیز سیستمهای جدید را بپذیرند. بطور خلاصه Message Brokerها مدیریت همکاری بین سیستمهای مختلف را بر عهده دارند. قرار دادن Message Brokerها بین ارسال کنندگان و دریافت کنندگان، انعطاف پذیری را در ارتباط بین سیستمهای مختلف افزایش میدهد و با کمترین میزان تغییر در ارسال کنندگان و گیرندگان میتوانید قابلیتهای جدیدی را به سیستم اضافه کنید.
با این روش شما میتوانید با کمترین هزینه برای سیستمهای درگیر، تغییرات سیستمهای پایه را در سیستمهای وابسته اعمال کنید؛ آن هم بصورتیکه با افزایش تعداد سیستمهای وابسته، نیازی به تغییر در سیستم پایه و سایر سیستمها نباشد. همچنین با این روش شما به راحتی و کمترین هزینه میتوانید تمامی زیرسیستمهای خود ازجمله زیرسیستمهای مشترک را بصورت یک زیرسیستم مستقل پیاده سازی کنید و با این کار یکپارچگی کل سیستم خود را افزایش دهید. کارآیی آنها را بالا ببرید و با مستقل شدن آنها مدیریت آنها را برای خودتان سادهتر کنید.
انواع مختلفی از Message Brokerها وجود دارند که هر کدام از آنها مزایا و معایب خاص خودشان را دارند و به دلیل اینکه من در سری مقالات سیستمهای توزیع شده سعی دارم شما را با مبانی پیاده سازی آنها آشنا کنم، تنها یکی از آنها را مورد بررسی قرار میدهم و مقایسه و تصمیم گیری در مورد اینکه کدامیک از آنها کارآیی بیشتری را برای شما دارد، بر عهده خودتان میگذارم. من در اینجا شناخته شدهترین Message Brokerهایی را که در دسترس هستند و شما میتوانید از آنها استفاده کنید، به شما معرفی میکنم.
لیست Message brokerها:
در فصل بعد من سعی میکنم شما را با Rabbitmq که از معروفترین، پایدارترین و قابل اعتمادترین Message Brokerهایی که شخصا چندین سیستم را با استفاده از آن پیاده سازی کردهام، آشنا کنم و ببینیم که چگونه این ابزار میتواند به ما در رفع مشکلاتیکه در نحوه مدیریت و سازماندهی سیستمهای مختلف بوجود میآیند، کمک کند.
البته این نکته را نیز باید ذکر کنم که همانطور که میبینید همیشه دلیل استفاده کردن از سیستمهای توزیع شده، بالابردن کارآیی نیست. ما میتوانیم برای پیاده سازی سیستمهای توزیع شده دلایل و اهداف دیگری نیز داشته باشیم. همانطور که مشاهده کردید ما نهتنها از Message Brokerها میتوانیم در سیستمهایی که واقعا تمام اجزایشان بصورت توزیع شده پیاده سازی شدهاند، استفاده کنیم، بلکه میتوانیم از آنها برای مدیریت وابستگیها و ارتباطات بین سیستمهای فعلی که داریم نیز استفاده کنیم و درواقع بصورت واقعی و فنی برای همه آنها هدف واحدی را تعریف کنیم. فعلا هدف من این است که با هم ببینیم چگونه میتوانیم وظایف مختلف سیستم را در سخت افزارهای مختلف، تقسیم کنیم و ارتباطات آنها را مدیریت کنیم. در فصلهای بعد میبینیم که برای رسیدن به اهداف دیگر سیستمهای توزیع شده از چه روشها و ابزارهای دیگری میتوان استفاده کرد.
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fa-IR"); Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("fa-IR");
[Required(ErrorMessageResourceName = "ResourceKeyName", ErrorMessageResourceType = typeof(<SolutionName>.Resources.<ResourceClassName>))]
public class LocalizationDisplayNameAttribute : DisplayNameAttribute { private readonly DisplayAttribute _display; public LocalizationDisplayNameAttribute(string resourceName, Type resourceType) { _display = new DisplayAttribute { ResourceType = resourceType, Name = resourceName }; } public override string DisplayName { get { try { return _display.GetName(); } catch (Exception) { return _display.Name; } } } }
public class LocalizationDisplayNameAttribute : DisplayNameAttribute { private readonly PropertyInfo nameProperty; public LocalizationDisplayNameAttribute(string displayNameKey, Type resourceType = null) : base(displayNameKey) { if (resourceType != null) nameProperty = resourceType.GetProperty(base.DisplayName, BindingFlags.Static | BindingFlags.Public); } public override string DisplayName { get { if (nameProperty == null) base.DisplayName; return (string)nameProperty.GetValue(nameProperty.DeclaringType, null); } } }
[LocalizationDisplayName("ResourceKeyName", typeof(<SolutionName>.Resources.<ResourceClassName>))]
public class BaseController : Controller { private const string LanguageCookieName = "MyLanguageCookieName"; protected override void ExecuteCore() { var cookie = HttpContext.Request.Cookies[LanguageCookieName]; string lang; if (cookie != null) { lang = cookie.Value; } else { lang = ConfigurationManager.AppSettings["DefaultCulture"] ?? "fa-IR"; var httpCookie = new HttpCookie(LanguageCookieName, lang) { Expires = DateTime.Now.AddYears(1) }; HttpContext.Response.SetCookie(httpCookie); } Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang); base.ExecuteCore(); } }
public class LocalizationActionFilterAttribute : ActionFilterAttribute { private const string LanguageCookieName = "MyLanguageCookieName"; public override void OnActionExecuting(ActionExecutingContext filterContext) { var cookie = filterContext.HttpContext.Request.Cookies[LanguageCookieName]; string lang; if (cookie != null) { lang = cookie.Value; } else { lang = ConfigurationManager.AppSettings["DefaultCulture"] ?? "fa-IR"; var httpCookie = new HttpCookie(LanguageCookieName, lang) { Expires = DateTime.Now.AddYears(1) }; filterContext.HttpContext.Response.SetCookie(httpCookie); } Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang); base.OnActionExecuting(filterContext); } }
<select id="langs" onchange="languageChanged()"> <option value="fa-IR">فارسی</option> <option value="en-US">انگلیسی</option> </select> <script type="text/javascript"> function languageChanged() { setCookie("MyLanguageCookieName", $('#langs').val(), 365); window.location.reload(); } document.ready = function () { $('#langs').val(getCookie("MyLanguageCookieName")); }; function setCookie(name, value, exdays, path) { var exdate = new Date(); exdate.setDate(exdate.getDate() + exdays); var newValue = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString()) + ((path == null) ? "" : "; path=" + path) ; document.cookie = name + "=" + newValue; } function getCookie(name) { var i, x, y, cookies = document.cookie.split(";"); for (i = 0; i < cookies.length; i++) { x = cookies[i].substr(0, cookies[i].indexOf("=")); y = cookies[i].substr(cookies[i].indexOf("=") + 1); x = x.replace(/^\s+|\s+$/g, ""); if (x == name) { return unescape(y); } } } </script>
GET https://www.dntips.ir HTTP/1.1 ... Accept-Language: fa-IR,en-US;q=0.5 ...
Accept-Language: fa-IR,fa;q=0.8,en-US;q=0.5,ar-BH;q=0.3
<system.web> <globalization enableClientBasedCulture="true" uiCulture="auto" culture="auto"></globalization> </system.web>
var langs = filterContext.HttpContext.Request.UserLanguages;
routes.MapRoute( "Localization", // Route name "{lang}/{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults );
public class BaseController : Controller { protected override void ExecuteCore() { var lang = RouteData.Values["lang"]; if (lang != null && !string.IsNullOrWhiteSpace(lang.ToString())) { Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang.ToString()); } base.ExecuteCore(); } }
public class BaseController : Controller { protected override void OnActionExecuted(ActionExecutedContext context) { var view = context.Result as ViewResultBase; if (view == null) return; // not a view var viewName = view.ViewName; view.ViewName = GetGlobalizationViewName(viewName, context); base.OnActionExecuted(context); } private static string GetGlobalizationViewName(string viewName, ControllerContext context) { var cultureName = Thread.CurrentThread.CurrentUICulture.Name; if (cultureName == "en-US") return viewName; // default culture if (string.IsNullOrEmpty(viewName)) return context.RouteData.Values["action"] + "." + cultureName; // "Index.fa" int i; if ((i = viewName.IndexOf('.')) > 0) // ex: Index.cshtml return viewName.Substring(0, i + 1) + cultureName + viewName.Substring(i); // "Index.fa.cshtml" return viewName + "." + cultureName; // "Index" ==> "Index.fa" } }
public sealed class RazorGlobalizationViewEngine : RazorViewEngine { protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) { return base.CreatePartialView(controllerContext, GetGlobalizationViewPath(controllerContext, partialPath)); } protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { return base.CreateView(controllerContext, GetGlobalizationViewPath(controllerContext, viewPath), masterPath); } private static string GetGlobalizationViewPath(ControllerContext controllerContext, string viewPath) { //var controllerName = controllerContext.RouteData.GetRequiredString("controller"); var request = controllerContext.HttpContext.Request; var lang = request.Cookies["MyLanguageCookie"]; if (lang != null && !string.IsNullOrEmpty(lang.Value) && lang.Value != "en-US") { var localizedViewPath = Regex.Replace(viewPath, "^~/Views/", string.Format("~/Views/Globalization/{0}/", lang.Value)); if (File.Exists(request.MapPath(localizedViewPath))) viewPath = localizedViewPath; } return viewPath; }
protected void Application_Start() { ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new RazorGlobalizationViewEngine()); }
<?xml version="1.0" encoding="utf-8"?> <root> <!-- Microsoft ResX Schema ... --> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> ... </xsd:schema> <resheader name="resmimetype"> <value>text/microsoft-resx</value> </resheader> <resheader name="version"> <value>2.0</value> </resheader> <resheader name="reader"> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <data name="RightToLeft" xml:space="preserve"> <value>false</value> <comment>RightToleft is false in English!</comment> </data> </root>