Контракт сообщений WCF и потоковая передача

Я схожу с ума по пограничной линии, я работал с этим больше дня и до сих пор не понимаю, почему это не работает,

У меня есть MessageContract, который я использую для отправки потока, но получаю следующую ошибку:

Введите System.IO.FileStream с именем контракта данных FileStream: http://schemas.datacontract.org/2004/07/System.IO 'не ожидается. Добавьте любые типы, не известные статически, в список известных типов, например, используя атрибут KnownTypeAttribute или добавив их в список известных типов, переданный в DataContractSerializer.

[ServiceContract()]
public interface IContentService
{
    [OperationContract(), FaultContract(typeof(ContentFault))]
    PublishItemResponse PublishFile(PublishFileRequest request);
}


[MessageContract()]
public class PublishFileRequest
{ 
 [MessageHeader()]
 public FileInventoryItem Item {get;set;}

 [MessageHeader()]
 public Request Request  {get;set;}

 [MessageBodyMember()]
 public Stream FileContent {get;set;}
}



 [MessageContract()]
 public class Request
 {
  [MessageHeader()]
  public Guid AuthorizationToken { get; set; }

  [MessageHeader()]
  public string CoreVersion  { get; set; }

  [MessageHeader()]
  public string Password { get; set; }

  [MessageHeader()]
  public DateTime RequestTime { get; set; }

  [MessageHeader()]
  public string ComponentVersion { get; set; }

  [MessageHeader()]
  public string UserName  { get; set; }
 }



[MessageContract()]
[Serializable()]
public class FileInventoryItem : InventoryItemBase
{
 public Stream FileContent { get; set;}
}



[MessageContract()]
[KnownType(typeof(FileInventoryItem))]
[KnownType(typeof(FolderInventoryItem))]
[Serializable()]
public abstract class InventoryItemBase
{
 public List<string> Errors {get;set;}

 public List<string> Warnings  {get;set;}

 [MessageHeader()]
 public StagingAction Action {get;set;}

 [MessageHeader()]
 public string ContentXml  {get;set;}

 [MessageHeader()]
 public int ItemId {get;set;}

 [MessageHeader()]
 public ItemType ItemType { {get;set;}

 [MessageHeader()]
 public string Name  {get;set;}

 [MessageHeader()]
 public int ParentId {get;set;}

 [MessageHeader()]
 public Guid ParentUniqueId  {get;set;}

 [MessageHeader()]
 public Guid UniqueId  {get;set;}

 [MessageHeader()]
 public Guid Version  {get;set;}
}

Любая помощь приветствуется,


person kay.one    schedule 08.07.2010    source источник
comment
В ошибке упоминается System.IO.FileStream. В вашем ServiceContract нет FileStream. Почему?   -  person Arseni Mourzenko    schedule 09.07.2010
comment
[MessageBodyMember ()] public Stream FileContent {get; set;} то, что передается, является файловым потоком, унаследованным от Stream.   -  person kay.one    schedule 09.07.2010
comment
Унаследовано от Stream. Это проблема. Вы пробовали отправить только чистый Stream, чтобы проверить, работает ли он?   -  person Arseni Mourzenko    schedule 09.07.2010
comment
Не могу этого сделать, поскольку Stream - это абстрактный тип.   -  person kay.one    schedule 09.07.2010
comment
какое-либо окончательное решение с полным образцом исходного кода, работающим над этим?   -  person Kiquenet    schedule 07.06.2013
comment
Если вы не видели этот пост на SO, он может пролить свет на причину, по которой это не работает stackoverflow.com/ а / 1322817/132599.   -  person David Clarke    schedule 17.02.2014


Ответы (2)


WCF требует, чтобы сериализуемые типы точно соответствовали типам, объявленным в контракте. Вы можете обойти это, добавив KnownType, чтобы указать, что вы знаете, что будет использоваться определенный подтип (в этом случае вы должны добавить его в класс PublishFileRequest).

Однако, хотя это устранит первую ошибку, ваш код все равно не будет работать, поскольку потоки FileStream не сериализуемы.

person David Nelson    schedule 09.07.2010
comment
Файловые потоки не сериализуются с помощью серилизатора xml, они сериализуемы с помощью серилизатора messagecontract. У меня есть FileStream в приложении в изолированной среде, он просто не работает в этой конкретной настройке. - person kay.one; 12.07.2010
comment
Может быть, используя DAtacontract, а не messagecontract? - person Kiquenet; 07.06.2013

Объект FileStream указывает на файловую систему, к которой нельзя получить доступ с другого компьютера.

Вместо этого используйте MemoryStream для передачи данных. Вы можете использовать Stream.CopyTo (memoryStream) для копирования данных в объект MemoryStream.

person BluE    schedule 26.09.2018