संसाधन से DisplayName विशेषता?


160

मेरे पास एक स्थानीयकृत एप्लिकेशन है, और मैं सोच रहा हूं कि क्या DisplayNameएक संसाधन से एक निश्चित मॉडल संपत्ति के लिए संभव है ।

मैं ऐसा कुछ करना चाहता हूं:

public class MyModel {
  [Required]
  [DisplayName(Resources.Resources.labelForName)]
  public string name{ get; set; }
}

लेकिन मैं ऐसा नहीं कर सकता, जैसा कि कंपाइलर कहता है: "एक एट्रिब्यूट तर्क एक स्थिर अभिव्यक्ति होना चाहिए, टाइपो एक्सप्रेशन या एंसेरिटी एंप्लायमेंट एक्सप्रेशन ऑफ़ ए टाइप पैरामीटर" :(

क्या कोई वर्कअराउंड हैं? मैं मैन्युअल रूप से लेबल आउटपुट कर रहा हूं, लेकिन मुझे सत्यापनकर्ता आउटपुट के लिए इनकी आवश्यकता है!

जवाबों:


112

कैसे एक कस्टम विशेषता लिखने के बारे में:

public class LocalizedDisplayNameAttribute: DisplayNameAttribute
{
    public LocalizedDisplayNameAttribute(string resourceId) 
        : base(GetMessageFromResource(resourceId))
    { }

    private static string GetMessageFromResource(string resourceId)
    {
        // TODO: Return the string from the resource file
    }
}

जो इस तरह इस्तेमाल किया जा सकता है:

public class MyModel 
{
    [Required]
    [LocalizedDisplayName("labelForName")]
    public string Name { get; set; }
}

हां, मैंने आज सुबह एक समान समाधान पर काम किया और यह संभव है। : तब मैं इस पोस्ट जो एक ही दृष्टिकोण है पाया adamyan.blogspot.com/2010/02/...
Palantir

23
@ अपनी पोस्ट, इस एक के नीचे (सबसे अधिक वोटों के साथ), एक बहुत अच्छा समाधान है। सिर्फ उन लोगों के लिए जो केवल स्वीकृत पदों को पढ़ते हैं
321X

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

5
TODO के लिए सुझाव: वापसी Resources.Language.ResourceManager.GetString (resourceId);
लियोनेल सांचे दा सिल्वा

4
आपको निम्न का उपयोग करना चाहिए: [प्रदर्शन (नाम = "लेबलफ़ोरनाम", रिसोर्सटाइप = टाइपोफ़ (रिसोर्सस रिसोर्स))] जैसा कि नीचे वर्णित है ...
फ्रैंक बाउचर

375

यदि आप MVC 3 और .NET 4 का उपयोग करते हैं, तो आप नामस्थान Displayमें नई विशेषता का उपयोग कर सकते हैं System.ComponentModel.DataAnnotations। यह विशेषता विशेषता को प्रतिस्थापित करती DisplayNameहै और स्थानीयकरण समर्थन सहित बहुत अधिक कार्यक्षमता प्रदान करती है।

आपके मामले में, आप इसे इस तरह उपयोग करेंगे:

public class MyModel
{
    [Required]
    [Display(Name = "labelForName", ResourceType = typeof(Resources.Resources))]
    public string name{ get; set; }
}

साइड नोट के रूप में, यह विशेषता अंदर App_GlobalResourcesया संसाधनों के साथ काम नहीं करेगी App_LocalResources। यह कस्टम उपकरण ( GlobalResourceProxyGenerator) के साथ करना है जो इन संसाधनों का उपयोग करते हैं। इसके बजाय सुनिश्चित करें कि आपकी संसाधन फ़ाइल 'एंबेडेड संसाधन' पर सेट है और 'ResXFileCodeGenerator' कस्टम टूल का उपयोग करें।

(एक और साइड नोट के रूप में, आपको एमवीसी के साथ App_GlobalResourcesया इसका उपयोग नहीं करना चाहिए App_LocalResources। आप इस बारे में अधिक पढ़ सकते हैं कि यहां ऐसा क्यों है )


यह यहाँ उपयोग किए गए विशिष्ट उदाहरण के लिए अच्छा है, लेकिन यह गतिशील संपत्ति के अधिकांश लोगों के लिए काम नहीं करेगा जो तार चाहते हैं।
१६:

1
यह अच्छा है जब हमारे पास उत्पादन को तैनात करने से पहले हमारे साथ हमारे सभी स्थान हैं। लेकिन अगर मैं db स्ट्रिंग्स के लिए db को कॉल करना चाहता हूं तो इस तरह का दृष्टिकोण उचित नहीं है। इसके अलावा संसाधन फ़ाइल का नुकसान, यह है कि परिवर्तनों को प्रभावित करने के लिए फिर से संकलन की आवश्यकता होती है, इसका मतलब है कि आपको क्लाइंट को एक और संस्करण जारी करने की आवश्यकता है। मैं इसे एक बुरे दृष्टिकोण के रूप में नहीं कह रहा हूं, कृपया ऐसा महसूस न करें
kbvishnu

बस एक समस्या: हमें मॉडल में संसाधन प्रकार जानना होगा। मेरे पास एक मॉडल डीएलएल और दो अलग-अलग परियोजनाओं में एक वेबसाइट है। मैं मॉडल में प्रदर्शन नाम सेट करने और वेबसाइट में संसाधन प्रकार सेट करने में सक्षम होना चाहता हूं ...
Kek

1
Resharper प्राप्त करें, और अपनी परियोजना में संसाधन फ़ाइल बनाएँ, और यह स्वचालित रूप से याद दिलाएगा और फिर नाम को संसाधन फ़ाइल में ले जाने में आपकी सहायता करेगा।
एआईबीएम

14
सी # 6 के साथ, के बजाय Name = "labelForName"आप भी उपयोग कर सकते हैं Name = nameof(Resources.Resources.labelForName)
उवे कीम

35

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

संसाधन फ़ाइल कोड पीढ़ी के लिए विकल्प

जिसका अर्थ है कि आप इसके बजाय कुछ ऐसा कर सकते हैं (C # 6.0 का उपयोग करके)। तब आपको यह याद नहीं रखना चाहिए कि फर्स्टनेम को कम किया गया था या कैमल कैड किया गया था। और आप देख सकते हैं कि क्या अन्य गुण एक ही संसाधन मान का उपयोग सभी संदर्भों के साथ करते हैं।

[Display(Name = nameof(PropertyNames.FirstName), ResourceType = typeof(PropertyNames))]
public string FirstName { get; set; }

इस Winforms के साथ काम करेंगे? मेरे पास एक वर्ग है जो मैंने संसाधनों से प्रदर्शन एनोटेशन जोड़ा है और मैंने संपत्ति के नाम को प्राप्त करने के लिए लिंक से GetAttributeFrom विधि का उपयोग किया है, लेकिन यह स्थानीयकृत नहीं दिखाता है!
Dark_Knight

2
क्या आप स्थानीय पाठ को प्राप्त करने के लिए विशेषता। नाम या विशेषता का उपयोग कर रहे हैं। के लिए दस्तावेज़ीकरण .Name का कहना है "नाम संपत्ति का मूल्य प्राप्त करने के लिए इस संपत्ति का उपयोग न करें। इसके बजाय GetName विधि का उपयोग करें।" msdn.microsoft.com/en-us/library/…
टिकॉल

हां, मुझे यह समझ में आया कि मुझे गेटनेम () का इस्तेमाल करना था। धन्यवाद
Dark_Knight

20

अपडेट करें:

मुझे पता है कि बहुत देर हो चुकी है लेकिन मैं इस अपडेट को जोड़ना चाहूंगा:

मैं परम्परागत मॉडल मेटाडेटा प्रदाता का उपयोग कर रहा हूँ, जो फिल हैकेड द्वारा प्रस्तुत किया गया है, यह इसे देखने के लिए अधिक शक्तिशाली और आसान है: कन्वेंशनल मैलोडेलमाटाटाटा


पुराना उत्तर

यदि आप कई प्रकार के संसाधनों का समर्थन करना चाहते हैं:

public class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
    private readonly PropertyInfo nameProperty;

    public LocalizedDisplayNameAttribute(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)
            {
                return base.DisplayName;
            }
            return (string)nameProperty.GetValue(nameProperty.DeclaringType, null);
        }
    }
}

