我正在为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;
}
答案 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&lt;Item&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&lt;Item&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&lt;Item&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; }
}
}
}