user781700
user781700

Reputation: 964

WCF Client not able to connect on some machines

I have a simple self host WCF Service. I have this service running on remote server. I am able to communicate to service with client running on my machine(I am local admin). But when I run same client on different machine(non admin) they are not able to communicate.

I monitored resource manager and I see two random local ports are being open at each time of service call and call back. So I cannot open specific ports.

Any Idea what could be the possible reason or firewall configuration change on other machines?

I am very new to WCF. Please pardon me if its a basic question.

WCF Server Code

namespace CService
    {
    class Program
       {
       static void Main(string[] args) {

        Console.Title = "C Service";

        // Step 1 of the address configuration procedure: Create a URI to serve as the base address.
        Uri baseAddress = new Uri("http://" + GetServerIPPort.ServerIP + ":" + GetServerIPPort.Port + "/CService/Service");


        // Step 2 of the hosting procedure: Create ServiceHost
        ServiceHost selfHost = new ServiceHost(typeof(CSerice), baseAddress);

        try
        {
            // Step 3 of the hosting procedure: Add a service endpoint.
            selfHost.AddServiceEndpoint(typeof(ICService), new BasicHttpBinding(), "CService");

            // Step 4 of the hosting procedure: Enable metadata exchange.
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            selfHost.Description.Behaviors.Add(smb);

            // Step 5 of the hosting procedure: Start (and then stop) the service.
            selfHost.Open();
            Console.WriteLine("The Coemet Service is ready and its listening on {0}", baseAddress.AbsoluteUri.ToString() + ":" + baseAddress.Port.ToString());

            Console.WriteLine("Press <ENTER> to terminate service.");
            Console.WriteLine();
            Console.ReadLine();

            // Close the ServiceHostBase to shutdown the service.
            selfHost.Close();
        }
        catch (CommunicationException ce)
        {
            Console.WriteLine("An exception occurred: {0}", ce.ToString());
            selfHost.Abort();
        }
    }
}

I have generatedProxy object with help of this link http://msdn.microsoft.com/en-us/library/ms733133(v=vs.110).aspx

My client code snippet looks like this.

string serviceEndPointAddress = "http://" + GetServerIPPort.ServerIP + ":" +     GetServerIPPort.Port + "/CService/Service/CService";

            var remoteAddress = new System.ServiceModel.EndpointAddress(new Uri(serviceEndPointAddress));
            object rawOutput;
            using (var client = new CServiceClient(new BasicHttpBinding(), remoteAddress))
            {
                client.Endpoint.Binding.SendTimeout = new TimeSpan(0, 0, 0, 100);
                try
                {
                    rawOutput = client.GetData(Identifier, field, date);
                }
                catch (Exception e)
                {
                    errorMsg = e.ToString();
                }
            }\n

Error trowed at "client.GetData(Identifier, field, date)"

System.Runtime.Serialization.InvalidDataContractException: Type 'System.Threading.Tasks.Task1[System.Object]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types. at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type) at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id, RuntimeTypeHandle typeHandle, Type type) at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(Int32 id, RuntimeTypeHandle typeHandle, Type type) at System.Runtime.Serialization.XsdDataContractExporter.GetSchemaTypeName(Type type) at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.CreatePartInfo(MessagePartDescription part, OperationFormatStyle style, DataContractSerializerOperationBehavior serializerFactory) at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.CreateMessageInfo(DataContractFormatAttribute dataContractFormatAttribute, MessageDescription messageDescription, DataContractSerializerOperationBehavior serializerFactory) at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter..ctor(OperationDescription description, DataContractFormatAttribute dataContractFormatAttribute, DataContractSerializerOperationBehavior serializerFactory) at System.ServiceModel.Description.DataContractSerializerOperationBehavior.GetFormatter(OperationDescription operation, Boolean& formatRequest, Boolean& formatReply, Boolean isProxy) at System.ServiceModel.Description.DataContractSerializerOperationBehavior.System.ServiceModel.Description.IOperationBehavior.ApplyClientBehavior(OperationDescription description, ClientOperation proxy) at System.ServiceModel.Description.DispatcherBuilder.BindOperations(ContractDescription contract, ClientRuntime proxy, DispatchRuntime dispatch) at System.ServiceModel.Description.DispatcherBuilder.BuildProxyBehavior(ServiceEndpoint serviceEndpoint, BindingParameterCollection& parameters) at System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint serviceEndpoint, Boolean useActiveAutoClose) at System.ServiceModel.ChannelFactory.CreateFactory() at System.ServiceModel.ChannelFactory.OnOpening() at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.ChannelFactory.EnsureOpened() at System.ServiceModel.ChannelFactory1.CreateChannel(EndpointAddress address, Uri via) at System.ServiceModel.ClientBase1.CreateChannel() at System.ServiceModel.ClientBase1.CreateChannelInternal() at System.ServiceModel.ClientBase`1.get_Channel() at CServiceClient.GetData(String Identifier, String field, DateTime date)

Upvotes: 0

Views: 1055

Answers (3)

suraj
suraj

Reputation: 316

I too was facing the same issue, when I created a WCF Service on framework 4.5 higher and was trying to deploy on the IIS 8(i.e App pool 4.0), the above steps didn't solved my issue, So I recreated my full solution from scratch in framework 4.0 and re-deployed it. While consuming the services, followed the above steps to uncheck "Allow generation of asynchronous operations" Resolved my problem.

Upvotes: 0

Derek W
Derek W

Reputation: 10026

In .NET 4.5, there is new support for task-based asynchronous operations in WCF. When you generate a proxy on your development machine using VS 2012 or later - it can include these by default.

Now the new machine that you are using is likely running on .NET 4.0 and as a result does not know what the heck to do with the task-based asynchronous operation - hence the exception.

It's a pretty simple fix, to support clients running .NET 4.0 you just need to do either of the following in Service Reference Settings:

  1. Uncheck Allow generation of asynchronous operations
  2. Select Generate asynchronous operations instead of Generate task-based operations

Special thanks goes to this blog post.

Upvotes: 2

field_b
field_b

Reputation: 698

According to the exception you are passing an object that is not serializable. I suspect this is the Identifier in the following line of code:

rawOutput = client.GetData(Identifier, field, date);

According to the stack trace the CService is expecting two strings and a datetime:

System.ServiceModel.ClientBase`1.get_Channel() at CServiceClient.GetData(String Identifier, String field, DateTime date)

If you need to pass a custom object (data transfer object) using WCF you should use the DataContractAttribute attribute for the class and the DataMemberAttribute for each member, like this:

[DataContract]
public class Identifier
{
    [DataMember]
    public string Id {get;set;}
}

Upvotes: 0

Related Questions