C# WinForm WebBrowser 控件常用操作指南

温以宁
温以宁
发布时间:2026-10-14 | 2人浏览过
原创

在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交互的资料请关注本站其它相关文章!
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表