Localisation of Built in MVC Validation Messages

While working on web site for a client in Belgium I was wondering why the Required attribute error message wasn’t being localised based on the CurrentUICulture of the thread.

This was bugging me, so I downloaded the MVC 3 source code from CodePlex and found the Required attribute unit test. Even after changing the thread to use Flemish the below test still passed.

image

After talking to Damian we found that there are Language Packs for .NET 4. These can be obtained from https://www.microsoft.com/download/en/details.aspx?id=3324.

These packs will install the required resources in you .Net 4 framework directory.
image

As soon as I installed the Dutch language pack the above test failed as expected.

image

I still need to test what gets stored in the logs when these packs are installed and an exception is thrown. It won’t help us much if errors in the logs start getting stored in the language of the user that is logged in.

Dynamically Add Required Attribute for MVC3 jQuery Unobtrusive

While you can add the data-val attributes for MVC client side validation by default MVC unobtrusive validation won’t process them.

What you have to do is remove the validators and re-add them.

1
2
3
4
$(“#Password”).attr(“data-val-required”, “Password is required”);
$(“form”).removeData(“validator”);
$(“form”).removeData(“unobtrusiveValidation”);
$.validator.unobtrusive.parse(“form”);

Using Automapper With Windsor

It took me a little while to track this down so I’m posting it here. If you have resolvers that need DI you can get Automapper to use Windsor using the below.



 1: Mapper.Initialize(x => x.ConstructServicesUsing(_container.Resolve));



That’s it. Automapper will now use Windsor for object construction.

WCF With Out a Codefile

I’m always forgetting this. If you want to use wcf using an assembly instead of a code file here is what you have to do.

  1. Add the assembly as a reference.
  2. change the svc file mark up to

    1
    <%@ ServiceHost Service=”“  %>
  3. Change the service configuration in the web.config

    1
    2
    3
    4
    5
    6
    <service behaviorConfiguration=”tricoder_serviceBehavior” name=”<Concrete Class”>
    <endpoint address=”” binding=”basicHttpBinding” bindingConfiguration=””
    contract=”Interface with contracts” >
    </endpoint>
    <endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange” />
    </service>

And make sure that you use the full name of the concrete class and the interface.

Technorati Tags: wcf,.Net

Xps and Silverlight

I’ve recently been asked to investigate displaying an Xps file using Silverlight.

What I initially found was this sample posted by Koen Zwikstra. It turns out that the format of the Xps file is pretty similar to the Xaml use by Silverlight. What this sample does is replace or remove the items in the Xps file which Silverlight doesn’t understand.

The main item which needs translating is the Glyphs element, because of the way that Xps uses obfuscated fonts. For the Glyph element to use an obfuscated font in Silverlight it must be a resource of the Silverlight application. The problem with this is unless you have a predetermined set of Xps file to show you have no idea which fonts you need to embed as resources.

To get around this Koen converts the Glyphs to TextBlock to allow the use of the FontSource class which must use a stream which contains the unobfuscated font.

There was a small problem with the way Koen’s example deobfuscated the font which might have been because I’m using Silverlight 3 and the example was written for Silverlight 2. What I had to do was replace code in the ObfuscatedFontStream constructor.





 1: public ObfuscatedFontStream(Stream source, string fontFileName)


 2: {


 3:     if (source == null) {


 4:         throw new ArgumentNullException(“source”);


 5:     }


 6:     if (fontFileName == null) {


 7:         throw new ArgumentNullException(“fontFileName”);


 8:     }


 9:     this.source = source;


 10:  


 11:     string name = Path.GetFileNameWithoutExtension(fontFileName);


 12:     Guid guid;


 13:     try {


 14:         guid = new Guid(name);


 15:     }


 16:     catch (Exception e) {


 17:         throw new ArgumentException(string.Format(“File name {0} does not contain a valid GUID”, fontFileName), e);


 18:     }


 19:  


 20:     byte[] guidBytes = new byte[16];


 21:     for (int i = 0; i < guidBytes.Length; i++)


 22:     {


 23:         guidBytes[i] = Convert.ToByte(guid.ToString(“N”).Substring(i * 2, 2), 16);


 24:     }


 25:  


 26:     long position = source.Position;


 27:  


 28:     if (source.CanSeek)


 29:     {


 30:         source.Seek(0, SeekOrigin.Begin);


 31:     }


 32:  


 33:     this.header = new byte[32];


 34:     source.Read(this.header, 0, 32);


 35:     byte[] key = guid.ToByteArray();


 36:  


 37:     for (int i = 0; i < 32; i++) {


 38:         int gi = guidBytes.Length - (i % guidBytes.Length) - 1;


 39:         header[i] ^= guidBytes[gi];


 40:     }


 41:     // reset stream position


 42:     if (source.CanSeek)


 43:     {


 44:         source.Seek(position, SeekOrigin.Begin);


 45:     }


 46: }


There was still one problem with the sample and that was that it was not able to display Xps files generated from the Xps printer driver. For some reason the normal method of getting the resouces out of the Xps file using Application.GetResourceStream doesn’t work.

I found that I could use SilverlightContribs Zip methods to open the Xps file. What I did was change Koen’s Load method in XpsReader to use ZipFile if Application.GetResourceStream fails.





 1: private StreamResourceInfo Load(Uri uri)


 2:         {


 3:             StreamResourceInfo streamResourceInfo = Application.GetResourceStream(_xps, uri);


 4:             if (streamResourceInfo == null)


 5:             {


 6:                 // Zipfile closes the underlying stream when it is disposed, which we don’t really want.


 7:                 // so we copy the original stream and let ZipFile close that.


 8:                 Stream zipStream = CopyStream(_xps.Stream);


 9:                 using (var zipFile = new ZipFile(zipStream))


 10:                 {


 11:                     if (zipFile.FindEntry(uri.ToString(), true) > 0)


 12:                     {


 13:                         ZipEntry entry = zipFile.GetEntry(uri.ToString());


 14:                         Stream stream = zipFile.GetInputStream(entry.ZipFileIndex);


 15:                         MemoryStream depressed = CopyStream(stream);


 16:                         streamResourceInfo = new StreamResourceInfo(depressed, string.Empty);


 17:                     }


 18:                 }


 19:             }


 20:             return streamResourceInfo;


 21:         }


 22:  


 23:         private MemoryStream CopyStream(Stream stream)


 24:         {


 25:             var ms = new MemoryStream();


 26:             if (stream.CanSeek)


 27:             {


 28:                 stream.Seek(0, SeekOrigin.Begin);


 29:             }


 30:             var buffer = new byte[32768];


 31:             int read;


 32:             do


 33:             {


 34:                 read = stream.Read(buffer, 0, buffer.Length);


 35:                 if (read > 0)


 36:                 {


 37:                     ms.Write(buffer, 0, read);


 38:                 }


 39:             } while (read > 0);


 40:             ms.Seek(0, SeekOrigin.Begin);


 41:             return ms;


 42:         }


I found that I had to return an uncompressed stream due to the implementation of the InflaterInputStream not working with the rest of the sample.

Technorati Tags: .Net,C#,Silverlight

Resharper 5

Yesterday I installed the EAP build of Resharper 5. Once of the cool features I’ve found is that it adds support for the Microsoft Source Server to VS2005.

If you navigate to a type that is in MS code it will go off and download the reference source.

image

Then you get taken to that type in the reference code.

image

Technorati Tags: C#,Resharper

Playing With Asp.Net MVC Preview 2

Having played with xVal with MVC 1 I was interested to see the built in client side validation added to the MVC2.

After a little bit of searching and playing around I got the page set up.







 1: script type=”text/javascript” src=”../../Scripts/jquery-1.3.2.js”></script>

 1:  


 2: <script type=“text/javascript” src=“../../Scripts/jquery.validate.js”>


 1: 


 2: <script type=“text/javascript” src=“../../Scripts/MicrosoftMvcJQueryValidation.js”>


</script>


 2:  


 3:     h2><%

 1: = Html.Encode(ViewData[“Message”]) 


%></h2>


 4:     p>


 5:         To learn more about ASP.NET MVC visit a href=”http://asp.net/mvc" title=”ASP.NET MVC Website”>http://asp.net/mvc</a>.


 6:         <%

 1: = Html.ValidationSummary(“Create was unsuccessful. Please correct the errors and try again.”) 


%>


 7:         <%

 1:  


 2:             Html.ClientValidationEnabled = true; 


%>


 8:         <%

 1: using (Html.BeginForm())


 2:           {


%>


 9:           <%

 1: =Html.EditorForModel() 


%>


 10:            input type=”submit” value=”Save” />


 11:         <%

 1: } 


%>


 12:     </p>


Using this simple class as the model.





 1: using System.ComponentModel.DataAnnotations;


 2:  


 3: namespace MvcApplication6.Models


 4: {


 5:     public class Address


 6:     {


 7:         [Required(ErrorMessage = “The House Number or Name field is required”)]


 8:         public string HouseNumberName { get; set; }


 9:         [Required]


 10:         public string Street { get; set; }


 11:  


 12:         [Required]


 13:         public string City { get; set; }


 14:  


 15:         [Required]


 16:         public string PostCode { get; set; }


 17:     }


 18: }


Gave me this result.

Validation

I’m not sure about having the <% Html.ClientValidationEnabled = true; %> line, it doesn’t feel right. I’m also not sure about the usefulness of Html.EditorForModel() I need to poke around a bit more and see if there is some way of changing the captions.

Apart from that it seems pretty simple. I would like to see if it can be hooked up to nHibernate validation.

Technorati Tags: ASP.NET MVC