C#修改多个字典值会引发错误
我使用HTMLAgilityPack下载一些页面,我还存储来自表单的cookie信息和登录信息。我遇到的问题是,我正在执行一个GET操作来获取cookie信息和表单详细信息,以便下一步它可以使用用户名和密码登录,然后我尝试设置用户名和密码输入字段的值,以便我可以发布到登录页面。输入字段存储在C#修改多个字典值会引发错误,c#,dictionary,error-handling,html-agility-pack,C#,Dictionary,Error Handling,Html Agility Pack,我使用HTMLAgilityPack下载一些页面,我还存储来自表单的cookie信息和登录信息。我遇到的问题是,我正在执行一个GET操作来获取cookie信息和表单详细信息,以便下一步它可以使用用户名和密码登录,然后我尝试设置用户名和密码输入字段的值,以便我可以发布到登录页面。输入字段存储在字典中。我可以更改其中一个字典值,但在更改之后,我会出现错误: “对象引用未设置为对象的实例。” 如果我尝试更改密码,然后更改用户名,则用户名会抛出错误,反之亦然。这是我使用的代码: class Main {
字典中。我可以更改其中一个字典值,但在更改之后,我会出现错误:
“对象引用未设置为对象的实例。”
如果我尝试更改密码,然后更改用户名,则用户名会抛出错误,反之亦然。这是我使用的代码:
class Main
{
private void testLogin()
{
BrowserSession b = new BrowserSession();
b.Get("login.html");
b.FormElements["email_address"] = @"email";
b.FormElements["password"] = "password";
string response = b.Post("index.php?main_page=login");
}
}
}
public class BrowserSession
{
private bool _isPost;
private HtmlDocument _htmlDoc;
/// <summary>
/// System.Net.CookieCollection. Provides a collection container for instances of Cookie class
/// </summary>
public CookieCollection Cookies { get; set; }
/// <summary>
/// Provide a key-value-pair collection of form elements
/// </summary>
public FormElementCollection FormElements { get; set; }
/// <summary>
/// Makes a HTTP GET request to the given URL
/// </summary>
public string Get(string url)
{
_isPost = false;
CreateWebRequestObject().Load(url);
return _htmlDoc.DocumentNode.InnerHtml;
}
/// <summary>
/// Makes a HTTP POST request to the given URL
/// </summary>
public string Post(string url)
{
_isPost = true;
CreateWebRequestObject().Load(url, "POST");
return _htmlDoc.DocumentNode.InnerHtml;
}
/// <summary>
/// Creates the HtmlWeb object and initializes all event handlers.
/// </summary>
private HtmlWeb CreateWebRequestObject()
{
HtmlWeb web = new HtmlWeb();
web.UseCookies = true;
web.PreRequest = new HtmlWeb.PreRequestHandler(OnPreRequest);
web.PostResponse = new HtmlWeb.PostResponseHandler(OnAfterResponse);
web.PreHandleDocument = new HtmlWeb.PreHandleDocumentHandler(OnPreHandleDocument);
return web;
}
/// <summary>
/// Event handler for HtmlWeb.PreRequestHandler. Occurs before an HTTP request is executed.
/// </summary>
protected bool OnPreRequest(HttpWebRequest request)
{
AddCookiesTo(request); // Add cookies that were saved from previous requests
if (_isPost) AddPostDataTo(request); // We only need to add post data on a POST request
return true;
}
/// <summary>
/// Event handler for HtmlWeb.PostResponseHandler. Occurs after a HTTP response is received
/// </summary>
protected void OnAfterResponse(HttpWebRequest request, HttpWebResponse response)
{
SaveCookiesFrom(response); // Save cookies for subsequent requests
}
/// <summary>
/// Event handler for HtmlWeb.PreHandleDocumentHandler. Occurs before a HTML document is handled
/// </summary>
protected void OnPreHandleDocument(HtmlDocument document)
{
SaveHtmlDocument(document);
}
/// <summary>
/// Assembles the Post data and attaches to the request object
/// </summary>
private void AddPostDataTo(HttpWebRequest request)
{
string payload = FormElements.AssemblePostPayload();
byte[] buff = Encoding.UTF8.GetBytes(payload.ToCharArray());
request.ContentLength = buff.Length;
request.ContentType = "application/x-www-form-urlencoded";
System.IO.Stream reqStream = request.GetRequestStream();
reqStream.Write(buff, 0, buff.Length);
}
/// <summary>
/// Add cookies to the request object
/// </summary>
private void AddCookiesTo(HttpWebRequest request)
{
if (Cookies != null && Cookies.Count > 0)
{
request.CookieContainer.Add(Cookies);
}
}
/// <summary>
/// Saves cookies from the response object to the local CookieCollection object
/// </summary>
private void SaveCookiesFrom(HttpWebResponse response)
{
if (response.Cookies.Count > 0)
{
if (Cookies == null) Cookies = new CookieCollection();
Cookies.Add(response.Cookies);
}
}
/// <summary>
/// Saves the form elements collection by parsing the HTML document
/// </summary>
private void SaveHtmlDocument(HtmlDocument document)
{
_htmlDoc = document;
FormElements = new FormElementCollection(_htmlDoc);
}
}
public class FormElementCollection : Dictionary<string, string>
{
/// <summary>
/// Constructor. Parses the HtmlDocument to get all form input elements.
/// </summary>
public FormElementCollection(HtmlDocument htmlDoc)
{
var inputs = htmlDoc.DocumentNode.SelectSingleNode("//div[@id = 'loginDefault']").Descendants("input");
foreach (var element in inputs)
{
string name = element.GetAttributeValue("name", "undefined");
string value = element.GetAttributeValue("value", "");
if (!name.Equals("undefined")) { Add(name, value); }
}
}
/// <summary>
/// Assembles all form elements and values to POST. Also html encodes the values.
/// </summary>
public string AssemblePostPayload()
{
StringBuilder sb = new StringBuilder();
foreach (var element in this)
{
string value = HttpUtility.UrlEncode(element.Value);
sb.Append("&" + element.Key + "=" + value);
}
return sb.ToString().Substring(1);
}
}
主类
{
私有void testLogin()
{
BrowserSession b=新建BrowserSession();
b、 获取(“login.html”);
b、 FormElements[“电子邮件地址”]=“电子邮件”;
b、 FormElements[“密码”]=“密码”;
string response=b.Post(“index.php?main_page=login”);
}
}
}
公共类浏览器会话
{
私人书店;
私人HtmlDocument_htmlDoc;
///
///System.Net.CookieCollection。为Cookie类的实例提供收集容器
///
公共CookieCollection Cookies{get;set;}
///
///提供表单元素的键值对集合
///
public formelement集合FormElements{get;set;}
///
///对给定URL发出HTTP GET请求
///
公共字符串获取(字符串url)
{
_isPost=false;
CreateWebRequestObject().Load(url);
返回_htmlDoc.DocumentNode.InnerHtml;
}
///
///向给定URL发出HTTP POST请求
///
公共字符串帖子(字符串url)
{
_isPost=true;
CreateWebRequestObject().Load(url,“POST”);
返回_htmlDoc.DocumentNode.InnerHtml;
}
///
///创建HtmlWeb对象并初始化所有事件处理程序。
///
私有HtmlWeb CreateWebRequestObject()
{
HtmlWeb web=新的HtmlWeb();
web.UseCookies=true;
web.PreRequest=新的HtmlWeb.PreRequestHandler(OnPreRequest);
web.PostResponse=新的HtmlWeb.PostResponseHandler(OnAfterResponse);
web.PreHandleDocument=新的HtmlWeb.PreHandleDocumentHandler(OnPreHandleDocument);
返回网页;
}
///
///HtmlWeb.PreRequestHandler.的事件处理程序。在执行HTTP请求之前发生。
///
受保护的bool OnPreRequest(HttpWebRequest请求)
{
AddCookiesTo(请求);//添加以前请求中保存的cookie
if(_isPost)AddPostDataTo(request);//我们只需要在post请求中添加post数据
返回true;
}
///
///HtmlWeb.PostResponseHandler.的事件处理程序在收到HTTP响应后发生
///
受保护的无效OnAfterResponse(HttpWebRequest请求,HttpWebResponse响应)
{
SaveCookiesFrom(响应);//为后续请求保存cookies
}
///
///HtmlWeb.PreHandleDocumentHandler.的事件处理程序。在处理HTML文档之前发生
///
预处理文档上的受保护无效(HtmlDocument文档)
{
保存HTMLDocument(文档);
}
///
///组装Post数据并附加到请求对象
///
私有void AddPostDataTo(HttpWebRequest请求)
{
字符串负载=FormElements.AssemblePostPayload();
byte[]buff=Encoding.UTF8.GetBytes(payload.tocharray());
request.ContentLength=buff.Length;
request.ContentType=“application/x-www-form-urlencoded”;
System.IO.Stream reqStream=request.GetRequestStream();
请求流写入(buff,0,buff.Length);
}
///
///向请求对象添加cookie
///
私有void AddCookiesTo(HttpWebRequest请求)
{
if(Cookies!=null&&Cookies.Count>0)
{
request.CookieContainer.Add(Cookies);
}
}
///
///将Cookie从响应对象保存到本地CookieCollection对象
///
私有void SaveCookiesFrom(HttpWebResponse响应)
{
如果(response.Cookies.Count>0)
{
如果(Cookies==null)Cookies=new CookieCollection();
Cookies.Add(response.Cookies);
}
}
///
///通过解析HTML文档保存表单元素集合
///
私有作废保存HtmlDocument(HtmlDocument文档)
{
_htmlDoc=文件;
FormElements=新的FormElementCollection(_htmlDoc);
}
}
公共类FormElementCollection:字典
{
///
///解析HtmlDocument以获取所有表单输入元素。
///
公共FormElementCollection(HtmlDocument htmlDoc)
{
var inputs=htmlDoc.DocumentNode.SelectSingleNode(“//div[@id='loginDefault']”)。子体(“输入”);
foreach(输入中的var元素)
{
字符串名称=element.GetAttributeValue(“名称”,“未定义”);
字符串值=element.GetAttributeValue(“值”,“值”);
如果(!name.Equals(“未定义”){Add(name,value);}
}
}
///
///将所有表单元素和值组合到POST。html也对这些值进行编码。
///
公共字符串AssemblePostPayload()
{
StringBuilder sb=新的StringBuilder();
foreach(本文件中的var元素)
{
字符串值=HttpUtility.UrlEncode(element.value);
sb.追加(“&”+元素.键+“=”+值);
}
返回sb.ToString()子字符串(1);
}
}
如果有任何帮助,我们将不胜感激。在调试过程中,请在调用b constractor后设置断点。
您会发现FormElements属性
为空
您需要在BrowserSession const中将其初始化