फिर इसे इस तरह उपयोग करें:

    [LocalizedDisplayName("Password", typeof(Res.Model.Shared.ModelProperties))]
    public string Password { get; set; }

पूर्ण स्थानीयकरण ट्यूटोरियल के लिए यह पृष्ठ देखें ।


1
+1। हेक का समाधान निश्चित रूप से यहां के अन्य लोगों की तुलना में सबसे सुरुचिपूर्ण है। यह ASP.NET MVC में प्रोग्रामिंग की कन्वेंशन-आधारित शैली में बहुत अच्छी तरह से फिट बैठता है और इसे आसानी से एक एकल नगेट-कमांड और Global.asax.cs में कोड की एक पंक्ति के माध्यम से कार्यान्वित किया जाता है।
निलज़ोर

11

मुझे संसाधन गुणों का चयन करके अपने App_GlobalResources के साथ काम करने के लिए गुंडर्स का जवाब मिला और "कस्टम टूल" को "PublicResXFileCodeGenerator" पर स्विच करें और "एंबेडेड रिसोर्स" पर कार्रवाई करें। कृपया नीचे Gunders टिप्पणी देखें।

यहां छवि विवरण दर्ज करें

एक जादू की तरह काम करता है :)


यह एक संसाधन फ़ाइल में परिणाम करता है, जैसे कि आपने App_GlobalResources के बाहर एक संसाधन फ़ाइल जोड़ी थी। इसलिए आपकी संसाधन फ़ाइल अब "App_GlobalResources" संसाधन फ़ाइल के रूप में व्यवहार नहीं करेगी, जो बिल्कुल ठीक है। लेकिन आपको बस इसके बारे में पता होना चाहिए। तो अब आपके पास App_GlobalResources में संसाधन फ़ाइल डालने का "लाभ" नहीं है। आप बस इसे कहीं और रख सकते थे।
रेने

5
public class Person
{
    // Before C# 6.0
    [Display(Name = "Age", ResourceType = typeof(Testi18n.Resource))]
    public string Age { get; set; }

    // After C# 6.0
    // [Display(Name = nameof(Resource.Age), ResourceType = typeof(Resource))]
}
  1. संसाधन के संसाधन टाइप को परिभाषित करें ताकि यह संसाधन के लिए दिखे
  2. उस विशेषता का नाम परिभाषित करें , जिसका उपयोग संसाधन की कुंजी के लिए किया जाता है, C # 6.0 के बाद, आप nameofकुंजी को कोडित करने के बजाय मजबूत टाइप किए गए समर्थन के लिए उपयोग कर सकते हैं ।

  3. नियंत्रक में वर्तमान धागे की संस्कृति निर्धारित करें।

Resource.Culture = CultureInfo.GetCultureInfo("zh-CN");

  1. सार्वजनिक करने के लिए संसाधन की पहुँच सेट करें

  2. इस तरह से cshtml में लेबल प्रदर्शित करें

@Html.DisplayNameFor(model => model.Age)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.