Pregunta

I am starting out with WCF. I have created two console apps (server and client) that work without any issues but since moving them onto forms I'm having all kinds of problems. I had a look here and elsewhere on the net, I can't seem to find anything that can help me with my issue. I honestly don't understand the issue but I think it may have something to do with my datatypes (they're under different namespaces)?

Here's my Server code:

public partial class Form1 : Form
{
    ModelDataServer Server;
    public ScraperForm()
    {
        InitializeComponent();

        Server = new ModelDataServer(); // Opened Here
        Server.Scraper = this;
    }
}

[ServiceContract]
public interface IModelData
{
    [OperationContract]
    ArrayList GetData();
}

[ServiceBehavior(UseSynchronizationContext=false)]
public class ModelDataServer : IModelData
{
    ServiceHost Host;
    public DataModel Model { private get; set; }

    public ModelDataServer()
    {
        Host = new ServiceHost(typeof (ModelDataServer), 
            new Uri[]
            {
                new Uri("http://localhost:8000")
            });

        Host.AddServiceEndpoint(typeof(IModelData),
            new BasicHttpBinding(),
            "ModelData");

        Host.Open();    // Error Points Here!!!
    }

    public ArrayList GetData()
    {
        return Model.GetData();
    }

    public void CloseServer()
    {
        Host.Close();
    }
}

Here's my Client code:

[ServiceContract]
public interface IModelData
{
    [OperationContract]
    ArrayList GetData();
}

[ServiceBehavior(UseSynchronizationContext = false)]
public class ModelDataClient
{
    ChannelFactory<IModelData> HttpFactory;
    IModelData HttpProxy;

    public ModelDataClient()
    {
        HttpFactory = new ChannelFactory<IModelData>(
            new BasicHttpBinding(),
            new EndpointAddress("http://localhost:8000/ModelData"));

        HttpProxy = HttpFactory.CreateChannel();
    }

    public ArrayList GetData()
    {
        return HttpProxy.GetData();
    }
}

Here's the error I'm recieving (points to where I'm opening the ServiceHost):

The ChannelDispatcher at 'http://localhost:8000/ModelData' with contract(s) '"IModelData"' is unable to open its IChannelListener. 

P.S. I have been struggling to get delegates to work outside of something I've done in a tutorial. If anyone can suggest a better way that uses delegates instead of passing my form class into the other class that would be great.

¿Fue útil?

Solución

Yes, this is most likely related to namespace issues. For illustration issues, let's assume your server project's namespace is ServerApp, and your client's namespace is ClientApp. You define IModelData in both applications, which means you have ServerApp.IModelData and ClientApp.IModelData. Even though the code is identical, these are two separate interfaces (because of the namespace).

So you're trying to pass ClientApp.IModelData to the service, and it's expecting ServerApp.IModelData.

You can solve this by moving the interface IModelData to its own assembly and having the server app and the client app both reference this third assembly. That's what we do at work - all of our service contracts are in a separate assembly (two, actually, but that's a different story).

A couple of other things to note:

Unless your client is also hosting a service, you can remove the [ServiceContract] attribute from the class. Clients don't need that.

In your server app, what is Server.Scraper = this; for? It appears to be assigning the Form to a property Scraper in the service, but I don't see that property in your code. Additionally, services don't really use properties (I think I saw somewhere that you could do it, but it wasn't intuitive). I don't think you'd want to assign the entire form to the service, as service's in and of themselves don't usually have UIs - they supply data and receive data from the service.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top