3

Here is my code..

    private IHelloWorld ChannelFactoryWebService()
        {
            ServiceEndpoint tcpEndPoint = new ServiceEndpoint(
                                                ContractDescription.GetContract(typeof(IHelloWorld)),
                                                new NetTcpBinding(),
                                                new EndpointAddress("net.tcp://myserver/CultureTest/Service.svc"));

        ChannelFactory<IHelloWorld> factory = new ChannelFactory<IHelloWorld>(tcpEndPoint);
        factory.Endpoint.Behaviors.Add(new CultureBehaviour());

        return factory.CreateChannel();
    }


    [TestMethod]  <-------------- FAILING TEST ----
    public void ChangingCultureWASViaEndPointTest()
    {
        IHelloWorld client = ChannelFactoryWebService();

        CultureInfo cultureInfo = new CultureInfo("ar-SA");
        Thread.CurrentThread.CurrentCulture = cultureInfo;

        client.Hello();
        string culture = client.HelloCulture();

        Assert.AreEqual("ar-SA", culture);  <--- fails here.. I get en-US for culture

    }

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, IncludeExceptionDetailInFaults = true)]
public class Server : IHelloWorld
{
    #region IHelloWorld Members

    public void Hello()
    {
        Console.WriteLine(string.Format("Hello world from the server in culture {0}", Thread.CurrentThread.CurrentCulture.Name));
    }

    public string HelloCulture()
    {

        string cultureName = Thread.CurrentThread.CurrentCulture.Name;
        return cultureName;
    }

    #endregion
}


[ServiceContract]
public interface IHelloWorld
{
    [OperationContract]
    void Hello();

    [OperationContract]
    string HelloCulture();
}


    public class CultureMessageInspector : IClientMessageInspector, IDispatchMessageInspector
    {
        private const string HeaderKey = "culture";
        #region IDispatchMessageInspector Members

        public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
        {
            int headerIndex = request.Headers.FindHeader(HeaderKey, string.Empty);
            if (headerIndex != -1)
            {
                Thread.CurrentThread.CurrentCulture = new CultureInfo(request.Headers.GetHeader<String>(headerIndex));
            }
            return null;
        }

        public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
        }

        #endregion

        #region IClientMessageInspector Members

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
        }

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
        {
            request.Headers.Add(MessageHeader.CreateHeader(HeaderKey, string.Empty, Thread.CurrentThread.CurrentCulture.Name));
            return null;
        }

        #endregion
    }


    public class CultureBehaviour : IEndpointBehavior
    {
        #region IEndpointBehavior Members

        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {
            CultureMessageInspector inspector = new CultureMessageInspector();
            clientRuntime.MessageInspectors.Add(inspector);
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
        {
            CultureMessageInspector inspector = new CultureMessageInspector();
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }

        #endregion
    }


public class CultureBehaviorExtension : BehaviorExtensionElement
{
    // BehaviorExtensionElement members
    public override Type BehaviorType
    {
        get { return typeof(CultureBehaviour); }
    }

    protected override object CreateBehavior()
    {
        return new CultureBehaviour();
    }
}

Web config for the hosting site for Service looks as follows:

  <endpointBehaviors>
    <behavior name="Default">
      <CultureExtension/>
    </behavior>
  </endpointBehaviors>

  <serviceBehaviors>
    <behavior>
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="true"/>
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

<extensions>
  <behaviorExtensions>
    <add name="CultureExtension" type="Extension.CultureBehaviorExtension, Extension, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </behaviorExtensions>
</extensions>

<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

My question is, inside the following code when I go through the service hosted by website, I am unable to get the culture value of ar-SA inside the Hello method of the service. I tried my best to clarify the question here. Please let me know what else needs to be clarified.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, IncludeExceptionDetailInFaults = true)]
public class Server : IHelloWorld
{
    #region IHelloWorld Members

    public void Hello()
    {
    <--- problem here unable to get culture value of ar-SA here --->
        Console.WriteLine(string.Format("Hello world from the server in culture {0}", Thread.CurrentThread.CurrentCulture.Name));
    }

    public string HelloCulture()
    {

        string cultureName = Thread.CurrentThread.CurrentCulture.Name;
        Console.WriteLine("**************************hello**********************************");
        Console.WriteLine(cultureName);
        return cultureName;
    }

    #endregion
}
dotnet-practitioner
  • 13,968
  • 36
  • 127
  • 200
  • 1
    +1. Sorry I'm not trying to answer your question. I'm running the WCF service self-hosted, and your code set me on the right path for adding the culture behavior. – Mike Fuchs Nov 11 '14 at 18:15

1 Answers1

1

Its not really an answer why that particular code doesnt work, but why dont you just sent in the culture string and set it in your method on the WCF service?

Thats the way we usualy do it, or if its an authenticated user, just save it on the user so they can switch to any language regardless of computer config.

cjensen
  • 2,703
  • 1
  • 16
  • 15
  • we don't want to send the culture via method call. BTW.. this code works when I host the service using console application. It does not work with service hosted with iis. :( – dotnet-practitioner Aug 16 '12 at 21:12