Channeldispatcher не может открыть свой ichannellistener

Я начинаю с WCF. Я создал два консольных приложения (серверное и клиентское), которые работают без каких-либо проблем, но после их перемещения в формы у меня возникают всевозможные проблемы. Я посмотрел здесь и в других местах в сети, я не могу найти ничего, что может помочь мне с моей проблемой. Я, честно говоря, не понимаю проблему, но думаю, что это как-то связано с моими типами данных (они находятся в разных пространствах имен)?

Вот мой код сервера:

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();
    }
}

Вот мой код клиента:

[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();
    }
}

Вот ошибка, которую я получаю (указывает на то, где я открываю ServiceHost):

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

PS Я изо всех сил пытался заставить делегатов работать вне того, что я сделал в учебнике. Если кто-то может предложить лучший способ, который использует делегаты вместо передачи моего класса формы в другой класс, это было бы здорово.

1 ответ

Решение

Да, это, скорее всего, связано с проблемами пространства имен. Для иллюстрации проблемы предположим, что пространство имен вашего сервера проекта ServerAppи пространство имен вашего клиента ClientApp, Вы определяете IModelData в обоих приложениях, что означает, что у вас есть ServerApp.IModelData а также ClientApp.IModelData, Даже если код идентичен, это два отдельных интерфейса (из-за пространства имен).

Итак, вы пытаетесь пройти ClientApp.IModelData к сервису, и он ожидает ServerApp.IModelData,

Вы можете решить эту проблему, переместив интерфейс IModelData в свою собственную сборку, и серверное приложение и клиентское приложение ссылаются на эту третью сборку. Это то, что мы делаем на работе - все наши сервисные контракты находятся в отдельной сборке (на самом деле два, но это другая история).

Несколько других вещей, чтобы отметить:

Если ваш клиент также не размещает службу, вы можете удалить [ServiceContract] атрибут из класса. Клиентам это не нужно.

В приложении вашего сервера, что является Server.Scraper = this; за? Похоже, что назначение формы для свойства Scraper в сервисе, но я не вижу это свойство в вашем коде. Кроме того, сервисы на самом деле не используют свойства (я думаю, я где-то видел, что вы можете сделать это, но это не было интуитивно понятно). Я не думаю, что вы захотите назначить всю форму службе, поскольку сами по себе службы обычно не имеют интерфейсов - они предоставляют данные и получают данные от службы.

Другие вопросы по тегам