рдкрд╛рда рдХрд╛ рдЙрджреНрджреЗрд╢реНрдпред рдмрд╣реБрднрд╛рд╖реА рд╕рд╛рдЗрдЯ рдмрдирд╛рдирд╛ рд╕реАрдЦреЗрдВред DB рд╕рдВрд░рдЪрдирд╛ рд╕рд╛рдЗрдЯ рд╕рдВрд╕рд╛рдзрдиред рднрд╛рд╖рд╛ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ред рднрд╛рд╖рд╛рдУрдВ рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдВред рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░реЗрдВред
рдмрд╣реБрднрд╛рд╖реА рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХреЗ рдореБрджреНрджреЗ
рддреЛ, рдЧреНрд░рд╛рд╣рдХ рд╕рд╛рдЗрдЯ рдХреЛ рдмрд╣реБрднрд╛рд╖реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддред рддрд╛рдХрд┐ рд░реВрд╕реА рдореЗрдВ, рдФрд░ рдлреНрд░реЗрдВрдЪ рдореЗрдВ, рдФрд░ рдЕрдВрдЧреНрд░реЗрдЬреА рдореЗрдВред рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдмрд╣реБрднрд╛рд╖реА рдмреНрд▓реЙрдЧ, рдПрдХ рд╣реЛрдЯрд▓ рд╕рд╛рдЗрдЯ, рдПрдХ рд░рд┐рдпрд▓ рдПрд╕реНрдЯреЗрдЯ рд╕рд╛рдЗрдЯ рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВрдЧреЗ рдХрд┐ рд╣рдо рдХреНрдпрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдВрдЧреЗ:
- рдЪрдпрдирд┐рдд рд╕реНрдерд╛рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рджрд┐рдирд╛рдВрдХ, рд░рд╛рд╢рд┐рдпрд╛рдБ рд▓рд┐рдЦрдирд╛ред System.Globalization рд╡рд░реНрдЧ рдЗрд╕реЗ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред
- рд╕рд╛рдЗрдЯ рдХреЗ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд╕рдВрд╕рд╛рдзрди - рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ ("рдлрд╝реАрд▓реНрдб рдЦрд╛рд▓реА рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛", "рдлрд╝реАрд▓реНрдб рдЖрд╡рд╢реНрдпрдХ рд╣реИ") рдФрд░ рдЕрдиреНрдп рд╕рдВрджреЗрд╢ред
- рдЧреИрд░-рдПрдореНрдмреЗрдбреЗрдб рд╕рдВрд╕рд╛рдзрди, рдЬреИрд╕реЗ рд▓реЛрдЧреЛ, рдЪрд┐рддреНрд░, рдирд┐рдпрдВрддреНрд░рдг рдХреЗ js- рд╕реНрдерд╛рдиреАрдпрдХрд░рдгред рдЙрдирдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкреГрд╖реНрда рдкрд░ рд╡рд░реНрддрдорд╛рди рднрд╛рд╖рд╛ рдореВрд▓реНрдп рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
- рдХрд╕реНрдЯрдо рдореВрд▓реНрдпред
рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВред рдЙрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
- рд╕рдмрд╕реЗ рд╕рд░рд▓ рдЪреАрдЬреЗрдВ рдЬреЛ рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рд╡реЗ рд╡рд┐рднрд┐рдиреНрди рд╕рд╛рдЗрдЯреЗрдВ рд╣реИрдВред рдПрдХ рд░реВрд╕реА рд╕рд╛рдЗрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдХрд┐рдпрд╛ред рд╣рдореЗрдВ рдПрдХ рдЕрдиреБрд╡рд╛рдж рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╕рд╛рдЗрдЯ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдИ, рд╕рднреА рдбреЗрдЯрд╛ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд┐рдпрд╛ рдФрд░ рдпрд╣ рдмрд╛рдд рд╣реИред рдпрд╣ рд╡рд┐рдХрд▓реНрдк рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИ, рдЬрдм рд╕рд╛рдЗрдЯ рдЫреЛрдЯреА рд╣реИ, рдХреЗрд╡рд▓ рдХреБрдЫ рдкреГрд╖реНрда, рд╕реНрдереИрддрд┐рдХ рдФрд░ рдХреЛрдИ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдкреИрдирд▓ рдирд╣реАрдВ рд╣реИред
- рд╡рд┐рднрд┐рдиреНрди рдбреЗрдЯрд╛рдмреЗрд╕ред рд╕рд╛рдЗрдЯ, рдЪрдпрдирд┐рдд рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдПрдХ рдпрд╛ рджреВрд╕рд░реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдЬреБрдбрд╝реА рд╣реЛрддреА рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдПрдХ рдирдИ рднрд╛рд╖рд╛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдкреВрд░реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рд╕рд╛рдЗрдЯ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдбреЗрдЯрд╛рдмреЗрд╕ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдПрдХ рднрд╛рд╖рд╛ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд▓реЗрдЦ рджреВрд╕рд░реЗ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЫрд╡рд┐рдпреЛрдВ рдХреА рдирдХрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬрд┐рд╕реЗ рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
- рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдкреНрд░рдмрдВрдзрдиред
рддреАрд╕рд░реЗ рд╡рд┐рдХрд▓реНрдк рдкрд░ рддреБрд░рдВрдд рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдФрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╣рдо рдЗрд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
- рд▓реИрдВрдЧ рдкреИрд░рд╛рдореАрдЯрд░ рдЕрдм рд╕рд╛рдЗрдЯ рдкрддреЗ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ
- рд╢рд╛рдпрдж рдкрддрд╛ рд╣реА рд▓рдЧреЗрдЧрд╛
our-site.com{lang}/{controller}/{action}
- рд╢рд╛рдпрдж рдкрддрд╛ рд╣реА рд▓рдЧреЗрдЧрд╛
our-site.com{controller}/{action}?lang=ru
- рд▓реИрдВрдЧ рдкреИрд░рд╛рдореАрдЯрд░ рдПрдХ рдЖрдИрдПрд╕рдУ рджреЛ рдЕрдХреНрд╖рд░ рдХреА рднрд╛рд╖рд╛ рдкрд░рд┐рднрд╛рд╖рд╛ рд╣реИ (рдЖрд░рдпреВ - рд░реВрд╕реА, рдмреНрд░рд┐рдЯреЗрди - рдпреВрдХреНрд░реЗрдиреА, рд╕реАрдПрд╕ - рдЪреЗрдХ)
- рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рддрд╛рд░реАрдЦреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП System.Globalization рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
- рд╣рдо рджрд┐рдП рдЧрдП рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдВрддрд░рд┐рдХ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЖрдпреЛрдЬрди рдХрд░рддреЗ рд╣реИрдВ
- рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдлрд╝реАрд▓реНрдб рдХрд╛ рдЕрдиреБрд╡рд╛рдж рд╣реЛред
рд╣рдо 2 рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдмрдирд╛рдПрдВрдЧреЗ - рд░реВрд╕реА рдФрд░ рдЕрдВрдЧреНрд░реЗрдЬреА, рдФрд░ рд░реВрд╕реА рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╣реЛрдЧрд╛ред
рд░реВрдЯрд┐рдВрдЧ
DefaultAreaRegademy рдореЗрдВ, рд▓реИрдВрдЧ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ (/Areas/Default/DefaultAreaRegistration.cs) рдЬреЛрдбрд╝реЗрдВ:
context.MapRoute( name: "lang", url: "{lang}/{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints : new { lang = @"ru|en" }, namespaces: new[] { "LessonProject.Areas.Default.Controllers" } ); context.MapRoute( name : "default", url : "{controller}/{action}/{id}", defaults : new { controller = "Home", action = "Index", id = UrlParameter.Optional, lang = "ru" }, namespaces : new [] { "LessonProject.Areas.Default.Controllers" } );
рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рд▓рд╛рдЗрди рд▓реИрдВрдЧ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ, рддреЛ рд╣рдо "рд▓реИрдВрдЧ" рдорд╛рд░реНрдЧ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдХрдВрдЯреНрд░рд╛рд╕реНрдЯрд┐рдиреНрд╕ (рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ) рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ, рдпрд╣рд╛рдВ рдпрд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рднрд╛рд╖рд╛ рдХреЗрд╡рд▓ рдЖрд░рдпреВ рдпрд╛ рдПрди рд╣реЛ рд╕рдХрддреА рд╣реИред рдпрджрд┐ рдпрд╣ рд╢рд░реНрдд рдкреВрд░реА рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рддреЛ рд╣рдо рдЕрдЧрд▓реЗ рдорд╛рд░реНрдЧ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ - "рдбрд┐рдлрд╝реЙрд▓реНрдЯ", рдЬрд╣рд╛рдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ lang = ruред
рд╣рдо рдереНрд░реЗрдб рд╕рдВрд╕реНрдХреГрддрд┐ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП DefaultController рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ (Thread.Current.CurrentCulture) (/Areas/Default/DefaultController.cs):
public class DefaultController : BaseController { public string CurrentLangCode { get; protected set; } public Language CurrentLang { get; protected set; } protected override void Initialize(System.Web.Routing.RequestContext requestContext) { if (requestContext.HttpContext.Request.Url != null) { HostName = requestContext.HttpContext.Request.Url.Authority; } if (requestContext.RouteData.Values["lang"] != null && requestContext.RouteData.Values["lang"] as string != "null") { CurrentLangCode = requestContext.RouteData.Values["lang"] as string; CurrentLang = Repository.Languages.FirstOrDefault(p => p.Code == CurrentLangCode); var ci = new CultureInfo(CurrentLangCode); Thread.CurrentThread.CurrentUICulture = ci; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name); } base.Initialize(requestContext); } }
рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ, BaseController рдореЗрдВ рд╣рдо рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ (/Controllers/BaseController.cs) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдЯреНрд░реАрдо рд╕рдВрд╕реНрдХреГрддрд┐ рдХреЗ рдЖрд░рдВрдн рдХреЛ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ:
protected override void Initialize(System.Web.Routing.RequestContext requestContext) { if (requestContext.HttpContext.Request.Url != null) { HostName = requestContext.HttpContext.Request.Url.Authority; } base.Initialize(requestContext); }
рд╣рдо рдЗрд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЬрд╛рдБрдЪрддреЗ рд╣реИрдВ рдХрд┐ рджрд┐рдирд╛рдВрдХ рдЖрдЙрдЯрдкреБрдЯ рдХреИрд╕реЗ рдмрджрд▓рддрд╛ рд╣реИ:

