有时rss编码不正确

时间:2015-04-11 18:42:12

标签: c# rss windows-phone

我正在为Windows Phone编写RSS feed阅读器项目。我使用下面的结构来阅读Feed。 它似乎对我跟踪的200多个输入正常工作 - 除了来自NASA的两个输入

"http://www.nasa.gov/rss/dyn/TWAN_vodcast.rss"
"http://www.nasa.gov/rss/dyn/TWAN_podcast.rss"

我经常遇到问题。不总是和不一样的饲料,但每周几次,而不是很好的utf-8文本rss饲料我得到非文字的东西开始(十进制)

31, 65533, 8, 0, 0.. 

奇怪的是,用例如同时阅读饲料Chrome始终显示出良好的文字效果。

我在这里缺少一些微不足道的东西吗? Chrome可以做的一些黑魔法,但Windows Phone不能?有什么方法我可以修复"在我的应用程序中Windows Phone失败了吗?出于兼容性原因,我正在为VS Express 2012上的WP7.8构建

(是的,我前一段时间通过电子邮件发送给饲主,但没有得到任何回复)

    public void GetFeed(string _RssUri)
    {
        WebClient wc = new WebClient();
        wc.OpenReadCompleted += wc_OpenReadCompleted;
        wc.OpenReadAsync(new Uri(_RssUri));
    }

    void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            using (StreamReader sr = new StreamReader(e.Result, true))
            {
                _feedString = sr.ReadToEnd();
            }
            Assert.IsTrue("0:60 1:63 2:120 3:109 4:108 5:32" == decodeStringContent(rssContent), "Feed does not start with '<?xml '");

            // doSomething(_feedString);
        }
    }

    public static string decodeStringContent(string _in, int _maxItems = 5)
    {
        string _decoding = "";
        int _i = 0;
        foreach (char x in _in)
        {
            if (_decoding != "") _decoding = _decoding + " ";
            _decoding = _decoding + _i++.ToString() + ":" + Convert.ToInt32(x);
            if (_maxItems > 0 && _i > _maxItems) break;
        }
        return _decoding;
    }

1 个答案:

答案 0 :(得分:1)

不确定您遇到的那些特殊问题。我在WP8商店中也有一个提要阅读器应用程序,当我预览新的提要时,我没有遇到这个特定的问题。我尝试了这两个提要,两者都运行正常。

我粘贴了一段可能对您有帮助的代码。很多你不需要的代码,但它应该为你提供一个基础。

using FeedModel.Classes;
using FeedModel.Helpers;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Xml.Linq;

namespace FeedModel
{
  public class FeedDiscovery
  {
    private delegate void HttpGetDelegate(IAsyncResult asynchronousResult);

    private enum FeedType { RSS, Atom, RDF }

    public void FindFeeds(SearchFeedsCallback callback, string searchString)
        {
            string url = "https://ajax.googleapis.com/ajax/services/feed/find";
            string args = string.Format("v=1.0&q={0}", searchString);
            httpGet(url, args, (IAsyncResult asynchronousResult) => 
                {
                    try
                    {
                        HttpWebRequest sidrequest = (HttpWebRequest)asynchronousResult.AsyncState;
                        // End the operation            
                        HttpWebResponse response = (HttpWebResponse)sidrequest.EndGetResponse(asynchronousResult);
                        Stream streamResponse = response.GetResponseStream();
                        StreamReader streamRead = new StreamReader(streamResponse);
                        string subscriptionContent = streamRead.ReadToEnd();
                        // Close the stream object            
                        streamResponse.Close();
                        streamRead.Close();
                        // Release the HttpWebResponse            
                        response.Close();

                        JObject jobj = JObject.Parse(subscriptionContent);
                        JArray subscriptions = (JArray)((JObject)jobj["responseData"])["entries"];

                        List<FDFeedItem> feeds =
                            (from f in subscriptions
                             select new FDFeedItem()
                             {
                                 Title = WebBrowserHelper.StripHtml((string)f["title"]),
                                 XmlUrl = (string)f["url"],
                                 Description = WebBrowserHelper.StripHtml((string)f["contentSnippet"]),
                                 HtmlUrl = (string)f["link"],
                             }).ToList();

                        callback(new SearchFeedsEventArgs(feeds)
                        {
                            Failed = false,
                            Error = "",
                        });
                       // return;
                    }
                    catch
                    {
                        callback(new SearchFeedsEventArgs(new List<FDFeedItem>())
                        {
                            Failed = true,
                            Error = "Failed",
                        });                    
                    }
                });
        }


