asp.net mvc - एक एएसपी.NET एमवीसी ऐप में संस्कृति सेट करें




asp.net-mvc localization (6)

1: एक कस्टम विशेषता बनाएं और इस तरह की ओवरराइड विधि बनाएं:

public class CultureAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
    // Retreive culture from GET
    string currentCulture = filterContext.HttpContext.Request.QueryString["culture"];

    // Also, you can retreive culture from Cookie like this :
    //string currentCulture = filterContext.HttpContext.Request.Cookies["cookie"].Value;

    // Set culture
    Thread.CurrentThread.CurrentCulture = new CultureInfo(currentCulture);
    Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(currentCulture);
    }
}

2: App_Start में, FilterConfig.cs ढूंढें, यह विशेषता जोड़ें। (यह WHOLE आवेदन के लिए काम करता है)

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
    // Add custom attribute here
    filters.Add(new CultureAttribute());
    }
}    

बस !

यदि आप पूरे आवेदन के दौरान प्रत्येक नियंत्रक / कार्रवाई के लिए संस्कृति को परिभाषित करना चाहते हैं, तो आप इस विशेषता का उपयोग इस प्रकार कर सकते हैं:

[Culture]
public class StudentsController : Controller
{
}

या:

[Culture]
public ActionResult Index()
{
    return View();
}

एक एएसपीनेट एमवीसी ऐप में संस्कृति / यूआई संस्कृति को स्थापित करने के लिए सबसे अच्छी जगह क्या है

वर्तमान में मेरे पास एक संस्कृति नियंत्रक वर्ग है जो इस तरह दिखता है:

public class CultureController : Controller
{
    public ActionResult SetSpanishCulture()
    {
        HttpContext.Session["culture"] = "es-ES";
        return RedirectToAction("Index", "Home");
    }

    public ActionResult SetFrenchCulture()
    {
        HttpContext.Session["culture"] = "fr-FR";
        return RedirectToAction("Index", "Home");
    }
}

और इस तरह के लिंक के साथ होमपेज पर प्रत्येक भाषा के लिए एक हाइपरलिंक:

<li><%= Html.ActionLink("French", "SetFrenchCulture", "Culture")%></li>
<li><%= Html.ActionLink("Spanish", "SetSpanishCulture", "Culture")%></li>

जो ठीक काम करता है लेकिन मुझे लगता है कि ऐसा करने का एक और उचित तरीका है।

मैं निम्नलिखित एक्शनफिल्टर का उपयोग कर संस्कृति पढ़ रहा हूं http://www.iansuttle.com/blog/post/ASPNET-MVC-Action-Filter-for-Localized-Sites.aspx । मैं एक एमवीसी नोब का थोड़ा सा हूं इसलिए मुझे विश्वास नहीं है कि मैं इसे सही जगह पर स्थापित कर रहा हूं। मैं इसे web.config स्तर पर नहीं करना चाहता, इसे उपयोगकर्ता की पसंद पर आधारित होना चाहिए। मैं अपनी ब्राउज़र सेटिंग्स से संस्कृति प्राप्त करने के लिए अपने http-headers को भी देखना नहीं चाहता हूं।

संपादित करें:

बस स्पष्ट होने के लिए - मैं यह तय करने की कोशिश नहीं कर रहा हूं कि सत्र का उपयोग करना है या नहीं। मैं उस बिट से खुश हूं। जो मैं काम करने की कोशिश कर रहा हूं वह यह है कि यदि संस्कृति संस्कृति में ऐसा करना सर्वोत्तम होता है जिसमें प्रत्येक संस्कृति को सेट करने के लिए एक क्रिया विधि है, या क्या ऐसा करने के लिए एमवीसी पाइपलाइन में एक बेहतर जगह है?


आपका प्रश्न सबसे अच्छा स्थान क्या है। सबसे अच्छी जगह Controller.Initialize अंदर है। विधि शुरू करें। एमएसडीएन लिखता है कि इसे कन्स्ट्रक्टर के बाद और एक्शन विधि से पहले कहा जाता है। OnActionExecuting को ओवरराइड करने के विपरीत, आरंभिक विधि में अपना कोड डालने से आपको अपनी कक्षाओं और अपनी संपत्तियों पर स्थानीयकृत होने के लिए सभी कस्टम डेटा एनोटेशन और विशेषता होने का लाभ मिल सकता है।

