Исключение ReadAsDataContract при чтении пространства имен - PullRequest
2 голосов
/ 02 февраля 2010

Я пытаюсь использовать REST API в твиттере, упомянутый по этой ссылке , используя стартовый комплект WCF REST, упомянутый по этой ссылке .

Я использую те же объекты в DataContract, которые упоминались в статье - statusList и status.

[assembly: ContractNamespace("", ClrNamespace = "TwitterShell")]
[CollectionDataContract(Name = "statuses", ItemName = "status")]
public class statusList : List<status> { }
public class user
{
    public string id;
    public string name;
    public string screen_name;
}
public class status
{
    public string id;
    public string text;
    public user user;
}

Я читаю содержимое XML с помощью метода ReadAsDataContract ().

HttpClient http = new HttpClient("http://twitter.com/statuses/");
http.TransportSettings.Credentials =
    new NetworkCredential("{username}", "{password}");
HttpResponseMessage resp = http.Get("friends_timeline.xml");
resp.EnsureStatusIsSuccessful();
statusList sList = resp.Content.ReadAsDataContract<statusList>();

И я получаю следующее исключение. Я не определил следующее пространство имен вообще.

Ошибка в строке 1 позиции 24. Ожидается элемент 'statuses' из пространства имен 'http://schemas.datacontract.org/2004/07/sitename'.. Обнаружен' Element 'с именем' statuses ', пространство имен' '.

Пожалуйста, помогите. Спасибо.

Ответы [ 2 ]

3 голосов
/ 02 февраля 2010

Только не делай этого. Вам будет тяжело, если вы попытаетесь использовать Datacontracts и контракты на эксплуатацию для доступа к услугам, не относящимся к wcf.

Хорошо, я полагаю, это было немного несправедливо, когда вы оставляли вас без присмотра, поэтому попробуйте следующее:

var response = client.Get("http://twitter.com/statuses/friends_timeline.xml");

var statuses = response.Content.ReadAsXElement();

var statusQuery = from st in statuses.Elements("status")
                  select new status {
                                id = st.Element("id").Value,
                                text = st.Element("text").Value,
                                user = (from us in st.Elements("user")
                                        select new user {
                                             id = us.Element("id").Value,
                                             name = us.Element("name").Value,
                                             screen_name = us.Element("screen_name").Value
                                                         }).FirstOrDefault()
                                      };
var statuses = statusQuery.ToList();

Использование Linq to XML для создания объектов из XML-документа позволяет избежать магии сериализаторов и полностью контролировать имена и типы данных объектов на стороне клиента. Было бы действительно легко обернуть это как новый метод расширения HttpContent, чтобы вы могли просто сделать:

var statuses = response.Content.ReadAsTwitterStatuses();
0 голосов
/ 10 февраля 2011

Я наткнулся на ваш пост в поисках ответов на ту же проблему и смог найти решение для того, что вы ищете, если вы хотите отказаться от подхода LINQ to XML.

1) Убедитесь, что вы аннотировали свой класс Status следующим украшением

[DataContract (Namespace = "")]

Указав вышеуказанную аннотацию, вы переопределяете пространство имен из пространства имен по умолчанию вашего класса. Это должно исправить вашу проблему с пространством имен.

2) Для решения проблем с нулями (с которыми я тоже сталкивался) порядок ваших полей очень важен. Когда ваши объекты десериализованы, это делается в алфавитном порядке. Вы можете упорядочить поля в соответствии с порядком входящего XML, используя свойство Order в аннотации DataMember.

1010 *, например *

[DataMember (Order = 1)]
public string text

и т.д ...

...