Передача производного класса в метод веб-службы, который принимает абстрактный тип - PullRequest
2 голосов
/ 21 апреля 2009

У меня странная проблема, из-за которой у меня все в голове.

У меня есть следующие классы, определенные в одном проекте:

public abstract class AbstractUnitModel {

      public void executeRemoteModel(){}

}

//this class also implements a seperate interface, but I dont think that is the issue
public class BlastFurnaceUnitModel : AbstractUnitModel, IUnitModel {}

Теперь, если я попробую что-то вроде этого, оно будет работать как положено:

class Class1
{

    public void method1() {

        BlastFurnaceUnitModel b = new BlastFurnaceUnitModel();
        method2(b);
    }

    public void method2(AbstractUnitModel a) {}

 }

Теперь у меня есть другой проект, который предоставляет веб-метод. Этот метод принимает AbstractUnitModel и выполняет его удаленно, а затем отправляет результаты обратно клиенту. Итак, на сервере у меня есть это:

 [WebMethod]
 public AbstractUnitModel remotelyExecuteUnitModel(UnitModelWrapperInterface.AbstractUnitModel unitModel)
        {

           unitModel.executeRemoteModel();
           return unitModel;

         }

А на клиенте у меня это:

   public void remoteExecution() {

                var unitModelWebService = new UnitModelRemoteServer.RemoteModelExecutionWebService();
                unitModelWebService.remotelyExecuteUnitModelCompleted += new UnitModelRemoteServer.remotelyExecuteUnitModelCompletedEventHandler(remoteExecutionCompleted);
                unitModelWebService.remotelyExecuteUnitModelAsync(this.remoteBF);
            }

Но мой проект не скомпилируется, и я получаю следующие ошибки: Ошибка 109: лучшее совпадение перегруженного метода для 'CalibrationClient.UnitModelRemoteServer.RemoteModelExecutionWebService.remotelyExecuteUnitModelAsync (CalibrationClient.UnitModelRemoteServer.AbstractUnitModel) * недопустимы * аргументы недопустимы

Ошибка 110 Аргумент '1': невозможно преобразовать из 'UnitModelWrapperInterface.BlastFurnaceUnitModel' в 'CalibrationClient.UnitModelRemoteServer.AbstractUnitModel'

Я не могу понять, почему это происходит. У меня есть ссылки в проекте сервера на пространство имен, где определен AbstractUnitModel. Единственное, что показалось мне немного странным, это то, что он использует AbstractUnitModel из пространства имен 'CalibrationClient', а не UnitModelWrapperInterface. Кажется, что когда VS генерирует прокси для веб-службы на клиенте, он создает частичную абстрактную реализацию AbstractUnitModel. Это источник моей проблемы? Если так, как я мог бы исправить это?

редактировать для решения: Как указывалось, клиент должен знать обо всех классах, которые могут быть отправлены по проводам. Я решил эту проблему, удалив сгенерированные прокси-классы и ссылаясь на общую библиотеку. Не идеально, но достаточно хорошо в этой ситуации.

Ответы [ 3 ]

1 голос
/ 21 апреля 2009

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

Если вы хотите избежать этого, лучше всего использовать WCF. Это также касается полиморфных возвращаемых объектов, поскольку веб-сервисы также не могут справиться с полиморфизмом (поэтому тип возвращаемого значения метода remotelyExecuteUnitModel всегда AbstractUnitModel.

1 голос
/ 21 апреля 2009

Вы можете попробовать [XmlInclude]:

[XmlInclude(typeof(BlastFurnaceUnitModel))]
public abstract class AbstractUnitModel {...}

Стоит попробовать, хотя бы ...

(редактировать) Или на уровне метода:

[WebMethod(), XmlInclude(typeof(BlastFurnaceUnitModel))]
public AbstractUnitModel remotelyExecuteUnitModel(...) {...}

(менее уверен насчет второго)

0 голосов
/ 21 апреля 2009

Класс, представленный в вашем WebService, создается в другом пространстве имен внутри ссылки на службу.

Я обычно создаю метод, подобный

WebServiceReferenceNS.AbstractUnitModel ToWebServiceModel(AbstractUnitModel unitModel)
{
}

для подготовки классов к WebService. Но я хотел бы посмотреть, есть ли более элегантное решение.

...