    public void FeedPreview(FeedPreviewCallback callback, string url)
    {
      try
      {
        httpGet(url, "", (IAsyncResult asynchronousResult) =>
        {
          try
          {
            HttpWebRequest sidrequest = (HttpWebRequest)asynchronousResult.AsyncState;
            // End the operation            
            HttpWebResponse response = (HttpWebResponse)sidrequest.EndGetResponse(asynchronousResult);
            Stream streamResponse = response.GetResponseStream();
            StreamReader streamRead = new StreamReader(streamResponse);
            string subscriptionContent = streamRead.ReadToEnd();
            XDocument doc = XDocument.Parse(subscriptionContent);

            FeedType feedType = FeedType.RSS;
            if (doc.Root.ToString().StartsWith("<feed xmlns") || doc.Root.ToString().StartsWith("2005/Atom\">"))
              feedType = FeedType.Atom;

            List<Article> articles;
            string title = "";
            string description = "";

            switch (feedType)
            {
              case FeedType.RSS:
                articles = ParseRss(doc, out title, out description);
                break;
              case FeedType.RDF:
                articles = ParseRdf(doc, out title, out description);
                break;
              case FeedType.Atom:
                articles = ParseAtom(doc, out title, out description);
                break;
              default:
                throw new NotSupportedException(string.Format("{0} is not supported", feedType.ToString()));
            }
            FDFeedItem feed = new FDFeedItem();
            feed.Title = title;
            feed.Description = description;
            feed.XmlUrl = url;
            
            callback(new FeedPreviewEventArgs(articles, feed)
            {
              Failed = false,
              Error = ""
            });
          }
          catch
          {
            callback(new FeedPreviewEventArgs(new List<Article>(), new FDFeedItem())
            {
              Failed = true,
              Error = "Failed to get articles"
            });
          }
        });
      }
      catch
      {
        callback(new FeedPreviewEventArgs(new List<Article>(), new FDFeedItem())
        {
          Failed = true,
          Error = "Failed"
        });
      }
    }


    public void GetFeedDetails(FeedDetailsCallback callback, string url)
    {
      try
      {
        httpGet(url, "", (IAsyncResult asynchronousResult) =>
        {
          try
          {
            HttpWebRequest sidrequest = (HttpWebRequest)asynchronousResult.AsyncState;
            // End the operation            
            HttpWebResponse response = (HttpWebResponse)sidrequest.EndGetResponse(asynchronousResult);
            Stream streamResponse = response.GetResponseStream();
            StreamReader streamRead = new StreamReader(streamResponse);
            string subscriptionContent = streamRead.ReadToEnd();
            XDocument doc = XDocument.Parse(subscriptionContent);

            callback(new FeedsDetailsEventArgs(new FDFeedItem())
            {
              Failed = false,
              Error = ""
            });
          }
          catch
          {
            callback(new FeedsDetailsEventArgs(new FDFeedItem())
            {
              Failed = true,
              Error = "Failed to get feed"
            });
          }
        });
      }
      catch
      {

        callback(new FeedsDetailsEventArgs(new FDFeedItem())
        {
          Failed = true,
          Error = "Failed"
        });
      }
    }

    private void httpGet(string requestUrl, string getArgs, HttpGetDelegate httpGetResponse)
    {
      string url = requestUrl;
      if (getArgs != "")
        url = string.Format("{0}?{1}", requestUrl, getArgs);

      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
      request.Method = "GET";
      request.BeginGetResponse(new AsyncCallback(httpGetResponse), request);
    }








