我已经成功地使用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运行而不是我直接调用的,我如何告诉验证方法使用特定的文化?
答案 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 );
}