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

发布于 2024-11-15 22:36:54 字数 921 浏览 5 评论 0原文

我已经成功使用 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 上的文化,但这似乎不仅改变了文化或当前连接,而且还改变了所有的连接。

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

I've implemented localized validation, client-side, using the DataAnnotations attributes successfully. Now, I want to implement custom validation running server-side using the CustomValidationAttribute but my problem is that I can't find a way to get the client-side culture while executing the validation.

Here's the setup for the custom validation method:

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
}

This code returns the message but from the culture that the server is currently set.

I also tried to set the attribute on the property this way with same result:

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

I also tried to expose a method on my DomainService to change the Culture on the ValidationResources resx but this seems to be changing the culture not only or the current connection but for all the connections.

Since the validation is ran by Ria Services and not something I am calling directly, how can I tell the validation method to use a specific culture?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

好倦 2024-11-22 22:36:54

我遇到了这个线程,我能够解决我的问题并有区域性名称传递给 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 的魔力,我们甚至可以在 DomainServiceInitialize 中更改 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 );
}

I came across this thread and I was able to fix my issue and have the culture name pass to every request made by the DomainContext (client) to the server.

First, we need to create a custom IClientMessageInspector that will be responsible to set a parameter for the CurrentUICulture for every requests.

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
}

Next, we need to create a custom WebHttpBehavior that will inject our custom 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();
}

Finally, we extend the client DomainContext.OnCreate method to add our custom WebHttpBehavior. NOTE: The namespace of the extended DomainContext class must be the same as the generated one...

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();
}

Now, on the server-side, when we want to get the language code we can simply access it like this:

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

To enjoy even more of the DataAnnotation magic, we can even change the CurrentUICulture in the Initialize of the DomainService like this:

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

  base.Initialize( context );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文