рдкрд╣рд▓рд╛ рдЪрд░рдг рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред рд╣рдо рд╕рд╛рдЗрдЯ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рдкреНрд░рдмрдВрдзрди рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реИрдВред
рд╕рд╛рдЗрдЯ рд╕рдВрд╕рд╛рдзрди
рд╕рд╛рдЗрдЯ рд╕рдВрд╕рд╛рдзрди рд╕рднреА рд╕реНрдерд┐рд░ рд▓рд╛рдЗрдиреЗрдВ рд╣реИрдВ рдЬрд┐рдирдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
- рдореЗрдиреВ рдирд╛рдо
- рдпреБрдХреНрддрд┐рдпрд╛рдБ
- рддреНрд░реБрдЯрд┐ рдирд┐рд╖реНрдХрд░реНрд╖
рдореБрдЦреНрдп рдкреГрд╖реНрда рдкрд░ рдЪрд╛рд░ рдРрд╕реА рд▓рд╛рдЗрдиреЗрдВ рд╣реИрдВ: рднреВрдорд┐рдХрд╛рдПрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛, рд▓реЙрдЧрд┐рди рдФрд░ рдкрдВрдЬреАрдХрд░рдгред рд╕рдВрд╕рд╛рдзрди рдлрд╝рд╛рдЗрд▓реЗрдВ рдмрдирд╛рдПрдБ:
- Asp.net рдлрд╝реЛрд▓реНрдбрд░ рдХреЛ App_LocalResources рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:

- рдЗрд╕рдореЗрдВ GlobalRes.resx рдФрд░ GlobalRes.en.resx рдлрд╛рдЗрд▓реЗрдВ рдмрдирд╛рдПрдБ:

- рд╣рдо рдЙрди рдкрд░ рдЕрдкрдиреА рд▓рд╛рдЗрдиреЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, GlobalRes рдореЗрдВ - рд░реВрд╕реА рдЕрдиреБрд╡рд╛рдж, GlobalRes.en рдореЗрдВ - рдЕрдВрдЧреНрд░реЗрдЬреА:
рджрд░реНрдЬ | рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ |
рд░рдЬрд┐рд╕реНрдЯрд░ | рдкрдВрдЬреАрдХрд░рдг |
рднреВрдорд┐рдХрд╛рдПрдБ | рднреВрдорд┐рдХрд╛ |
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ | рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ |
- GlobalRes рдХреЗ рд▓рд┐рдП рдЧреБрдг рдЦреЛрд▓реЗрдВ рдФрд░ рдлрд╝реАрд▓реНрдб рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдорд╛рди рд╕реЗрдЯ рдХрд░реЗрдВ
- рдмрд┐рд▓реНрдб рдПрдХреНрд╢рди: рдПрдВрдмреЗрдбреЗрдб рд╕рдВрд╕рд╛рдзрди
- рдХрд╕реНрдЯрдо рдЯреВрд▓: PublicResXFileCodeGenerator

