Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use "ErrorMessageResourceType" in DataAnnotations in Windows Store (Metro) app

In my Windows Store (Metro) app I am using DataAnnotations for my objects. Everything works fine.

Now I try to place my strings into Resource.resw files. The DataAnnotations need 2 properties to be filled: ErrorMessageResourceName and ErrorMessageResourceType. How do I use ErrorMessageResourceType with the new resource types?

public class Person : Entity
{
    private string _firstName;

    [Required( ErrorMessageResourceName = "GenericFieldRequired", ErrorMessageResourceType = typeof( ??? ))]
    public string FirstName {
        get { return _firstName; }
        set { SetPropertyChanged( ref _firstName, value, this ); }
    }
}

Any suggestions?

UPDATE: I found a Visual Studio tool which automatically generates the Resources.cs file:

Resw Generator

like image 564
Michael A. Volz aka Flynn Avatar asked Dec 18 '12 14:12

Michael A. Volz aka Flynn


1 Answers

After a lot of digging I think I understand why you are having issues.

In other project types the Resource file is automatically converted into a class with static methods called the name of the resource key.

There isn't a way really to do this automatically so I wrote a T4 Template that can help you out with this.

<#@ template debug="false" hostspecific="True" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Xml" #>
<#@ assembly name="System.Xml" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
using Windows.ApplicationModel.Resources;
<# 
  var namespaceName = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint");
#> 
namespace <#= namespaceName #>
{ 
    public class ResourceHelper
    {
        private static readonly ResourceLoader resourceLoader = new ResourceLoader("Resources");
<# using (XmlReader reader = XmlReader.Create(Host.ResolvePath("Resources.resw")))
        {
             bool found=reader.ReadToFollowing("data");
             while(found)
             {
                reader.MoveToFirstAttribute();
                string name = reader.Value;     

#>
            public static string <#= name #>
            {
                get
                {
                    return resourceLoader.GetString("<#= name #>");
                }
            }
<#
                found=reader.ReadToFollowing("data");
            }
        }#>

    } 
}

If you place the template in the same folder as your resource file it will output a file called ResourceHelper.cs. This can then be used in your object model:-

 [Required(ErrorMessageResourceName = "validation_string", ErrorMessageResourceType = typeof(ResourceHelper))]

Note there are a few limitations. Firstly, I'm not very good at T4 templates, so the code can probably be vastly improved. For now you must ensure the name you give your resource will result in a valid method name - don't put spaces in there!

Secondly the template won't automatically generate when you add a new key/value in your resource file, you must go into the template and hit save.

Apart from that it should work fine - hope it helps!

like image 140
Ross Dargan Avatar answered Nov 15 '22 10:11

Ross Dargan