उदाहरण के लिए, मेरा स्थानीयकरण तर्क उस वर्ग से आता है जो मेरे कस्टम नियंत्रक से इंजेक्शन दिया जाता है। मेरे पास इस ऑब्जेक्ट तक पहुंच है क्योंकि प्रारंभकर्ता को कन्स्ट्रक्टर के बाद बुलाया जाता है। मैं थ्रेड की संस्कृति असाइनमेंट कर सकता हूं और हर त्रुटि संदेश सही तरीके से प्रदर्शित नहीं कर सकता।

 public BaseController(IRunningContext runningContext){/*...*/}

 protected override void Initialize(RequestContext requestContext)
 {
     base.Initialize(requestContext);
     var culture = runningContext.GetCulture();
     Thread.CurrentThread.CurrentUICulture = culture;
     Thread.CurrentThread.CurrentCulture = culture;
 }

यहां तक ​​कि यदि आपका तर्क किसी वर्ग के अंदर नहीं है जैसा कि मैंने प्रदान किया है, तो आपके पास RequestContext तक पहुंच है जो आपको यूआरएल और एचटीपी कॉन्टेक्स्ट और रूटडेटा की अनुमति देता है जो आप मूल रूप से किसी भी पार्सिंग को संभवतः कर सकते हैं।


मुझे पता है कि यह एक पुराना सवाल है, लेकिन यदि आप वास्तव में यह अपने DefaultModelBinder.ResourceClassKey = "MyResource"; साथ काम करना चाहते हैं ( DefaultModelBinder.ResourceClassKey = "MyResource"; संबंध में DefaultModelBinder.ResourceClassKey = "MyResource"; साथ ही DefaultModelBinder.ResourceClassKey = "MyResource"; कक्षाओं के डेटा एनोटेशन में संकेतित संसाधन), कंट्रोलर या यहां तक ​​कि ActionFilter संस्कृति को स्थापित करने में बहुत देर हो चुकी है

संस्कृति को Application_AcquireRequestState में सेट किया जा सकता है, उदाहरण के लिए:

protected void Application_AcquireRequestState(object sender, EventArgs e)
    {
        // For example a cookie, but better extract it from the url
        string culture = HttpContext.Current.Request.Cookies["culture"].Value;

        Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(culture);
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
    }

संपादित करें

असल में कस्टम रूटरहेंडलर का उपयोग करने का एक बेहतर तरीका है जो यूआरएल के अनुसार संस्कृति को सेट करता है, जो पूरी तरह से एलेक्स एडमैन द्वारा उनके ब्लॉग पर वर्णित है।

सभी को GetHttpHandler विधि को ओवरराइड करना है और वहां संस्कृति सेट करना है।

public class MultiCultureMvcRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        // get culture from route data
        var culture = requestContext.RouteData.Values["culture"].ToString();
        var ci = new CultureInfo(culture);
        Thread.CurrentThread.CurrentUICulture = ci;
        Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
        return base.GetHttpHandler(requestContext);
    }
}

मैं इस स्थानीयकरण विधि का उपयोग कर रहा हूं और एक रूट पैरामीटर जोड़ा जो संस्कृति और भाषा को सेट करता है जब भी कोई उपयोगकर्ता example.com/xx-xx/ पर जाता है

उदाहरण:

routes.MapRoute("DefaultLocalized",
            "{language}-{culture}/{controller}/{action}/{id}",
            new
            {
                controller = "Home",
                action = "Index",
                id = "",
                language = "nl",
                culture = "NL"
            });

मेरे पास एक फ़िल्टर है जो वास्तविक संस्कृति / भाषा सेटिंग करता है:

using System.Globalization;
using System.Threading;
using System.Web.Mvc;

public class InternationalizationAttribute : ActionFilterAttribute {

    public override void OnActionExecuting(ActionExecutingContext filterContext) {

        string language = (string)filterContext.RouteData.Values["language"] ?? "nl";
        string culture = (string)filterContext.RouteData.Values["culture"] ?? "NL";

        Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture));
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture));

    }
}

