Проблема с объектом в качестве параметра в REST API Service - PullRequest
0 голосов
/ 18 января 2012

РЕДАКТИРОВАТЬ: Очевидно, что у меня работает.Я тестировал с использованием xml, сгенерированного из сериализованного объекта, который не работал.Я только что начал возиться с этим и решил попробовать использовать динамический XML, который я создаю (как и здесь), и это сработало.Я думаю, может быть, это потому, что когда я пробовал это таким образом, прежде чем я не использовал те же пространства имен ... Однако, почему использование xml из сериализованного объекта не работает?Я заметил, что он использует другое пространство имен в XML, когда он создается из объекта.Почему это так?

Исходное сообщение: У меня проблема с передачей пользовательского объекта в API REST, который я создаю.Сейчас я просто пытаюсь проверить это, разместив объект типа Lead в методе WebInvoke.Мой сервис написан с WCF.Объект Lead находится в отдельном проекте библиотеки классов, который будет соответствовать уровню моей бизнес-логики.

Я публикую сообщения с использованием обычной страницы ASP .net.В этом разделе кода вы увидите, что я попытался создать xml двумя способами, вручную, а также сериализовав объект как xml и используя его в качестве данных POST.Ни одна из них не работает, и я получаю эту ошибку: Удаленный сервер возвратил ошибку: (400) Bad Request.

Я знаю, что служба настроена правильно, так как я могу позвонить и получить ответ отдругой метод WebInvoke, который я написал, это метод GET.

Вот соответствующий код: Код интерфейса службы:

[ServiceContract(Namespace = "http://www.mytestnamespace.com/test")]
public interface IRESTService
{
    [OperationContract]
    [WebInvoke(Method = "POST",
        UriTemplate = "leads",
        RequestFormat = WebMessageFormat.Xml,
        ResponseFormat = WebMessageFormat.Xml)]
    string AddLead(Lead lead);

    [OperationContract]
    [WebInvoke(Method = "GET",
        UriTemplate = "lead/{id}",
        ResponseFormat = WebMessageFormat.Xml)]
    string LeadData(string id);
}

Код службы:

public class RESTService : IRESTService
{
    public string AddLead(Lead lead)
    {
        return "AddLead Hit";
    }

    public string LeadData(string id)
    {
        return "LeadData was hit, id=" + id;
    }
}

Ведущий объект Код:

[DataContract(Name="Lead",
    Namespace = "http://www.mytestnamespace.com/test")]
public class Lead
{
    [DataMember(Name="FirstName")]
    public string FirstName { get; set; }
    [DataMember(Name = "LastName")]
    public string LastName { get; set; }
    [DataMember(Name = "Email")]
    public string Email { get; set; }
    [DataMember(Name = "Phone")]
    public string Phone { get; set; }
}

И, наконец, код, который я использую на странице aspx для публикации данных:

try
    {
        Lead l = new Lead();
        l.FirstName = "John";
        l.LastName = "Doe";
        l.Email = "John.Doe@gmail.com";
        l.Phone = "5555551234";

        XmlSerializer ser = new XmlSerializer(typeof(Lead));
        StringWriter sw = new StringWriter();
        ser.Serialize(sw, l);

        string s = sw.ToString();




        /*XmlDocument doc = new XmlDocument();
        XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "utf-8", null);

        XmlElement root = doc.CreateElement("Lead");
        root.SetAttribute("xmlns", "http://www.mytestnamespace.com/test");
        //root.SetAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
        doc.InsertBefore(dec, doc.DocumentElement);
        doc.AppendChild(root);

        XmlElement firstName = doc.CreateElement("FirstName");
        XmlElement lastName = doc.CreateElement("LastName");
        XmlElement email = doc.CreateElement("Email");
        XmlElement phone = doc.CreateElement("Phone");

        firstName.AppendChild(doc.CreateTextNode("John"));
        lastName.AppendChild(doc.CreateTextNode("Doe"));
        email.AppendChild(doc.CreateTextNode("John.Doe@gmail.com"));
        phone.AppendChild(doc.CreateTextNode("8885551234"));

        root.AppendChild(firstName);
        root.AppendChild(lastName);
        root.AppendChild(email);
        root.AppendChild(phone);*/

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri("http://localhost:54966/RESTService.svc/leads"));
        req.Method = "POST";
        req.ContentType = "application/xml";
        //byte[] formData = UTF8Encoding.UTF8.GetBytes(doc.InnerXml);
        byte[] formData = UTF8Encoding.UTF8.GetBytes(s);
        req.ContentLength = formData.Length;

        using (Stream post = req.GetRequestStream())
        {
            post.Write(formData, 0, formData.Length);
        }

        string result = null;
        using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
        {
            StreamReader reader = new StreamReader(resp.GetResponseStream());
            result = reader.ReadToEnd();
        }
    }
    catch (Exception exc)
    {
        throw exc;
    }

1 Ответ

1 голос
/ 26 апреля 2012

Хотя вы можете сериализовать типы IXmlSerializable, [Serializable], POCO и т. Д. С помощью DataContractSerializer, как если бы они были сериализованы с их собственными сериализаторами, обратное неверно. Вы не можете сериализовать / десериализовать типы [DataContract] с другими сериализаторами и все же получить результат, который вы действительно намереваетесь получить. В этом случае XmlSerializer полностью игнорирует атрибуты [DataContract], но не вызывает исключения. Это потому, что он предполагает, что он похож на другой тип POCO (простой старый объект C #) с открытыми полями и свойствами, и пытается сериализовать его с использованием этой модели.

Для получения дополнительной информации об этом см. Посты блога на http://blogs.msdn.com/b/sowmy/archive/2006/02/22/536747.aspx и http://blogs.msdn.com/b/sowmy/archive/2006/05/14/why-prevent-datacontract-ixmlserializable.aspx

Итак, решение здесь одно из двух: - Удалите DataContract и т. Д. Из типа DataContract и начните использовать [Serializable], IXmlSerializable, ISerializable, POCO или какой-либо другой механизм сериализации, который вы можете использовать с XmlFormatter или XmlSerializer

  • Удалите использование XmlSerializer и используйте вместо него DataContractSerializer.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...