这是班级:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using System.Net;
namespace GatherLinks
{
/// <summary>
/// A result encapsulating the Url and the HtmlDocument
/// </summary>
class WebPage
{
public Uri Url { get; set; }
/// <summary>
/// Get every WebPage.Internal on a web site (or part of a web site) visiting all internal links just once
/// plus every external page (or other Url) linked to the web site as a WebPage.External
/// </summary>
/// <remarks>
/// Use .OfType WebPage.Internal to get just the internal ones if that's what you want
/// </remarks>
public static IEnumerable<WebPage> GetAllPagesUnder(Uri urlRoot)
{
var queue = new Queue<Uri>();
var allSiteUrls = new HashSet<Uri>();
queue.Enqueue(urlRoot);
allSiteUrls.Add(urlRoot);
while (queue.Count > 0)
{
Uri url = queue.Dequeue();
HttpWebRequest oReq = (HttpWebRequest)WebRequest.Create(url);
oReq.UserAgent = @"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5";
HttpWebResponse resp = (HttpWebResponse)oReq.GetResponse();
WebPage result;
if (resp.ContentType.StartsWith("text/html", StringComparison.InvariantCultureIgnoreCase))
{
HtmlDocument doc = new HtmlDocument();
try
{
var resultStream = resp.GetResponseStream();
doc.Load(resultStream); // The HtmlAgilityPack
result = new Internal() { Url = url, HtmlDocument = doc };
}
catch (System.Net.WebException ex)
{
result = new WebPage.Error() { Url = url, Exception = ex };
}
catch (Exception ex)
{
ex.Data.Add("Url", url); // Annotate the exception with the Url
throw;
}
// Success, hand off the page
yield return new WebPage.Internal() { Url = url, HtmlDocument = doc };
// And and now queue up all the links on this page
foreach (HtmlNode link in doc.DocumentNode.SelectNodes(@"//a[@href]"))
{
HtmlAttribute att = link.Attributes["href"];
if (att == null) continue;
string href = att.Value;
if (href.StartsWith("javascript", StringComparison.InvariantCultureIgnoreCase)) continue; // ignore javascript on buttons using a tags
Uri urlNext = new Uri(href, UriKind.RelativeOrAbsolute);
// Make it absolute if it's relative
if (!urlNext.IsAbsoluteUri)
{
urlNext = new Uri(urlRoot, urlNext);
}
if (!allSiteUrls.Contains(urlNext))
{
allSiteUrls.Add(urlNext); // keep track of every page we've handed off
if (urlRoot.IsBaseOf(urlNext))
{
queue.Enqueue(urlNext);
}
else
{
yield return new WebPage.External() { Url = urlNext };
}
}
}
}
}
}
///// <summary>
///// In the future might provide all the images too??
///// </summary>
//public class Image : WebPage
//{
//}
/// <summary>
/// Error loading page
/// </summary>
public class Error : WebPage
{
public int HttpResult { get; set; }
public Exception Exception { get; set; }
}
/// <summary>
/// External page - not followed
/// </summary>
/// <remarks>
/// No body - go load it yourself
/// </remarks>
public class External : WebPage
{
}
/// <summary>
/// Internal page
/// </summary>
public class Internal : WebPage
{
/// <summary>
/// For internal pages we load the document for you
/// </summary>
public virtual HtmlDocument HtmlDocument { get; internal set; }
}
}
}
它永远不会停在这条线上:
public Uri Url { get; set; }
永远不要停止在这堂课的其他任何一行。只有当我删除该行:
public Uri Url { get; set; }
然后停在其他线路上。但我不明白为什么它停在第一线?我该如何解决?
我尝试过阅读有关自动属性但我不明白它是什么,我不想在这个类中使用它。
答案 0 :(得分:1)
not supported上的断点为auto-implemented properties。尝试在GetAllPagesUnder
方法的第一行设置它。
答案 1 :(得分:1)
将断点添加到声明此类的位置。
WebPage wp =new WebPage();
因为Asif在上面说过,它不会在声明中停止。
或者在声明Class设置Url变量
之后wp.Url="blahblahblah.html";
编辑:我不知道断点不能处理自动属性。
改变你的
public Uri Url{get;set;}
到
private Uri _Url=new Uri();
public Url URL{get{return _Url;}set{_Url = value;}}
你在这里做的是创建一个私有变量名_Url并使用属性Url访问它
使用
Url="blahblahblah";
与您目前正在使用它相同
答案 2 :(得分:0)
你的问题非常模糊 - 但我预感到你正在打电话的某个地方:
var results = WebPage.GetAllPagesUnder([some uri]);
你是否期望在调用该方法时遇到断点?
它不会 - 它产生一个普查员。在您foreach
可枚举之前,代码实际上并没有做任何事情;或者可能通过ToArray
,ToList
或类似内容加载它。
至于自动属性,你不能断点 - 但是你不应该 - 只需要断开设置属性的代码。如果确实想要,请坚持使用私有支持字段并手动实现该属性。如果做不到这一点,给类一个构造函数,它接受Uri
并设置它,然后你断点。
答案 3 :(得分:0)
您可以在Url
属性设置断点,就像described here一样。
设置断点的标准方法不适用于自动属性。