1

在我的 ASP.NET MVC3 项目中,我有一个像这样的视图模型,其中我为属性硬编码了错误消息。

public class UserProfileVM
{
  [Required]
  [StringLength(200, ErrorMessage = "Name should be 10 chars")]
  public string Name { set;get;}

 //other properties
}

我想ErrorMessage根据用户的偏好设置(用户选择的语言)动态加载属性的值。所以我有这样的函数返回语言标签

public string GetLabel(string labelCode)
{
  string labelText="Get from somewhere using labelCode";
  //Get User's language preference from Session and return the labelText here
  return labelText;
}

我试图在我的视图模型中这样使用它

[Required]
[StringLength(200, ErrorMessage = GetLabel("MinCharErr"))]
public string Name { set;get;}

但我无法编译我的代码。我收到一个错误,例如属性参数必须是属性参数类型的常量表达式、类型表达式或数组创建表达式

有人可以告诉我如何解决这个问题。我需要使用该GetLabel方法来获取相关文本。

4

2 回答 2

1

您应该创建自己的StringLength类来实现这一点:

public class CustomStringLength : StringLengthAttribute {
    public CustomStringLength() {
        //Set your error message right here
        base.ErrorMessage = userOptions.GetErrorByLabel(labelCode);
    }
}

显然,这需要连接到您的后端数据,但是,这是您如何动态设置错误消息的一般思路。

于 2013-06-17T21:39:01.140 回答
0

但我无法编译我的代码。我收到一个错误,例如属性参数必须是属性参数类型的常量表达式、类型表达式或数组创建表达式

因为您无法自定义属性,例如ErrorMessageResourceNameErrorMessageResourceType获取一些动态结果。

您只能通过在自定义类中传递参数化构造函数来自定义类中的属性Length。这意味着StringLengthAttribute你只能OverrideLengthString

就像你说你想通过一些关键来获得相应的Error Message,那是不可能的。

你也可以在你的资源文件中写下下面提到的消息

"Maximum allowed length is {0}"

并且在运行时,您可以通过在自定义类中将其替换为参数化构造函数值(即最大字符串长度)来格式化字符串

从 Session 中获取用户的语言偏好并在此处返回 labelText

您已在 Global.asax 文件中设置语言。因此,您的资源文件将根据UserLanguage. 因此,只需指定 Key 名称,对应的值将Resource file根据所选语言从中获取

如何设置语言?

public sealed class LanguageManager
{
    /// <summary>
    /// Default CultureInfo
    /// </summary>
    public static readonly CultureInfo DefaultCulture = new CultureInfo("en-US");

    /// <summary>
    /// Available CultureInfo that according resources can be found
    /// </summary>
    public static readonly CultureInfo[] AvailableCultures;

    static LanguageManager()
    {
        List<string> availableResources = new List<string>();
        string resourcespath = Path.Combine(System.Web.HttpRuntime.AppDomainAppPath, "App_GlobalResources");
        DirectoryInfo dirInfo = new DirectoryInfo(resourcespath);
        foreach (FileInfo fi in dirInfo.GetFiles("*.*.resx", SearchOption.AllDirectories))
        {
            //Take the cultureName from resx filename, will be smt like en-US
            string cultureName = Path.GetFileNameWithoutExtension(fi.Name); //get rid of .resx
            if (cultureName.LastIndexOf(".") == cultureName.Length - 1)
                continue; //doesnt accept format FileName..resx
            cultureName = cultureName.Substring(cultureName.LastIndexOf(".") + 1);
            availableResources.Add(cultureName);
        }

        List<CultureInfo> result = new List<CultureInfo>();
        foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
        {
            //If language file can be found
            if (availableResources.Contains(culture.ToString()))
            {
                result.Add(culture);
            }
        }

        AvailableCultures = result.ToArray();

        CurrentCulture = DefaultCulture;
        if (!result.Contains(DefaultCulture) && result.Count > 0)
        {
            CurrentCulture = result[0];
        }
    }

    /// <summary>
    /// Current selected culture
    /// </summary>
    public static CultureInfo CurrentCulture
    {
        get { return Thread.CurrentThread.CurrentCulture; }
        set
        {
            Thread.CurrentThread.CurrentUICulture = value;
            Thread.CurrentThread.CurrentCulture = value;
        }
    }
}
于 2013-06-18T01:28:09.383 回答