.NET MVC:本地化RequiredAttribute(没有资源文件)

发布于 2024-10-26 02:38:20 字数 898 浏览 6 评论 0原文

这是我们在 .NET MVC 2 中面临的问题。

我们尝试使用 DataAnnotations 来处理模型验证,就像它应该做的那样。我们遇到的唯一问题是我们不想要标准错误消息(因为我们的网站上有多种语言)。

我们希望对其进行本地化,但该网站的设置方式是所有文本都来自数据库。所以我们希望数据库中也有错误消息。

因此,我们编写了一个自定义的RequiredAttribute,如下所示:

public class LocalizedRequiredAttribute : RequiredAttribute
{   
    public string LocalizedErrorMessage
    {
        get
        {
            return ErrorMessage;
        }
        set
        {
            ErrorMessage = value.Translate();
        }
    }

}

我们编写了String类的扩展以添加“Translate()”方法,该方法为正确的本地化版本执行必要的数据库查找。

我们这样使用我们的属性:

[LocalizedRequired(LocalizedErrorMessage = "Naam is required")]
public string Name {get; set; }

这有效,但只能一次。

如果您首先访问法语网站,您将看到法语错误消息,指出您应该输入一个值。如果您稍后访问英文网站,您仍然会在英文页面上看到法语错误。 Setter 似乎只被调用一次。

我们可以采取什么措施来防止这种行为并在每次运行验证/模型填充值时刷新错误消息?

感谢您能给我的任何帮助。

This is the problem that we're facing in .NET MVC 2.

We're trying to use DataAnnotations to take care of the Model Validation for us, like it's supposed to. The only problem that we're having is that we don't want the standard error messages (because we have multiple languages on our website).

We want to localize this, but the way the site is setup, is that all text comes from a database. So we'd like to have our error messages in the database as well.

So we wrote a custom RequiredAttribute, like this:

public class LocalizedRequiredAttribute : RequiredAttribute
{   
    public string LocalizedErrorMessage
    {
        get
        {
            return ErrorMessage;
        }
        set
        {
            ErrorMessage = value.Translate();
        }
    }

}

We wrote an extension to the String class to add the "Translate()" method, which does the necessary database lookup for the correct localized version.

We use our attribute like this:

[LocalizedRequired(LocalizedErrorMessage = "Naam is required")]
public string Name {get; set; }

This works, but only once.

If you visit the site in French first, you'll see the French error message stating that you're supposed to enter a value. If you visit the English site later, you'll still see the French error on the English page. The Setter seems to be called only once.

What can we do to prevent this behavior and refresh the error message every time the validation is run / the model is populated with values?

Thanks for any help you can give me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘虞初梦 2024-11-02 02:38:21

只需使用方法 FormatErrorMessage() (每次都会调用)来设置 ErrorMessage 属性

,但它很 hackish

public class ErrorLocalizedRequiredAttribute : RequiredAttribute
{
    public ErrorLocalizedRequiredAttribute(string name)
    {
        Name = name;
    }

    public string Name
    { get; set; }

    public override string FormatErrorMessage(string name)
    {
        //get translation from DB by Name
        ErrorMessage = Localization.Translate(Name);
        return base.FormatErrorMessage(name);
    }
}
.
.
.
[ErrorLocalizedRequiredAttribute("EmailIsRequired")]
public string Email
{
    get; set;
}

Just use method FormatErrorMessage() (whis is called everytime) to set ErrorMessage property

But it's hackish

public class ErrorLocalizedRequiredAttribute : RequiredAttribute
{
    public ErrorLocalizedRequiredAttribute(string name)
    {
        Name = name;
    }

    public string Name
    { get; set; }

    public override string FormatErrorMessage(string name)
    {
        //get translation from DB by Name
        ErrorMessage = Localization.Translate(Name);
        return base.FormatErrorMessage(name);
    }
}
.
.
.
[ErrorLocalizedRequiredAttribute("EmailIsRequired")]
public string Email
{
    get; set;
}
屋顶上的小猫咪 2024-11-02 02:38:20

您不能通过将 .Translate() 从 setter 移至 getter 来解决此问题吗?您的 setter 只被调用一次是有道理的。

编辑:
我认为 ErrorMessage 是一条虚拟消息,但事实并非如此。

您唯一的选择可能是创建从数据库检索值的资源类(您不需要资源文件)。

[Required(ErrorMesageResourceName="FirstName", ErrorMessageResourceType=typeof(ABCResourceClass))]  
public string Name {get; set; } 

class ABCResourceClass{
  public static String  FirstName{
    get{
        return Translate("FirstName");
    }
  }

}

您可以从示例中推断出,注释框架调用名称与您提供给 ErrorMessageResourceName 的字符串相匹配的属性。

如果您有很多属性,您可以采用某种代码生成技术来创建 ABCResourceClass。

Couldn't you fix this by moving your .Translate() from your setter to your getter? It makes sense that your setter is called only once.

Edit:
I assumed ErrorMessage was a virtual message, which is not the case.

Your only option might be to create Resource class (you don't need a resource file) that retrieves your values from the database.

[Required(ErrorMesageResourceName="FirstName", ErrorMessageResourceType=typeof(ABCResourceClass))]  
public string Name {get; set; } 

class ABCResourceClass{
  public static String  FirstName{
    get{
        return Translate("FirstName");
    }
  }

}

As you can infer from the example, the annotations framework calls the property with the name that matches the string you provide to ErrorMessageResourceName.

You could resort to some kindof code generation technique to create the ABCResourceClass if you have a lot of properties.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文