    /// <summary>
    /// Parses an Atom feed and returns a <see cref="IList&amp;lt;Item&amp;gt;"/>.
    /// </summary>
    private List<Article> ParseAtom(XDocument doc, out string title, out string description)
    {
      title = doc.Root.Elements().First(i => i.Name.LocalName == "title").Value;
      try
      {
        description = doc.Root.Elements().First(i => i.Name.LocalName == "subtitle").Value;
      }
      catch { description = ""; }

      try
      {

        var entries = from item in doc.Root.Elements().Where(i => i.Name.LocalName == "entry")
                      select new Article
                      {
                        Content = item.Elements().First(i => i.Name.LocalName == "content").Value,
                        Url = item.Elements().First(i => i.Name.LocalName == "link").Attribute("href").Value,
                        PublishedDate = ParseDate(item.Elements().First(i => i.Name.LocalName == "published").Value),
                        Title = item.Elements().First(i => i.Name.LocalName == "title").Value,
                        Summary = WebBrowserHelper.GetSummary(item.Elements().First(i => i.Name.LocalName == "content").Value),
                        CrawlTime = DateTime.ParseExact("01/01/1970", "dd/MM/yyyy", CultureInfo.InvariantCulture),
                        Author = item.Elements().First(i => i.Name.LocalName == "author").Elements().First(i=> i.Name.LocalName == "name").Value ,
                        Read = false,
                        Starred = false,
                        FeedProviderName = "NewsBlur",
                        OpenMode = ArticleOpenMode.UseContent,
                        Image = WebBrowserHelper.ExtractFirstImageFromHTML(item.Elements().First(i => i.Name.LocalName == "content").Value),

                      };
        return entries.ToList();
      }
      catch
      {
        return new List<Article>();
      }
    }

    /// <summary>
    /// Parses an RSS feed and returns a <see cref="IList&amp;lt;Item&amp;gt;"/>.
    /// </summary>
    private List<Article> ParseRss(XDocument doc, out string title, out string description)
    {
      title = "";
      description = "";
      try
      {
        //XDocument doc = XDocument.Load(url);
        // RSS/Channel/item
       var root = doc.Root.Descendants().First(i => i.Name.LocalName == "channel"); //.Elements() .First(i => i.Name.LocalName == "description").Value;
       title = root.Elements().First(i => i.Name.LocalName == "title").Value;
       description = root.Elements().First(i => i.Name.LocalName == "description").Value;

       var entries = from item in root.Elements().Where(i => i.Name.LocalName == "item")
                      select new Article
                      {
                        Content = item.Elements().First(i => i.Name.LocalName == "description").Value,
                        Url = item.Elements().First(i => i.Name.LocalName == "link").Value,
                        PublishedDate = ParseDate(item.Elements().First(i => i.Name.LocalName == "pubDate").Value),
                        Title = item.Elements().First(i => i.Name.LocalName == "title").Value,
                        Summary = WebBrowserHelper.GetSummary(item.Elements().First(i => i.Name.LocalName == "description").Value),
                        //Author = WebBrowserHelper.GetSummary(item.Elements().First(i => i.Name.LocalName == "creator").Value),
                        Author = "",
                        Read = false,
                        Starred = false,
                        FeedProviderName = "NewsBlur",
                        OpenMode = ArticleOpenMode.UseContent,
                        Image = WebBrowserHelper.ExtractFirstImageFromHTML(item.Elements().First(i => i.Name.LocalName == "description").Value),
                      };
        return entries.ToList();
      }
      catch (Exception e)
      {
        return new List<Article>();
      }
    }

    /// <summary>
    /// Parses an RDF feed and returns a <see cref="IList&amp;lt;Item&amp;gt;"/>.
    /// </summary>
    private List<Article> ParseRdf(XDocument doc, out string title, out string description)
    {
      title = "";
      description = "";
      try
      {
        //XDocument doc = XDocument.Load(url);
        // <item> is under the root
        var entries = from item in doc.Root.Descendants().Where(i => i.Name.LocalName == "item")
                      select new Article
                      {
                        Content = item.Elements().First(i => i.Name.LocalName == "description").Value,
                        FeedUrl = item.Elements().First(i => i.Name.LocalName == "link").Value,
                        PublishedDate = ParseDate(item.Elements().First(i => i.Name.LocalName == "date").Value),
                        Title = item.Elements().First(i => i.Name.LocalName == "title").Value,
                        Summary = WebBrowserHelper.GetSummary(item.Elements().First(i => i.Name.LocalName == "description").Value),
                        Image = WebBrowserHelper.ExtractFirstImageFromHTML(item.Elements().First(i => i.Name.LocalName == "description").Value),
                        OpenMode = ArticleOpenMode.UseContent,
                      };
        return entries.ToList();
      }
      catch
      {
        return new List<Article>();
      }
    }

