检查URL是否为有效的订阅源

6
我正在使用Argotic Syndication Framework处理订阅源。但问题是,如果我向Argotic传递一个无效的URL(例如:http://stackoverflow.com 是一个html页面,不是订阅源),程序会卡住(我指的是,Argotic会陷入无限循环)。那么,如何检查一个URL是否指向有效的订阅源?
4个回答

7

从.NET 3.5开始,您可以使用以下内容。如果它不是有效的 feed,则会引发异常。

using System.Diagnostics;
using System.ServiceModel.Syndication;
using System.Xml;

public bool TryParseFeed(string url)
{
    try
    {
        SyndicationFeed feed = SyndicationFeed.Load(XmlReader.Create(url));

        foreach (SyndicationItem item in feed.Items)
        {
            Debug.Print(item.Title.Text);
        }
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

或者您可以尝试自己解析该文档:

string xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<event>This is a Test</event>";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);

那么请尝试检查根元素。它应该是feed元素,并且具有"http://www.w3.org/2005/Atom"命名空间:

<feed xmlns="http://www.w3.org/2005/Atom" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:re="http://purl.org/atompub/rank/1.0">

References: http://msdn.microsoft.com/en-us/library/system.servicemodel.syndication.syndicationfeed.aspx http://dotnet.dzone.com/articles/systemservicemodelsyndication


由于我的项目是一个Web应用程序,因此我不能信任头内容。有人可能会提供无效的反馈,但有效的XML和有效的根元素,那么我的应用程序就会挂起...:( - Mahdi Ghiasi
谢谢更新。但是有一个问题:System.ServiceModel.Syndication 支持哪些订阅格式? - Mahdi Ghiasi
在Atom 1.0中使用<feed>,在RSS 2.0中使用<rss>。http://msdn.microsoft.com/zh-cn/library/system.servicemodel.syndication.syndicationfeed.aspx - Akira Yamamoto
你的方法的优点是它不需要任何网络请求来确定其是否有效。但缺点是,Argotic支持更多的Feed类型,而System.ServiceModel.Syndication则不支持。 - Mahdi Ghiasi
@AkiraYamamoto 使用SyndicationFeed.Load()的问题在于,它经常会在“有效”的rss和atom源上遇到dtd错误。问题是该源可能根据规范来说是“无效”的,但对使用它们的应用程序来说却是有效的,因此SyndicationFeed.Load()会排除很多好的源。 - Matthew

2

谢谢。看来你的答案是最好的。但是你能再解释一下SOAP API吗?如何联系该API?是否可以使用GET请求调用该API? - Mahdi Ghiasi
@MahdiGhiasi 请查看此文章 - http://msdn.microsoft.com/zh-cn/library/ff512390.aspx 如果不清楚,我稍后会创建一个示例。 - Dmitry Khryukin
如果您能提供一个示例,那就太好了 :) 谢谢 - Mahdi Ghiasi
@MahdiGhiasi 好的。9-10小时后我会有空处理这个事情。 - Dmitry Khryukin
这项服务有一个限制:每秒只能发送1个请求。因此,我无法从服务器端向该服务发出请求。关于客户端,它也不允许使用ajax请求:http://stackoverflow.com/questions/11997256/call-a-external-web-page-cross-domain-with-javascript ,难道没有任何方法可以从客户端使用该服务吗? - Mahdi Ghiasi

1

你可以检查内容类型,它必须是text/xml。参见this question以查找内容类型。

你可以使用这段代码:

var request = HttpWebRequest.Create("http://www.google.com") as HttpWebRequest;
if (request != null)
{
    var response = request.GetResponse() as HttpWebResponse;

    string contentType = "";

    if (response != null)
        contentType = response.ContentType;
}

感谢问题的答案

更新

要检查是否为feed地址,您可以使用W3C Feed Validation服务。

更新2

如BurundukXP所说,它有一个SOAP API。 要使用它,请阅读这个问题的答案


1
每个XML都不是一个Feed。另外,请阅读我对其他答案的评论。 - Mahdi Ghiasi
@ahmadalishafiee - 你的核心陈述:“它必须是text/xml”是不正确的。首先,任何响应都可以指示任何内容类型,因此仅凭该结果并不具有权威性。此外,text/rss+xml是RSS提要的有效内容类型。 - Matthew

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接