[c#] 자원의 DisplayName 속성?

지역화 된 응용 프로그램 DisplayName이 있으며 특정 모델 속성을 Resource에서 설정할 수 있는지 궁금합니다 .

나는 이런 식으로하고 싶다 :

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

그러나 컴파일러가 “속성 인수는 속성 매개 변수 유형의 상수 표현식, 유형 유형 또는 배열 작성 표현식이어야합니다.”

해결 방법이 있습니까? 레이블을 수동으로 출력하고 있지만 유효성 검사기 출력에 레이블이 필요합니다!



답변

맞춤 속성을 작성하는 방법은 다음과 같습니다.

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; }
}


답변

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’사용자 지정 도구를 사용하십시오.

(추가 참고로, MVC를 사용 App_GlobalResources하거나 사용해서는 안됩니다 App_LocalResources. 이것이 왜 그런지에 대한 자세한 내용은 여기를 참조 하십시오 )


답변

리소스 파일을 열고 액세스 수정자를 public 또는 internal로 변경하면 리소스 파일에서 클래스를 생성하여 강력한 형식의 리소스 참조를 만들 수 있습니다.

리소스 파일 코드 생성을위한 옵션

즉 C # 6.0을 사용하여 대신 이와 같은 작업을 수행 할 수 있습니다. 그런 다음 이름이 소문자인지 낙타인지 기억하지 않아도됩니다. 그리고 다른 속성이 모든 리소스 찾기에서 동일한 리소스 값을 사용하는지 확인할 수 있습니다.

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


답변

최신 정보:

너무 늦었지만이 업데이트를 추가하고 싶습니다.

Phil Haacked 가 제시 한 Conventional Model Metadata Provider 를 사용하고 있습니다.이 모델 은 더 강력하고 적용하기 쉽습니다.
ConventionalModelMetadataProvider


기존 답변

여러 유형의 리소스를 지원하려면 다음을 수행하십시오.

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; }

전체 현지화 자습서를 보려면 이 페이지를 참조 하십시오 .


답변

리소스 속성을 선택하고 “사용자 지정 도구”를 “PublicResXFileCodeGenerator”로 전환하고 작업을 “내장 리소스”로 빌드하여 Gunders가 내 App_GlobalResources 작업에 대한 답변을 얻었습니다. 아래의 Gunders 의견을 준수하십시오.

여기에 이미지 설명을 입력하십시오

매력처럼 작동합니다 🙂


답변

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. 자원 을 찾도록 속성의 ResourceType 을 정의하십시오.
  2. 리소스 키에 사용되는 특성의 이름 을 정의합니다. C # 6.0 이후 nameof에는 키를 하드 코딩하는 대신 강력한 형식의 지원에 사용할 수 있습니다 .

  3. 컨트롤러에서 현재 스레드의 문화권을 설정하십시오.

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

  1. 자원의 접근성을 공개로 설정

  2. 다음 과 같이 cshtml에 레이블을 표시하십시오.

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


답변