C# WinForm WebBrowser 控件常用操作指南
在C# WinForm开发中,WebBrowser控件常用于集成第三方Web页面或展示内部系统。本文详细梳理了该控件在实际项目中的关键用法,包括C#代码与JavaScript脚本的双向通信、Session Cookie的处理机制,以及通过HttpWebRequest实现自动化网页登录的方法。
WebBrowser双向通信与权限配置
要实现WinForm程序与加载的HTML页面之间的数据交换,首先需要解除 COM 互操作的沙箱限制。
第1步:启用 ObjectForScripting
为了让 JavaScript 能直接调用 C# 类中的方法,必须在 Form 加载时设置 ObjectForScripting 属性,并授予完全信任权限。
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
[ComVisibleAttribute(true)]
public partial class frmWebData : Form
{
public frmWebData()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
// 将当前窗体对象暴露给脚本
wbService.ObjectForScripting = this;
base.OnLoad(e);
}
}
第2步:后台调用 JS 函数
在网页加载完成后,可通过 Document.InvokeScript 触发前端定义的函数,例如用于显示错误提示:
<script type="text/javascript">
function ErrorMessage(message) {
document.getElementById("error").innerText = message;
}
</script>
C# 后台实现逻辑:
static string ErrorMsg = string.Empty;
private void wbService_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (!string.IsNullOrEmpty(ErrorMsg))
{
wbService.Document.InvokeScript("ErrorMessage", new object[] { string.Format("操作失败,原因:{0}!", ErrorMsg) });
}
}
第3步:JS 调用后台方法
前端 HTML 可通过 window.external.MethodName() 触发 C# 公共方法:
<a onclick="window.external.DoSvrWebDbBack()">刷新/回调</a>
对应的 C# 处理方法:
public void DoSvrWebDbBack()
{
try
{
// 执行具体业务逻辑...
}
catch (TimeoutException)
{
ErrorMsg = "超时,请稍候再尝试!";
}
catch (Exception ex)
{
ErrorMsg = ex.Message.ToString();
}
}
Cookie 管理与 HttpWebRequest 模拟登录
在处理需要身份验证的 Web 页面时,正确传递 Session ID 是关键。除了依赖 WebBrowser 自带的缓存,也可以手动设置 Cookie 或使用独立的 HTTP 请求模块进行验证。
第4步:使用 P/Invoke 手动设置 Cookie
通过调用 wininet.dll 的 InternetSetCookie API,可以绕过浏览器自动管理,强制注入指定的 Session Cookie:
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool InternetSetCookie(string urlName, string cookieName, string cookieData);
// 使用示例
Cookie _cookie = BaseWinForm.LoginMessage.SessionID2;
string refererUrl = BaseWinForm.LoginMessage.SvrWebDbLoingUrl;
string targetUrl = BaseWinForm.LoginMessage.SvrWebDbBack;
InternetSetCookie(targetUrl, "ASP.NET_SessionId", _cookie.Value);
wbService.Navigate(targetUrl, null, null, string.Format("Referer:{0}", refererUrl));
第5步:HttpWebRequest 封装与凭证创建
对于复杂的 POST 请求,建议封装一个工具类来处理参数编码和响应接收。以下工具支持自定义请求规则和凭证生成:
public class HttpWebRequestToolV2
{
public delegate HttpWebRequest RequestRule(string url);
/// <summary>
/// 发起 HttpWebResponse 请求
/// </summary>
public static HttpWebResponse CreateHttpWebRequest(string url, byte[] credentials, RequestRule httpWebRequestRule)
{
if (string.IsNullOrEmpty(url)) throw new ArgumentNullException("url");
HttpWebRequest _request = null;
if (httpWebRequestRule != null)
{
_request = httpWebRequestRule(url);
}
else
{
_request = WebRequest.Create(url) as HttpWebRequest;
_request.Method = "POST";
_request.ContentType = "application/x-www-form-urlencoded";
_request.CookieContainer = new CookieContainer();
}
if (credentials != null)
{
_request.ContentLength = credentials.Length;
using (var requestStream = _request.GetRequestStream())
{
requestStream.Write(credentials, 0, credentials.Length);
}
}
return _request.GetResponse() as HttpWebResponse;
}
/// <summary>
/// 将字典转为 URL Encoded 字节流
/// eg: UserName=admin&PassWord=123
/// </summary>
public static byte[] CreateCredentials(IDictionary<string, string> credentials, Encoding encoding)
{
if (credentials == null || credentials.Count == 0 || encoding == null)
{
throw new ArgumentException("Invalid parameters");
}
StringBuilder _credentials = new StringBuilder();
foreach (KeyValuePair<string, string> credential in credentials)
{
_credentials.AppendFormat("{0}={1}&", credential.Key, credential.Value);
}
string result = _credentials.ToString().TrimEnd('&');
return encoding.GetBytes(result);
}
}
第6步:网页登录验证流程
结合上述工具,可以实现完整的登录验证逻辑,提取返回的 Session Cookie:
public static HttpWebRequest RequestSetting(string url)
{
HttpWebRequest _request = WebRequest.Create(url) as HttpWebRequest;
_request.Method = "POST";
_request.ContentType = "application/x-www-form-urlencoded";
_request.Timeout = 10000; // 超时5秒
_request.CookieContainer = new CookieContainer();
return _request;
}
/// <summary>
/// 登录 web 网页验证
/// </summary>
public bool ProcessRemoteLogin(string url, string _userName, string _userPwd, string _macAddress, out Cookie sessionID)
{
bool _checkResult = false;
string _errorMessage = string.Empty;
// 1. 构建凭证
IDictionary<string, string> _requestCredentials = new Dictionary<string, string>();
_requestCredentials.Add("UserName", _userName);
_requestCredentials.Add("PassWord", _userPwd);
_requestCredentials.Add("MacAddress", _macAddress);
byte[] _credentials = HttpWebRequestToolV2.CreateCredentials(_requestCredentials, Encoding.UTF8);
// 2. 发送请求
CookieCollection _cookie = null;
using (HttpWebResponse _httpRespone = HttpWebRequestToolV2.CreateHttpWebRequest(url, _credentials, RequestSetting))
{
_cookie = new CookieCollection();
if (_httpRespone.Cookies.Count > 0)
_cookie.Add(_httpRespone.Cookies);
}
// 3. 解析结果
Cookie _loginType = _cookie["LoginType"];
Cookie _err = _cookie["Err"];
sessionID = _cookie["ASP.NET_SessionId"];
if (_loginType != null && _err != null && sessionID != null)
{
_checkResult = _loginType.Value.Equals("1");
if (!_checkResult)
_errorMessage = HttpUtility.UrlDecode(_err.Value);
}
else
{
_errorMessage = "Web服务异常,请稍候再试!";
}
if (!string.IsNullOrEmpty(_errorMessage))
throw new Exception(_errorMessage);
return _checkResult;
}
提取 WebBrowser 中的 CookieContainer
有时需要将 WebBrowser 当前页面的 Cookie 转换为 CookieContainer 以便在其他 HTTP 请求中使用。可以通过解析 Document 的 Cookie 字符串来实现:
public static CookieContainer GetCookieContainer(this WebBrowser webBrowser)
{
if (webBrowser == null) throw new ArgumentNullException("webBrowser");
CookieContainer _cookieContainer = new CookieContainer();
string _cookieString = webBrowser.Document.Cookie;
if (string.IsNullOrEmpty(_cookieString)) return _cookieContainer;
string[] _cookies = _cookieString.Split(';');
if (_cookies == null) return _cookieContainer;
foreach (string cookieString in _cookies)
{
string[] _cookieNameValue = cookieString.Split('=');
if (_cookieNameValue.Length != 2) continue;
string name = _cookieNameValue[0].Trim();
string value = _cookieNameValue[1].Trim();
if (!string.IsNullOrEmpty(name))
{
Cookie _cookie = new Cookie(name, value);
_cookieContainer.Add(_cookie);
}
}
return _cookieContainer;
}
以上就是C# WinForm WebBrowser 控件常用操作的详细内容,更多关于WinForm与Web交互的资料请关注本站其它相关文章!本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













