Silverlight使用带有RIA服务的DataAnnotations进行本地化自定义验证

时间:2011-06-17 12:16:30

标签: validation silverlight-4.0 localization data-annotations ria

我已经成功地使用DataAnnotations属性实现了客户端的本地化验证。现在,我想使用 CustomValidationAttribute 实现运行服务器端的自定义验证,但我的问题是我无法在执行验证时找到获取客户端文化的方法。

以下是自定义验证方法的设置:

public static ValidationResult ValidateField( string fieldValue, ValidationContext validationContext )
{
#if !SILVERLIGHT
    // Get the message from the ValidationResources resx.
    return new ValidationResult( ValidationResources.Message, new string[]{ "Field" } );
#else
    return ValidationResult.Success;
#endif
}

此代码返回消息,但是从服务器当前设置的文化中返回。

我也尝试以这种方式在属性上设置属性,结果相同:

      [CustomValidation( typeof( CustomValidation ), "ValidateField", ErrorMessageResourceName = "Message", ErrorMessageResourceType = typeof( ValidationResources ) )]

我还尝试在我的DomainService上公开一个方法,以更改ValidationResources resx上的Culture,但这似乎不仅改变了文化,也改变了当前连接,但改变了所有连接。

由于验证是由Ria Services运行而不是我直接调用的,我如何告诉验证方法使用特定的文化?

1 个答案:

答案 0 :(得分:1)

我遇到了this线程,我能够修复我的问题,并将文化名称传递给DomainContext(客户端)向服务器发出的每个请求。

首先,我们需要创建一个自定义 IClientMessageInspector ,负责为每个请求设置CurrentUICulture的参数。

public class AppendLanguageMessageInspector : IClientMessageInspector
{
  #region IClientMessageInspector Members

  public void AfterReceiveReply( ref Message reply, object correlationState )
  {
    // Nothing to do
  }

  public object BeforeSendRequest( ref Message request, IClientChannel channel )
  {
    var property = request.Properties[ HttpRequestMessageProperty.Name ] as HttpRequestMessageProperty;
    if( property != null )
    {
      property.Headers[ "CultureName" ] = Thread.CurrentThread.CurrentUICulture.Name;
    }

    return null;
  }

  #endregion // IClientMessageInspector Members
}

接下来,我们需要创建一个自定义 WebHttpBehavior ,它将注入我们的自定义 IClientMessageInspector

public class AppendLanguageHttpBehavior : WebHttpBehavior
{
  public override void ApplyClientBehavior( ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime )
  {
    clientRuntime.MessageInspectors.Add( _inspector );
  }

  private readonly AppendLanguageMessageInspector _inspector = new AppendLanguageMessageInspector();
}

最后,我们扩展客户端DomainContext.OnCreate方法以添加我们的自定义 WebHttpBehavior 注意:扩展DomainContext类的名称空间必须与生成的名称空间相同...

public partial class DomainService1
{
  partial void OnCreated()
  {
    var domainClient = this.DomainClient as WebDomainClient<IDomainService1Contract>;
    if( domainClient != null )
    {
      domainClient.ChannelFactory.Endpoint.Behaviors.Add( DomainService1.AppendLanguageHttpBehavior );
    }
  }

  private static readonly AppendLanguageHttpBehavior AppendLanguageHttpBehavior = new AppendLanguageHttpBehavior();
}

现在,在服务器端,当我们想要获取语言代码时,我们可以像这样访问它:

var cultureName = System.Web.HttpContext.Current.Request.Headers[ "CultureName" ];

为了享受更多的DataAnnotation魔术,我们甚至可以像这样更改 DomainService Initialize 中的CurrentUICulture:

public override void Initialize( DomainServiceContext context )
{
  var cultureName = System.Web.HttpContext.Current.Request.Headers[ "UICultureName" ];
  Thread.CurrentThread.CurrentUICulture = new CultureInfo( cultureName );

  base.Initialize( context );
}