    private DateTime ParseDate(string date)
    {
      DateTime result;
      if (DateTime.TryParse(date, out result))
        return result;
      else
      {
        int i = date.LastIndexOf(" ");
        if (i > date.Length - 6)
        {
          date = date.Substring(0, i).Trim();
          if (DateTime.TryParse(date, out result))
            return result;

        }
        return DateTime.MinValue;
      }
    }

    private string GetSummary(string content)
    {
      string lContent = content.Trim('\"');
      int contentLength = 800;
      if (lContent.Length < 800)
        contentLength = lContent.Length;
      string _localContent = "";
      try
      {
        _localContent = WebBrowserHelper.StripHtml(lContent.Substring(0, contentLength));
      }
      catch
      {
      }
      if (_localContent.Length > 150)
        _localContent = _localContent.Substring(0, 150) + "...";

      return _localContent;
    
    }
  }
}

​

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Globalization;

namespace FeedModel.Classes
{
  public enum ArticleOpenMode {OpenWebPage,UseContent, Mobilizer};
  public class Article
  {
    private string _id;
    protected DateTime _publishedDate;
    protected DateTime _crawlTime;
    private string _author;
    private string _title;
    private string _content;
    private string _summary;
    private string _url;
    protected bool _read;
    protected bool _starred;
    private string _rawDate;
    private string _rawCrawlTime;
    private ArticleOpenMode _openMode;
    protected List<string> _tags;
    private string _feedProviderName;
    private string _feedTitle;
    private string _feedUrl;
    private string _feedId;
    private string _image;
    private AccountTypes _accountType;

    public Article()
    {
      _tags = new List<string>();
      _image = "";
    }


    public ArticleOpenMode OpenMode
    {
      get { return _openMode; }
      set { _openMode = value; }
    }


    public bool Read
    {
      get { return _read; }
      set { _read = value; }
    }

    public bool Starred
    {
      get { return _starred; }
      set { _starred = value; }
    }

    public string Image
    {
      get { return _image; }
      set { _image = value; }
    }

    public string FeedProviderName
    {
      get { return _feedProviderName; }
      set { _feedProviderName = value; }
    }

    public string FeedTitle
    {
      get { return _feedTitle; }
      set { _feedTitle = value; }
    }

    public string FeedUrl
    {
      get { return _feedUrl; }
      set { _feedUrl = value; }
    }

    public string FeedId
    {
      get { return _feedId; }
      set { _feedId = value; }
    }

    public string Url
    {
      get { return _url; }
      set { _url = value; }
    }

    public string Content
    {
      get { return _content; }
      set { _content = value; }
    }

    public string Summary
    {
      get { return _summary; }
      set { _summary = value; }
    }

    public string Title
    {
      get { return _title; }
      set { _title = value; }
    }

    public string Author
    {
      get { return _author; }
      set { _author = value; }
    }

    public DateTime PublishedDate
    {
      get { return _publishedDate; }
      set { _publishedDate = value; }
    }

    public DateTime CrawlTime
    {
      get { return _crawlTime; }
      set { _crawlTime = value; }
    }

    public string Id
    {
      get { return _id; }
      set { _id = value; }
    }


    public List<string> Tags
    {
      get { return _tags; }
      set { _tags = value; }
    }

    public string RawPublishDate
    {
      get { return _rawDate; }
      set
      {
        Double seconds;
        _rawDate = value;
        try
        {
          seconds = Convert.ToDouble(_rawDate);
          DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
          _publishedDate = origin.AddSeconds(seconds);
        }
        catch
        {
          _publishedDate = DateTime.Now;
        }
      }
    }

    public string RawCrawlTime
    {
      get { return _rawCrawlTime; }
      set
      {
        Double seconds;
        _rawCrawlTime = value;
        //try
        //{
        //  seconds = Convert.ToDouble(_rawCrawlTime);
        //  DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        //  _crawlTime = origin.AddSeconds(seconds);
        //}
        //catch
        //{
          _crawlTime = DateTime.Now;
        //}
      }
    }

    public AccountTypes AccountType
    {
      get { return _accountType; }
      set { _accountType = value; }
    }


  }
}