Da habe ich mich gestern lang und breit damit beschäftigt, wie man das Problem auf Property-Basis lösen kann, dann das. Das gezeigte Beispiel funktioniert zwar in der Theorie - und auch in den Tests - nur in der Praxis fällt es durch. Problem: "validationContext" ist null. Immer.
Ich stecke noch nicht so tief drin, als das ich wüsste, warum Microsoft das nicht implementiert hat - aber da wir ja von einem Release Candidate sprechen, nehme ich mal an, dass sich da in absehbarer Zeit auch nichts tun wird.
Nach einiger Suche, Flüchen und 2, 3 grauen Haaren bin ich dann auf eine Lösung direkt vor meiner Nase gestoßen. Microsoft liefert in den Projekt-Templates für MVC2 in Visual Studio bereits eine Klasse namens "PropertiesMustMatchAttribute" mit. Der Name ist selbsterklärend:
1: [AttributeUsage(AttributeTargets.Class, AllowMultiple = true,
2: Inherited = true)]
3: public sealed class PropertiesMustMatchAttribute :
4: ValidationAttribute
5: {
6: private const string _defaultErrorMessage =
7: "'{0}' and '{1}' do not match.";
8: private readonly object _typeId = new object();
9:
10: public PropertiesMustMatchAttribute(string originalProperty,
11: string confirmProperty)
12: : base(_defaultErrorMessage)
13: {
14: OriginalProperty = originalProperty;
15: ConfirmProperty = confirmProperty;
16: }
17:
18: public string ConfirmProperty { get; private set; }
19: public string OriginalProperty { get; private set; }
20:
21: public override object TypeId
22: {
23: get { return _typeId; }
24: }
25:
26: public override string FormatErrorMessage(string name)
27: {
28: return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
29: OriginalProperty, ConfirmProperty);
30: }
31:
32: public override bool IsValid(object value)
33: {
34: PropertyDescriptorCollection properties =
35: TypeDescriptor.GetProperties(value);
36: object originalValue =
37: properties.Find(OriginalProperty, true).GetValue(value);
38: object confirmValue =
39: properties.Find(ConfirmProperty, true).GetValue(value);
40: return Object.Equals(originalValue, confirmValue);
41: }
42: }
Es funktioniert übrigens auch prima - auch wenn die Überprüfung erst nach denen der Properties ausgeführt wird, also ganz zum Schluss. Aber damit kann ich leben.