Проблема с передачей объекта между WCF и ASMX с использованием DataContracts

Я пытаюсь использовать ASMX/WCF для передачи объектов между сайтами (общедоступными/частными). Я могу передать сериализованный объект из моей частной службы ASMX в общедоступную службу WCF, но не могу десериализовать объект. Код ниже, за которым следует ошибка.

Служба WCF, которая вызывает частную службу ASMX.

[WebGet(UriTemplate = "{part}")]
public Distributor GetDistributorInventory(string part)
{
    const string url = "http://www.site.com/service/lookup.asmx/StockCheck?part=" + part;
    //This is a wrapper for a HttpWebRequest that returns a string
    string results = WebHelper.HttpRequest("GET", "text/xml", null, url, new CookieContainer());  
    byte[] byteArray = Encoding.ASCII.GetBytes(results);
    MemoryStream stream = new MemoryStream(byteArray);
    DataContractSerializer deserialize = new DataContractSerializer(typeof(Distributor));
    return (Distributor)deserialize.ReadObject(stream);
}

Контракт, используемый как в государственных, так и в частных службах

[DataContract(Namespace = "http://www.site.com/Services/", Name = "Inventory")]
public class Inventory
{
    [DataMember(Order = 1)]
    public string MPN{ get; set; }
    [DataMember(Order = 2)]
    public string DataSheetURL { get; set; }
    [DataMember(Order = 3)]
    public List<Distributor> Stock { get; set; }
}

[DataContract(Namespace = "http://www.site.com/Services/", Name = "Distributor")]
public class Distributor
{
    [DataMember(Order = 1)]
    public string Name { get; set; }
    [DataMember(Order = 2)]
    public string Part { get; set; }
    [DataMember(Order = 3)]
    public int Quantity { get; set; }
    [DataMember(Order = 4)]
    public string URL { get; set; }
}

Сообщение об ошибке:

Ошибка в строке 1, позиция 166. Ожидается элемент «Дистрибьютор» из пространства имен «http://www.site.com/Services/».. Обнаружен «Элемент» с именем «Инвентарь», пространство имен «http://www.site. com/Услуги/'.

Я мог бы пойти по этому пути совершенно неправильно, поэтому предложения по лучшему подходу (с образцом) будут очень признательны. Моя конечная цель — передавать объекты между службами WCF и WCF или ASMX с использованием пользовательских объектов и контрактов данных.


person Zachary    schedule 17.03.2011    source источник


Ответы (3)


Похоже, он пытается десериализоваться как Distributor, но ответ на вызов StockCheck возвращает Inventory.

person CyberDude    schedule 17.03.2011
comment
Хороший звонок, это не решило проблему, но это была проблема. Хорошая находка, спасибо! - person Zachary; 17.03.2011

Служба asmx, вероятно, не использует DataContractSerialiser. здесь короткое видео о том, как выполнить пользовательскую сериализацию в службе ASMX.

Или вы можете десериализовать в службе WCF, используя тот же сериализатор, что и служба asmx (XmlSerialiser?)

Другой вариант — использовать сериализатор Json. Здесь есть пример.

person Preet Sangha    schedule 17.03.2011

Вот окончательное решение, которое я нашел для выполнения этой работы с наименьшим объемом работы.

  1. Я переключился с передачи моего объекта в виде XML на JSON (это была моя конечная цель, хотя я начал с XML)

  2. После получения моего объекта JSON я заметил, что у него есть оболочка «d:» и свойство «__type:», которое добавляется. Зная, что их нужно удалить, я решил найти общий способ удаления элементов.

  3. Мое общее решение состояло в том, чтобы использовать этот код/статью на Codeplex с методами расширения, выполняющими очистку с помощью Reg Ex. Очень простой.

Вот мой результирующий код:

[WebGet(UriTemplate = "{part}")]
public Distributor GetDistributorInventory(string part)
{
  const string url = "http://www.site.com/service/lookup.asmx/StockCheck";
  string results = WebHelper.HttpRequest("POST", "application/json; charset=utf-8", "{part: " + part + "}", url, new CookieContainer());

  Inventory inventory = new JavaScriptSerializer().CleanAndDeserialize<Inventory>(results);

  return inventory;
}

Еще одним преимуществом этого решения является возможность конвертировать объект независимо от пространства имен. Это приводит к возможности использовать объект «sender.Inventory» в моей исходной службе ASMX и объект «receiver.Inventory» в моей службе WCF, где я собираюсь использовать объект.

person Zachary    schedule 17.03.2011