अंतर्राष्ट्रीयकरण विशेषता को सक्रिय करने के लिए, बस इसे अपनी कक्षा में जोड़ें:

[Internationalization]
public class HomeController : Controller {
...

अब जब भी कोई विज़िटर http://example.com/de-DE/Home/Index जाता है तो जर्मन साइट प्रदर्शित होती है।

मुझे आशा है कि यह उत्तर आपको सही दिशा में इंगित करेंगे।

मैंने एक छोटा एमवीसी 5 उदाहरण प्रोजेक्ट भी बनाया जो आप here पा सकते हैं

अंग्रेजी (यूएस) में वर्तमान दिनांक देखने के लिए बस http: // {yourhost}: {port} / en-us / home / index पर जाएं, या इसे http: // {yourhost}: {port} / de में बदलें जर्मन आदि के लिए -de / home / index।


यदि सबडोमेन का उपयोग करना है, उदाहरण के लिए उदाहरण के लिए पुर्तगाली सेट करने के लिए "pt.mydomain.com" जैसे, Application_AcquireRequestState का उपयोग नहीं किया जाएगा, क्योंकि इसे बाद के कैश अनुरोधों पर नहीं कहा जाता है।

इसे हल करने के लिए, मैं इस तरह के कार्यान्वयन का सुझाव देता हूं:

  1. इस तरह OutPutCache में VaryByCustom पैरामीटर जोड़ें:

    [OutputCache(Duration = 10000, VaryByCustom = "lang")]
    public ActionResult Contact()
    {
        return View("Contact");
    }
    
  2. Global.asax.cs में, फ़ंक्शन कॉल का उपयोग करके मेजबान से संस्कृति प्राप्त करें:

    protected void Application_AcquireRequestState(object sender, EventArgs e)
    {
        System.Threading.Thread.CurrentThread.CurrentUICulture = GetCultureFromHost();
    }
    
  3. GetCultureFromHost फ़ंक्शन को global.asax.cs में जोड़ें:

    private CultureInfo GetCultureFromHost()
    {
        CultureInfo ci = new CultureInfo("en-US"); // en-US
        string host = Request.Url.Host.ToLower();
        if (host.Equals("mydomain.com"))
        {
            ci = new CultureInfo("en-US");
        }
        else if (host.StartsWith("pt."))
        {
            ci = new CultureInfo("pt");
        }
        else if (host.StartsWith("de."))
        {
            ci = new CultureInfo("de");
        }
        else if (host.StartsWith("da."))
        {
            ci = new CultureInfo("da");
        }
    
        return ci;
    }
    
  4. और आखिरकार GetVaryByCustomString (...) को इस फ़ंक्शन का उपयोग करने के लिए ओवरराइड करें:

    public override string GetVaryByCustomString(HttpContext context, string value)
    {
        if (value.ToLower() == "lang")
        {
            CultureInfo ci = GetCultureFromHost();
            return ci.Name;
        }
        return base.GetVaryByCustomString(context, value);
    }
    

फ़ंक्शन Application_AququireRequestState को गैर-कैश किए गए कॉल पर कॉल किया जाता है, जो सामग्री को जेनरेट और कैश करने की अनुमति देता है। GetVaryByCustomString को कैश में सामग्री उपलब्ध है या नहीं, यह जांचने के लिए कैश किए गए कॉल पर कॉल किया जाता है, और इस मामले में हम वर्तमान संस्कृति जानकारी पर भरोसा करने के बजाय आने वाले होस्ट डोमेन मान की फिर से जांच करते हैं, जो नए अनुरोध के लिए बदल सकता था (क्योंकि हम सबडोमेन का उपयोग कर रहे हैं)।


protected void Application_AcquireRequestState(object sender, EventArgs e)
        {
            if(Context.Session!= null)
            Thread.CurrentThread.CurrentCulture =
                    Thread.CurrentThread.CurrentUICulture = (Context.Session["culture"] ?? (Context.Session["culture"] = new CultureInfo("pt-BR"))) as CultureInfo;
        }




culture