Локализованная пользовательская проверка Silverlight с использованием DataAnnotations со службами RIA - PullRequest
0 голосов
/ 17 июня 2011

Я успешно реализовал локализованную проверку на стороне клиента, используя атрибуты 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 для изменения культуры на Resx ValidationResources, но это, кажется, меняет культуру не только или текущее соединение, но длявсе соединения.

Поскольку служба Ria Services выполняет проверку, а не то, что я вызываю напрямую, как я могу указать методу проверки использовать определенную культуру?

1 Ответ

1 голос
/ 20 июня 2011

Я наткнулся на этот поток , и мне удалось исправить мою проблему, и имя культуры передавалось каждому запросу, сделанному 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, мы можем даже изменить CurrentUICulture в Initialize DomainService следующим образом:

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

  base.Initialize( context );
}
...