- рдЕрдм System.web.webPages.razor (Web.config) рдореЗрдВ Web.cofig рдХреЗ рд▓рд┐рдП Namepace LessonProject.App_LocalResources рдЬреЛрдбрд╝реЗрдВред
<system.web.webPages.razor> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="LessonProject.Helper" /> <add namespace="LessonProject.Tools" /> <add namespace="LessonProject.App_LocalResources" /> </namespaces> </pages> </system.web.webPages.razor>
- рд╣рдо UserLogin.cshtml (/Areas/Default/Views/Home/UserLogin.cshtml) рдФрд░ Index.cshtml ((/Areas/Default/Views/Hearome-Index.cshtml) рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:
@model LessonProject.Model.User @if (Model != null) { <li>@Model.Email</li> <li>@Html.ActionLink("", "Logout", "Login")</li> } else { <li><span class="btn btn-link" id="LoginPopup">@GlobalRes.Enter</span></li> <li>@Html.ActionLink(GlobalRes.Register, "Register", "User")</li> } тАж @{ ViewBag.Title = "LessonProject"; Layout = "~/Areas/Default/Views/Shared/_Layout.cshtml"; } <h2>LessonProject </h2> <p> @DateTime.Now.ToString("D") <div class="menu"> <a href="@Url.Action("Index", "Role", new { id = "1" })">@GlobalRes.Roles</a> @Html.ActionLink(GlobalRes.Users, "Index", "User") </div> </p>
рдЪрд▓рд╛рдПрдВ, рдЬрд╛рдВрдЪреЗрдВ:

рдЪрд▓рд┐рдП LoginView рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рддреНрдпрд╛рдкрди рд╕рдВрджреЗрд╢ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ:
- рдлрд╝реАрд▓реНрдб рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП ErrorMessage рдЪреБрдиреЗрдВ (/App_LocalResources/GlobalRes.resx):
EnterEmail | рдИрдореЗрд▓ рджрд░реНрдЬ рдХрд░реЗрдВ |
EnterPassword | рдкрд╛рд╕рд╡рд░реНрдб рдбрд╛рд▓реЗрдВ |
- рд╣рдо LoginView.cs (/Models/ViewModel/LoginView.cs) рдореЗрдВ рд╕рддреНрдпрд╛рдкрди рдирд┐рдпрдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
public class LoginView { [Required(ErrorMessageResourceType=typeof(GlobalRes), ErrorMessageResourceName="EnterEmail")] public string Email { get; set; } [Required(ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "EnterPassword")] public string Password { get; set; } public bool IsPersistent { get; set; } }
рд╕реНрдерд╛рдиреАрдпрд╣реЛрд╕реНрдЯ / en / рд▓реЙрдЧрд┐рди рдкреГрд╖реНрда рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:

рд▓реЗрдХрд┐рди рдкреЙрдкрдЕрдк рд▓реЙрдЧрд┐рди рдХреЗ рд▓рд┐рдП, рдпреЗ рдЪреЗрддрд╛рд╡рдиреА рд░реВрд╕реА рдореЗрдВ рд░рд╣реЗрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдкреЙрдкрдЕрдк рдмреНрд▓реЙрдХ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдпреВрдЖрд░рдПрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рддрджрдиреБрд╕рд╛рд░, рд▓рдВрдЧ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реЗрдЯ рдХрд░рдХреЗ, рд╣рдо рдЗрд╕реЗ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ:
- рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ (/App_LocalResources/GlobalRes(.en).resx)CurrentLang = ru рдФрд░ CurrentLang = en
- рдЗрд╕реЗ рдЫрд┐рдкреЗ рд╣реБрдП рдлрд╝реАрд▓реНрдб рдореЗрдВ _Layout.cshtml (/Areas/Default/Views/Saring/_Layout.cshtml) рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рдХрд░реЗрдВ:
<body> @Html.Hidden("CurrentLang", GlobalRes.CurrentLang) <div class="navbar navbar-fixed-top"> тАв ajax- (/Scripts/common.js): _this = this; this.loginAjax = "/Login/Ajax"; this.init = function () { _this.loginAjax = "/" + $("#CurrentLang").val() + _this.loginAjax; $("#LoginPopup").click(function () { _this.showPopup(_this.loginAjax, initLoginPopup); }); } function initLoginPopup(modal) { $("#LoginButton").click(function () { $.ajax({ type: "POST", url: _this.loginAjax, data : $("#LoginForm").serialize(),
рд╣рдо рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╣реИрдВ:

рдбреЗрдЯрд╛рдмреЗрд╕
рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реБрдП, рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЦрдВрдб рд╕реЗ рдЧреБрдЬрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреНрд░рдХрд╛рд░ рдкреЛрд╕реНрдЯ (рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯ) рдХреА рдПрдХ рд╡рд╕реНрддреБ рд╣реИ, рдЬреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рджреЛ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП:
рдЖрдИрдбреА | рдЕрджреНрд╡рд┐рддреАрдп рд░рд┐рдХреЙрд░реНрдб рд╕рдВрдЦреНрдпрд╛ | |
UserID | рджреНрд╡рд╛рд░рд╛ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ | |
рд╣реИрдбрд░ | рд╣реИрдбрд░ | рдЕрдиреБрд╡рд╛рдж рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ |
рдпреВрдЖрд░рдПрд▓ | рдЙрд░рд▓ рд░рд┐рдХреЙрд░реНрдб | |
рд╕рд╛рдордЧреНрд░реА | рд╕рд╛рдордЧреНрд░реА рдкреЛрд╕реНрдЯ рдХрд░реЗрдВ | рдЕрдиреБрд╡рд╛рдж рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ |
AddedDate | рддрд┐рдерд┐ рдЬреЛрдбрд╝реА рдЧрдИ | |
рддреЛ, рдпрд╣ рд╕рдм рдХреИрд╕реЗ рдЖрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
- рднрд╛рд╖рд╛ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдБ рднрд╛рд╖рд╛рдУрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛
- рдПрдХ рдкреЛрд╕реНрдЯ рдЯреЗрдмрд▓ рдмрдирд╛рдПрдБ рдЬрд╣рд╛рдБ рд╕рднреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рди рд╣реЛ
- рдкреЛрд╕реНрдЯ рдФрд░ рд▓реИрдВрдЧреНрд╡реЗрдЬ рд╕реЗ рдЬреБрдбрд╝реА рдкреЛрд╕реНрдЯрд▓реИрдВрдЧ рдЯреЗрдмрд▓ рдмрдирд╛рдПрдВ, рдЬрд╣рд╛рдВ рд╣рдо рдкреЛрд╕реНрдЯ рдЯреЗрдмрд▓ рдХреЗ рд▓рд┐рдП рдЬрд░реВрд░реА рдлреАрд▓реНрдб рдЯреНрд░рд╛рдВрд╕рд▓реЗрдЯ рдХрд░реЗрдВрдЧреЗ рдФрд░ рд▓реИрдВрдЧреНрд╡реЗрдЬ рдЯреЗрдмрд▓ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реЛрдВрдЧреЗ

рдареАрдХ рд╣реИ, рдЕрдм рдЗрд╕реЗ LessonProject.Model (LessonProject.Model / IRepository.cs) рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
#region Language IQueryable<Language> Languages { get; } bool CreateLanguage(Language instance); bool UpdateLanguage(Language instance); bool RemoveLanguage(int idLanguage); #endregion #region Post IQueryable<Post> Posts { get; } bool CreatePost(Post instance); bool UpdatePost(Post instance); bool RemovePost(int idPost); #endregion
рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рдмрдирд╛рдП рдЧрдП рд╕реНрдирд┐рдкреЗрдЯ / рдкреНрд░реЙрдХреНрд╕рд┐ / рд▓реИрдВрдЧреНрд╡реЗрдЬреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореЙрдбрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ:
namespace LessonProject.Model { public partial class Language { } }
/Proxy/Post.cs:
namespace LessonProject.Model { public partial class Post { } }
/SqlRepository/Language.cs:
public partial class SqlRepository { public IQueryable<Language> Languages { get { return Db.Languages; } } public bool CreateLanguage(Language instance) { if (instance.ID == 0) { Db.Languages.InsertOnSubmit(instance); Db.Languages.Context.SubmitChanges(); return true; } return false; } public bool UpdateLanguage(Language instance) { Language cache = Db.Languages.Where(p => p.ID == instance.ID).FirstOrDefault(); if (cache != null) { cache.Code = instance.Code; cache.Name = instance.Name; Db.Languages.Context.SubmitChanges(); return true; } return false; } public bool RemoveLanguage(int idLanguage) { Language instance = Db.Languages.Where(p => p.ID == idLanguage).FirstOrDefault(); if (instance != null) { Db.Languages.DeleteOnSubmit(instance); Db.Languages.Context.SubmitChanges(); return true; } return false; } }
/SqlRepository/Post.cs:
public partial class SqlRepository { public IQueryable<Post> Posts { get { return Db.Posts; } } public bool CreatePost(Post instance) { if (instance.ID == 0) { Db.Posts.InsertOnSubmit(instance); Db.Posts.Context.SubmitChanges(); return true; } return false; } public bool UpdatePost(Post instance) { Post cache = Db.Posts.Where(p => p.ID == instance.ID).FirstOrDefault(); if (cache != null) {
рддреЛ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреЛрд╕реНрдЯ рдХреНрд▓рд╛рд╕ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ PostLangs рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ, рдЬрд╣рд╛рдВ рд╡рд┐рднрд┐рдиреНрди рдЕрдиреБрд╡рд╛рдж рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдВрдЧреНрд░реЗрдЬреА рдпрд╛ рд░реВрд╕реА рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рд╣реЛ рднреА рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдирд╣реАрдВ рднреАред рд▓реЗрдХрд┐рди рдХрдо рд╕реЗ рдХрдо рдПрдХ рднрд╛рд╖рд╛ рддреЛ рд╣реЛрдиреА рд╣реА рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
- Post (Header, Content) рдХреЗ рд▓рд┐рдП рднрд╛рд╖рд╛ рдХреНрд╖реЗрддреНрд░ рдЬреЛрдбрд╝реЗрдВ
- рдХрд░реЗрдВрдЯрд▓реИрдВрдЧ рдкреНрд░реЙрдкрд░реНрдЯреА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реИрдВ, рдЬрдм рдмрджрд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рднрд╛рд╖рд╛ рдХреНрд╖реЗрддреНрд░ рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
- рдЬрдм рдЖрдк рдкреЛрд╕реНрдЯ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ PostLang рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдмрдирд╛рдИ рдЬрд╛рддреА рд╣реИред
- рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдХреЛрдИ рд░рд┐рдХреЙрд░реНрдб рдмрджрд▓рддреЗ рд╕рдордп, рдпрд╣ рдЬрд╛рдВрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреМрди рд╕реА рднрд╛рд╖рд╛ рдмрджрд▓ рд░рд╣реА рд╣реИ, рдФрд░ рдпрджрд┐ рдРрд╕реА рдХреЛрдИ рднрд╛рд╖рд╛ (рдЕрдиреБрд╡рд╛рдж) рдЕрднреА рддрдХ рдирд╣реАрдВ рд╣реИ, рддреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рдирдпрд╛ рдкреЛрд╕реНрдЯрд▓реИрдВрдЧ рд░рд┐рдХреЙрд░реНрдб рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
рдЖрдЗрдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝реЗрдВ (/Proxy/Post.cs):
public partial class Post { private int _currentLang; public int CurrentLang { get { return _currentLang; } set { _currentLang = value; var currentLang = PostLangs.FirstOrDefault(p => p.LanguageID == value); if (currentLang == null) { IsCorrectLang = false; var anyLang = PostLangs.FirstOrDefault(); if (anyLang != null) { SetLang(anyLang); } } else { IsCorrectLang = true; SetLang(currentLang); } } } private void SetLang(PostLang postLang) { Header = postLang.Header; Content = postLang.Content; } public bool IsCorrectLang { get; protected set; } public string Header { get; set; } public string Content { get; set; } }
рдпрд╣рд╛рдВ рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдЕрдЧрд░ рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХ рдЕрдиреБрд╡рд╛рдж рдирд╣реАрдВ рд╣реИ, рддреЛ рдкрд╣рд▓реЗ рдПрдХ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ IsCorrectLang = false рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЗрддрдирд╛ рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдХрдо рд╕реЗ рдХрдо рдХреБрдЫ рдЬрд╛рдирдХрд╛рд░реА рджрд┐рдЦрд╛рдиреЗ рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИ рдХрд┐ рдХреБрдЫ рднреА рди рджрд┐рдЦрд╛рдПрдВред
рдкреЛрд╕реНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдирд╛ / рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ (/SqlRepository/Post.cs):
public bool CreatePost(Post instance) { if (instance.ID == 0) { instance.AddedDate = DateTime.Now; Db.Posts.InsertOnSubmit(instance); Db.Posts.Context.SubmitChanges(); var lang = Db.Languages.FirstOrDefault(p => p.ID == instance.CurrentLang); if (lang != null) { CreateOrChangePostLang(instance, null, lang); return true; } } return false; } public bool UpdatePost(Post instance) { Post cache = Db.Posts.Where(p => p.ID == instance.ID).FirstOrDefault(); if (cache != null) { cache.Url = instance.Url; Db.Posts.Context.SubmitChanges(); var lang = Db.Languages.FirstOrDefault(p => p.ID == instance.CurrentLang); if (lang != null) { CreateOrChangePostLang(instance, cache, lang); return true; } return true; } return false; } private void CreateOrChangePostLang(Post instance, Post cache, Language lang) { PostLang postLang = null; if (cache != null) { postLang = Db.PostLangs.FirstOrDefault(p => p.PostID == cache.ID && p.LanguageID == lang.ID); } if (postLang == null) { var newPostLang = new PostLang() { PostID = instance.ID, LanguageID = lang.ID, Header = instance.Header, Content = instance.Content, }; Db.PostLangs.InsertOnSubmit(newPostLang); } else { postLang.Header = instance.Header; postLang.Content = instance.Content; } Db.PostLangs.Context.SubmitChanges(); }
рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ CreateOrChangePostLang рдлрд╝рдВрдХреНрд╢рди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
- рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдЖрд╡рд╢реНрдпрдХ рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рднрд╛рд╖рд╛ рдореЗрдВ рдЦреЛрдЬ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рднрд╛рд╖рд╛ рдирд╣реАрдВ рдорд┐рд▓реА рд╣реИ, рддреЛ рдХреЙрд▓ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рд╣рдо рдПрдХ PostLang рдСрдмреНрдЬреЗрдХреНрдЯ (рдпрд╛рдиреА рдЕрдиреБрд╡рд╛рдж) рдирд╣реАрдВ рдмрдирд╛рддреЗ рд╣реИрдВ
- рдпрджрд┐ рд╣рдо рдЖрд╡рд╢реНрдпрдХ рднрд╛рд╖рд╛ рдкрд╛рддреЗ рд╣реИрдВ, рддреЛ CreateOrChangePostLang рдкрд░ рдХреЙрд▓ рдХрд░реЗрдВ:
- рдпрджрд┐ рдХреИрд╢ рд╢реВрдиреНрдп рд╣реИ (рдЕрднреА рддрдХ PostLang рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдпрд╛
- рдпрджрд┐ рдХреИрд╢ рд╢реВрдиреНрдп рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдиреБрд╡рд╛рдж рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ, рддреЛ
- рдЕрдиреБрд╡рд╛рдж рдмрдирд╛рдПрдВ (PostLang рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░ рд▓рд┐рдЦреЗрдВ)
- рдЕрдиреНрдпрдерд╛, рдЬреЛ рдЕрдиреБрд╡рд╛рдж рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЙрд╕реЗ рдмрджрд▓ рджреЗрдВред
рдкреЛрд╕реНрдЯ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЛ рд╣рдЯрд╛рддреЗ рд╕рдордп, рд╕рднреА PostLang рдХреЛ OnDelete = рдХреИрд╕реНрдХреЗрдб рд▓рд┐рдВрдХ рджреНрд╡рд╛рд░рд╛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЗрд╕рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░реЗрдВ)
рдЖрд╡рд╢реНрдпрдХ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдБ рдкрд╣рд▓реЗ рд╣реА рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЬреЛрдбрд╝ рджреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП:
1 | рдЖрд░рдпреВ | рд░реВрд╕реА |
2 | рдПрди | рдЕрдВрдЧреНрд░реЗрдЬреА |
рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ
рдЕрдм, рдпрд╣ рд╕рдм рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдкреИрдирд▓ рдмрдирд╛рдПрдВрдЧреЗред рдХрд╛рд░реНрдп рдпреЛрдЬрдирд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ (рд╣рдо рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рдкрд░рд┐рд╖реНрдХреГрдд рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ рдЖрд╡рд╛рдЬ рджреЗрдВрдЧреЗ):
- рдореЙрдбрд▓ рдмрдирд╛рдПрдВ
- рдЗрдирдкреБрдЯ рднрд╛рд╖рд╛ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕рдВрдмрджреНрдз рдХрд░реЗрдВ (рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдпрд╛ рд╕рдВрдкрд╛рджрдХ рдХрд┐рд╕ рднрд╛рд╖рд╛ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ)
- рднрд╛рд╖рд╛ рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ рдмрдирд╛рдПрдВ
- рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рд╣реЛрдордкреЗрдЬ рдмрдирд╛рдПрдБ
- рдкреЛрд╕реНрдЯ рдХрдВрдЯреНрд░реЛрд▓рд░ рдмрдирд╛рдПрдВ
- рдбрд┐рдлрд╝реЙрд▓реНрдЯ / рдкреЛрд╕реНрдЯрдХрдВрдЯреНрд░реЛрд▓рд░ рднрд╛рдЧ рдореЗрдВ рд╕реВрдЪреА рдкреЛрд╕реНрдЯ рдХрд░реЗрдВ
рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рднрд╛рд╖рд╛:

IRepository.cs рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
bool ChangeLanguage(User instance, string LangCode);
рд╣рдо /SqlRepository/User.cs рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:
public bool ChangeLanguage(User instance, string LangCode) { var cache = Db.Users.FirstOrDefault(p => p.ID == instance.ID); var newLang = Db.Languages.FirstOrDefault(p => p.Code == LangCode); if (cache != null && newLang != null) { cache.Language = newLang; Db.Users.Context.SubmitChanges(); return true; } return false; }
рдореЙрдбрд▓ рдмрдирд╛рдПрдБ / рдореЙрдбрд▓ / рджреГрд╢реНрдп / рдореЙрдбрд▓ / рдкреЛрд╕реНрдЯ рджреГрд╢реНрдп:
public class PostView { public int ID { get; set; } public int UserID { get; set; } public bool IsCorrectLang { get; set; } public int CurrentLang { get; set; } [Required(ErrorMessage = " ")] public string Header { get; set; } [Required] public string Url { get; set; } [Required(ErrorMessage = " ")] public string Content { get; set; } }
рдорд╛рдиреНрдпрддрд╛ рд▓рд╛рдЗрдиреЛрдВ рдХреЛ GlobalRes рдореЗрдВ рдбрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣рд╛рдВ рд╣рдо рдХреЗрд╡рд▓ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдкреИрдирд▓ рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХреЛрдИ рдлрд╛рдпрджрд╛ рдирд╣реАрдВ рд╣реИ (рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рд╢рд╛рд╕рдХ рдорд╛рдореВрд▓реА рд▓реЛрдЧ рд╣реИрдВ)ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЕрдиреНрдп рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдкрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИред
/Areas/Admin/Controller/AdminController.cs рдмрдирд╛рдПрдБ:
public abstract class AdminController : BaseController { public Language CurrentLang { get { return CurrentUser != null ? CurrentUser.Language : null; } } protected override void Initialize(RequestContext requestContext) { CultureInfo ci = new CultureInfo("ru"); Thread.CurrentThread.CurrentCulture = ci; base.Initialize(requestContext); } }
рдФрд░ /Areas/Admin/Controller/HomeController.cs:
[Authorize(Roles="admin")] public class HomeController : AdminController { public ActionResult Index() { return View(); } public ActionResult AdminMenu() { return View(); } public ActionResult LangMenu() { if (CurrentLang == null) { var lang = repository.Languages.FirstOrDefault(); repository.ChangeLanguage(currentUser, lang.Code); } var langProxy = new LangAdminView(repository, CurrentLang.Code); return View(langProxy); } [HttpPost] public ActionResult ChangeLanguage(string SelectedLang) { repository.ChangeLanguage(currentUser, SelectedLang); return Redirect("~/admin"); } }
рдЗрд╕рд▓рд┐рдП, AdminController рдЪрдпрди рдФрд░ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдХрд┐рд╕ рднрд╛рд╖рд╛ рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдпрджрд┐ рдпрд╣ рднрд╛рд╖рд╛ рд╕реНрдерд╛рдкрд┐рдд рдирд╣реАрдВ рд╣реИ, рддреЛ рдкрд╣рд▓реЗ рд╡рд╛рд▓рд╛ рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ HomeController.cs рдореЗрдВ: LangMenu рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред LangAdminView.cs (/Models/ViewModel/LangAdminView.cs) рдмрдирд╛рдПрдВ:
public class LangAdminView { private IRepository Repository { get { return DependencyResolver.Current.GetService<IRepository>(); } } public string SelectedLang {get; set; } public List<SelectListItem> Langs { get; set; } public LangAdminView(string currentLang) { currentLang = currentLang ?? ""; Langs = new List<SelectListItem>(); foreach (var lang in Repository.Languages) { Langs.Add(new SelectListItem() { Selected = (string.Compare(currentLang, lang.Code, true) == 0), Value = lang.Code, Text = lang.Name }); } } }
рдЖрдЗрдП рджреЗрдЦреЗрдВ рд╕рднреА рд╡рд┐рд╡рд░рдг (+ js рдлрд╛рдЗрд▓реЗрдВ):
/Areas/Admin/Views/Shared/_Layout.cshtml:
@{ var currentUser = ((LessonProject.Controllers.BaseController)ViewContext.Controller).CurrentUser; } <!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> @Styles.Render("~/Content/css/jqueryui") @Styles.Render("~/Content/css") @RenderSection("styles", required: false) @Scripts.Render("~/bundles/modernizr") </head> <body> <div class="navbar navbar-fixed-top"> <div class="navbar-inner"> <div class="container-fluid"> <div class="btn-group pull-right"> <a class="btn dropdown-toggle" data-toggle="dropdown" href="#"><i class="icon-user"> </i> @currentUser.Email<span class="caret"></span> </a> <ul class="dropdown-menu"> <li><a href="/"> </a></li> <li class="divider"></li> <li><a href="@Url.Action("Logout", "Login", new { area = "Default" })"></a> </li> </ul> </div> <a class="brand" href="@Url.Action("Index", "Home")">LessonProject</a> </div> </div> </div> <div class="container-fluid"> <div class="row-fluid"> <div class="span3"> <div class="well sidebar-nav"> <ul class="nav nav-list"> @Html.Action("LangMenu", "Home") @Html.Action("AdminMenu", "Home") </ul> </div> </div> <div class="span9"> @RenderBody() </div> </div> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/jqueryui") @Scripts.Render("~/bundles/bootstrap") @Scripts.Render("~/bundles/common") @Scripts.Render("/Scripts/admin/common.js") @RenderSection("scripts", required: false) </body> </html>
Index.cshtml (/Areas/Admin/Views/Home/Index.cshtml):
@{ ViewBag.Title = "Index"; Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml"; } <h2></h2> AdminMenu.cshtml (/Areas/Admin/Views/Home/AdminMenu.cshtml): <li> @Html.ActionLink("", "Index", "Home") </li> <li> @Html.ActionLink("", "Index", "Post") </li>
LangMenu.cshtml (/Areas/Admin/Views/Home/LangMenu.cshtml:
@model LessonProject.Models.ViewModels.LangAdminView <li> @using (Html.BeginForm("ChangeLanguage", "Home", FormMethod.Post, new { id = "SelectLangForm" })) { @Html.DropDownList("SelectedLang", Model.Langs) } </li>
рдФрд░ рд╕реЗрд▓реЗрдиреНрдЧрд▓реИрдВрдЧ рд╣реИрдВрдбрд▓рд░ (/ рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕ / рдПрдбрдорд┐рди / рдПрдмреНрдиреЙрд░реНрдорд▓):
function AdminCommon() { _this = this; this.init = function () { $("#SelectedLang").change(function () { $("#SelectLangForm").submit(); }); } } var adminCommon = null; $().ready(function () { adminCommon = new AdminCommon(); adminCommon.init(); });
рд╣рдо рдкреНрд░рд╢рд╛рд╕рдХ рдХреЗ рдкрд╛рд╕ рдЬрд╛рддреЗ рд╣реИрдВ (рдореЗрд░реЗ рдкрд╛рд╕ chernikov@gmail.com рд╣реИ) рдФрд░
рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ / рдПрдбрдорд┐рди рдкреЗрдЬ рдкрд░ рдЬрд╛рдПрдБ:
рдпрджрд┐ рдЗрд╕реЗ рд▓реЙрдЧ рдЗрди рдХрд░рдирд╛ / рд▓реЙрдЧрд┐рди рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рдерд╛, рддреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ UserRole рдХрдиреЗрдХреНрд╢рди рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВ, рддрд╛рдХрд┐ рд╡рд░реНрддрдорд╛рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА "рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ" рдХреЛрдб рдХреЗ рд╕рд╛рде рдПрдХ рднреВрдорд┐рдХрд╛ рд╣реЛредрднрд╛рд╖рд╛рдУрдВ рдХреА рдбреНрд░реЙрдк-рдбрд╛рдЙрди рд╕реВрдЪреА рдЦреЛрд▓реЗрдВред рдпрд╣ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╣рдо рдХрд┐рд╕ рднрд╛рд╖рд╛ рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред
PostController.cs рдХрдВрдЯреНрд░реЛрд▓рд░ рдЬреЛрдбрд╝реЗрдВ (/Areas/Admin/Controllers/PostController.cs):
public class PostController : AdminController { public ActionResult Index(int page = 1) { var list = Repository.Posts.OrderByDescending(p => p.AddedDate); var data = new PageableData<Post>(list, page); data.List.ForEach(p => p.CurrentLang = CurrentLang.ID); return View(data); } [HttpGet] public ActionResult Create() { var postView = new PostView { CurrentLang = CurrentLang.ID }; return View("Edit", postView); } [HttpGet] public ActionResult Edit(int id) { var post = Repository.Posts.FirstOrDefault(p => p.ID == id); if (post != null) { post.CurrentLang = CurrentLang.ID; var postView = (PostView)ModelMapper.Map(post, typeof(Post), typeof(PostView)); return View(postView); } return RedirectToNotFoundPage; } [HttpPost] [ValidateInput(false)] public ActionResult Edit(PostView postView) { if (ModelState.IsValid) { var post = (Post)ModelMapper.Map(postView, typeof(PostView), typeof(Post)); post.CurrentLang = CurrentLang.ID; if (post.ID == 0) { post.UserID = CurrentUser.ID; Repository.CreatePost(post); } else { Repository.UpdatePost(post); } TempData["Message"] = "!"; return RedirectToAction("Index"); } return View(postView); } public ActionResult Delete(int id) { Repository.RemovePost(id); TempData["Message"] = " "; return RedirectToAction("Index"); } }
PageableData рдХреЛ рдмрджрд▓реЗрдВ рддрд╛рдХрд┐ рдЖрдк Foreach (/Models/Info/PageableData.cs) рдмрдирд╛ рд╕рдХреЗрдВ:
public class PageableData<T> where T : class { protected static int ItemPerPageDefault = 20; public List<T> List { get; set; } тАж public PageableData(IQueryable<T> queryableSet, int page, int itemPerPage = 0) { тАж List = queryableSet.Skip((PageNo - 1) * itemPerPage).Take(itemPerPage).ToList(); } }
Index.cshtml (/Areas/Admin/Views/Post/Index.cshtml):
@model LessonProject.Models.Info.PageableData<LessonProject.Model.Post> @{ ViewBag.Title = ""; Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml"; } <h2> </h2> @Html.ActionLink("", "Create", "Post", null, new { @class = "btn" }) <table class="table"> <thead> <tr> <th> # </th> <th> </th> <th> </th> <th> </th> </tr> </thead> @foreach (var item in Model.List) { <tr> <td> @item.ID </td> <td> @(item.IsCorrectLang ? "" : " ") </td> <td> @item.Header </td> <td> @Html.ActionLink("", "Edit", "Post", new { id = item.ID }, new { @class = "btn btn-mini" }) @Html.ActionLink("", "Delete", "Post", new { id = item.ID }, new { @class = "btn btn-mini btn-danger" }) </td> </tr> } </table>
ForEach рдореЗрдВ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддреЗ рд╕рдордп, рднрд╛рд╖рд╛ рдХреНрд╖реЗрддреНрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рддреНрдпреЗрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рднрд╛рд╖рд╛ - рд╡рд╣ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдкреИрдирд▓ рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред
рд╕рдВрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рджреГрд╢реНрдп рддреБрдЪреНрдЫ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ рд╕рднреА рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╣рдорд╛рд░рд╛ рдкреЛрд╕реНрдЯ рд╡реНрдпреВ рдкрд╣рд▓реЗ рд╣реА рднрд╛рд╖рд╛ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред (/Areas/Admin/Views/Post/Edit.cshtml):
@model LessonProject.Models.ViewModels.PostView @{ ViewBag.Title = Model.ID == 0 ? " " : " "; Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml"; } <h2>@(Model.ID == 0 ? " " : " ")</h2> <p> </p> @using (Html.BeginForm("Edit", "Post", FormMethod.Post)) { @Html.Hidden("ID", Model.ID) <fieldset> <div class="control-group"> <label class="control-label"> @(!Model.IsCorrectLang && Model.ID != 0 ? " " : "") </label> </div> <div class="control-group"> <label class="control-label"> </label> <div class="controls"> @Html.TextBox("Header", Model.Header, new { @class = "input-xlarge" }) @Html.ValidationMessage("Header") </div> </div> <div class="control-group"> <label class="control-label"> Url</label> <div class="controls"> @Html.TextBox("Url", Model.Url, new { @class = "input-xlarge" }) @Html.ValidationMessage("Url") </div> </div> <div class="control-group"> <label class="control-label"> </label> <div class="controls"> @Html.TextArea("Content", Model.Content, new { @class = "input-xlarge" }) @Html.ValidationMessage("Content") </div> </div> <div class="form-actions"> <button type="submit" class="btn btn-primary"> </button> @Html.ActionLink("", "Index", null, null, new { @class = "btn" }) </div> </fieldset> }
рдЕрдиреБрд╡рд╛рдж рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рдВрдХреЗрдд рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЦреЗрддреЛрдВ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рднрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЕрдиреБрд╡рд╛рджрд┐рдд рдФрд░ рд╕рд╣реЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рдЕрдиреБрд╡рд╛рдж рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред
рдХреБрдЫ рдкреЛрд╕реНрдЯ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЙрдирдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдВ:

рдареАрдХ рд╣реИ, рдкреЛрд╕реНрдЯ рдмрдирд╛рдП рдЧрдП
рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдПрдХ рдкреЛрд╕реНрдЯрдХрдВрдЯреНрд░реЛрд▓рд░ рдмрдирд╛рдПрдБ рдФрд░ рдкрджреЛрдВ (/Areas/Default/Controller/PostController.cs) рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ:
public class PostController : DefaultController { public ActionResult Index(int page = 1) { var list = Repository.Posts.OrderByDescending(p => p.AddedDate); var data = new PageableData<Post>(list, page); data.List.ForEach(p => p.CurrentLang = CurrentLang.ID); return View(data); } }
Index.cshtml (/Areas/Default/Views/Post/Index.cshtml):
@model LessonProject.Models.Info.PageableData<LessonProject.Model.Post> @{ ViewBag.Title = "Index"; Layout = "~/Areas/Default/Views/Shared/_Layout.cshtml"; } <div class="item"> @foreach (var post in Model.List) { <h3>@post.Header</h3> <p> @post.Content.NlToBr() </p> <span>@post.AddedDate.ToString("d")</span> } </div> <div class="pagination"> @Html.PageLinks(Model.PageNo, Model.CountPage, x => Url.Action("Index", new {page = x})) </div>
рдФрд░ рдЬрд╛рдВрдЪреЗрдВ:

рд╕реБрдкрд░!
рднрд╛рд╖рд╛рдУрдВ рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдВ
рдЪрд▓реЛ рдЧреНрд░рд╛рд╣рдХ рднрд╛рдЧ рдореЗрдВ рдЖрд░рдпреВ / рдПрди рд╕реНрд╡рд┐рдЪ рдмрдирд╛рддреЗ рд╣реИрдВред LangHelper.cs рд╡рд░реНрдЧ (/Helper/LangHelper.cs) рдЬреЛрдбрд╝реЗрдВ:
public static class LangHelper { public static MvcHtmlString LangSwitcher(this UrlHelper url, string Name, RouteData routeData, string lang) { var liTagBuilder = new TagBuilder("li"); var aTagBuilder = new TagBuilder("a"); var routeValueDictionary = new RouteValueDictionary(routeData.Values); if (routeValueDictionary.ContainsKey("lang")) { if (routeData.Values["lang"] as string == lang) { liTagBuilder.AddCssClass("active"); } else { routeValueDictionary["lang"] = lang; } } aTagBuilder.MergeAttribute("href", url.RouteUrl(routeValueDictionary)); aTagBuilder.SetInnerText(Name); liTagBuilder.InnerHtml = aTagBuilder.ToString(); return new MvcHtmlString(liTagBuilder.ToString()); } }
рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ _Layout.cshtml (/Areas/Default/Views/Saring/_Layout.cshtml) рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
<
div class="container"> <ul class="nav nav-pills pull-right"> @Html.Partial("LangMenu") </ul>
+ LangMenu.cshtml:
@Url.LangSwitcher("en", ViewContext.RouteData, "en") @Url.LangSwitcher("ru", ViewContext.RouteData, "ru")
рд╣рдо рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рджреЗрдЦрд╛! рд╕реМрдВрджрд░реНрдпред

рдЧрд▓рдд рдкреНрд░рд╛рд░реВрдк, рд░реВрд╕реА рдореЗрдВ рдЕрдиреБрд╡рд╛рдж
рдХрднреА-рдХрднреА, рдЬрдм рд╣рдо рдЕрдкреЗрдХреНрд╖рд┐рдд рд╕рдВрдЦреНрдпрд╛ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдПрдХ рдкрд╛рда рдорд╛рди рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
The value 'one hundred dollars' is not valid for Price.
рд▓реЗрдХрд┐рди рдЗрд╕ рд╕рдВрджреЗрд╢ рдХреЛ рд░реВрд╕реА рдореЗрдВ рдХреИрд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрджрдо рдЖрдкрдХреЛ рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗ:
- App_GlobalResources рдлрд╝реЛрд▓реНрдбрд░ рдЬреЛрдбрд╝реЗрдВ
- Message.resx рд╕рдВрд╕рд╛рдзрди рдЬреЛрдбрд╝реЗрдВ
- рдкрдВрдХреНрддрд┐ рдЬреЛрдбрд╝реЗрдВ "PropertyValueInvalid: рдорд╛рди {0} рдлрд╝реАрд▓реНрдб {1} рдХреЗ рд▓рд┐рдП рдорд╛рдиреНрдп рдирд╣реАрдВ рд╣реИ "
- App_Start рдореЗрдВ, Application_Start () (/Global.asax.cs) рдкрд░ рдПрдХ рдкрдВрдХреНрддрд┐ рдЬреЛрдбрд╝реЗрдВ
- DefaultModelBinder.ResourceClassKey = "рд╕рдВрджреЗрд╢";
- рдлрд╝реАрд▓реНрдб рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рдкреНрд░рджрд░реНрд╢рди [рдирд╛рдо = "рдореВрд▓реНрдп"] рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
- рд╣рдореЗрдВ рдЗрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓рддрд╛ рд╣реИ:

рдкрд░рд┐рдгрд╛рдо
рдПрдХ рдмрд╣реБрднрд╛рд╖реА рд╕рд╛рдЗрдЯ рдореЗрдВ рдХрд╛рдо рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
- рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХреЗ рддрд╛рд░ рдЕрд▓рдЧ
- рдбреЗрдЯрд╛рдмреЗрд╕ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдореЗрдВ рднрд╛рд╖рд╛ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рднрд╛рд╖рд╛ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓рд┐рдВрдХ рдХрд░реЗрдВ
- рднрд╛рд╖рд╛ рд╕рдорд░реНрдерди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ ajax рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
рдЕрдВрдд рдореЗрдВ, рдореИрдВ рдпрд╣ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдмрд╣реБрднрд╛рд╖реА рд╕рд╛рдЗрдЯ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рдирд╣реАрдВ рд╣реИ, рдЕрдЧрд░ рдЧреНрд░рд╛рд╣рдХ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд╣рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдЕрд╡рд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдмрд╣реБрднрд╛рд╖рд╛рд╡рд╛рдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд╛рдЗрдЯ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╢реБрд░реВ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдХрдо рд╕реЗ рдХрдо рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реНрддрд░ рдкрд░ред
рд╕рднреА рд╕реНрд░реЛрдд
https://bitbucket.org/chernikov/lessons рдкрд░ рд╕реНрдерд┐рдд рд╣реИрдВ