开发者

ReadAsDataContract exception while reading namespace

I'm trying to consume twitter's REST api mentioned at 开发者_如何学Pythonthis link using WCF REST starter kit mentioned at this link.

I'm using the same objects in DataContract as mentioned in the article - statusList and 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;
}

I'm reading the XML contents using ReadAsDataContract() method.

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>();

And I get the following exception. I have not defined the following namespace at all.

Error in line 1 position 24. Expecting element 'statuses' from namespace 'http://schemas.datacontract.org/2004/07/sitename'.. Encountered 'Element' with name 'statuses', namespace ''.

Please help. Thanks.


Just don't do it. You are in for a world of pain if you try using Datacontracts and operation contracts to access non-wcf services.

Ok, so I guess that was a bit unfair leaving you high and dry without an alternative, so try this:

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();

Using Linq to XML to create objects from the XML document allows you to avoid the magic of serializers and completely control the names and datatypes of your client side objects. It would be really easy to wrap this as a new HttpContent extension method so that you could simply do:

var statuses = response.Content.ReadAsTwitterStatuses();


I came across your post searching for answers to the same problem and I was able to find a solution for what you are looking for if you want to forgo the LINQ to XML approach.

1) Make sure you annotate your Status class with the following decoration

[DataContract (Namespace = "")]

By specifying the above annotation, you are overriding the namespace from the default namespace of your class. This should fix your namespace problem.

2) To address the issues of nulls (which I also experienced), order of your fields are very important. When your objects are deserialized, it is done in alphabetically order. You can order your fields to match the order of the incoming XML using the Order property on the DataMember annotation.

e.g.

[DataMember (Order = 1)]
public string text

etc ...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