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
в сервисе, но я не вижу это свойство в вашем коде. Кроме того, сервисы на самом деле не используют свойства (я думаю, я где-то видел, что вы можете сделать это, но это не было интуитивно понятно). Я не думаю, что вы захотите назначить всю форму службе, поскольку сами по себе службы обычно не имеют интерфейсов - они предоставляют данные и получают данные от службы.