1

I have a site which can be opened in multiple languages, the strings from the site are retrieved from a XML file which is provided by the product owner.

The model contains many fields but for this question we are just looking at FamilyName

public class RegisterViewModel
{
    public Translation Translation { get; set; }
    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "LastNameEnter")]
    [Display(Name = "Last Name")]
    public string FamilyName { get; set; }
}

I previously used to fetch validation and required error messaged for the fields on my models using the above format. Now though we have a helper which reads the XML file and creates a Translation object which contains a list of "Item", each Item is a string with some other properties.

I have tried to change the fields on my model to the following format however it doesnt work because I get following error:

An object reference is required for the non static field.

[Required(ErrorMessage = Translation.Item.Find(x => x.Id == "FamilyName " && x.Type == "Required").Text)]
public string FamilyName { get; set; }

How can I go about setting the error message using my non static Translation property.

The translation property is set in the constructor from the controller.

EDIT:

The issue lies in my Translation objects instantiation relying upon query strings in the request.

string Language = !String.IsNullOrEmpty(Request.QueryString["l"])? Request.QueryString["l"]: "en-en";
model.Translation = RegistrationScriptHelper.Translation.GetRegistrationScript(Request).Find(x => x.Language == Language);

EDIT 2: Global.asax.cs:

        DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomRequiredAttribute),
        typeof(RequiredAttributeAdapter));

Output:

tereško
  • 58,060
  • 25
  • 98
  • 150
ObiEff
  • 640
  • 8
  • 24

1 Answers1

2

You need to write your own attribute to achieve this. Here is an example:

public class MyReqAttribute : RequiredAttribute
{
    private string _errorID;
    public MyReqAttribute(string errorID)
    {
        _errorID=errorID;           
    }
    public override string FormatErrorMessage(string name)
    {
        string language = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["l"])? HttpContext.Current.Request.QueryString["l"]: "en-en";
        var translation = RegistrationScriptHelper.Translation.GetRegistrationScript(HttpContext.Current.Request).Find(x => x.Language == language);

        this.ErrorMessage = translation.Item.Find(x => x.Id == errorID 
            && x.Type == "Required").Text;

        return base.FormatErrorMessage(name);
    }

}

And in Global.asax.cs file add following line:

protected void Application_Start()
{
    // other codes here

    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MyReqAttribute), 
        typeof(RequiredAttributeAdapter));
}

Then you could use your own attribute in your models:

[MyReqAttribute("FamilyName")]
public string FamilyName { get; set; }
Sam FarajpourGhamari
  • 14,601
  • 4
  • 52
  • 56
  • How could I then use this in the view? Previously it was just @Html.ValidationMessageFor(m => m.FamilyName) in this instance will I have to create a new html helper? – ObiEff Aug 26 '15 at 13:21
  • No you don't need any change in your view. Since we injected our validator to MVC in `Global.asax.cs` – Sam FarajpourGhamari Aug 26 '15 at 13:28
  • Right but the issue here is that Translation is not a static object. Translation is created in the the controller and added to the Model. In this case MyReqAttribute has no access to translation, and passing it into the constructor for it has the same Non-Static error. – ObiEff Aug 26 '15 at 13:40
  • Then you must create new instance of your `Translation` class inside of the attribute. Submit your code where you are creating the translation object. I will show you how. – Sam FarajpourGhamari Aug 26 '15 at 13:45
  • Added in details, I use query strings to get the language of the translation as well as the specific client site. The client site is used in the Helper method, and after it is retrieved translations are selected using the language. My Query string looks like this ?v=LZ&l=en-gb – ObiEff Aug 26 '15 at 13:55
  • Works great, needed to make a few changes and create a dictionary storage to stop it from repeating the processing every time but its good now. Thanks – ObiEff Aug 26 '15 at 14:48
  • Just realised that validation messages are not being pushed into their span. They are set correctly on the Input but aren't firing. – ObiEff Aug 26 '15 at 15:48
  • What dose it mean they are set in input but not firing? Are you registered them in `global.asax.cs'? – Sam FarajpourGhamari Aug 26 '15 at 15:53
  • As in they are being set correctly in the Input field in the HTML, but instead of firing when the fields are not filled, nothing happens. Check Edit and comment on post. – ObiEff Aug 26 '15 at 15:59
  • The span is filed by JS when you click submit button and Jquery validator could not validate the input. If you check default `Required` attribute it behaves same. – Sam FarajpourGhamari Aug 26 '15 at 16:09