C# Web 浏览器控件下载(无提示 + 证书 SSL + WebForms)
本文关键字:证书 SSL WebForms 提示 浏览器 Web 控件 下载 | 更新日期: 2023-09-27 18:34:27
问题:
- 捕获所有 ASP.NET 视图状态回发数据
- 在SSLEnabled-WebClient中模拟Web浏览器的会话/Cookie状态
- 通过SSLEnabled-WebClient发送WebForm POSTDATA以自动下载文件
- 管理文件
挖掘我复杂问题的任何解决方案,终于我找到了解决方案。
-
将 MSHTML 引用添加到项目中
c:'windows'system32 or WOW64'mshtml.dll
-
使用
JQuery.serialize()
我可以设法从Top ASP.NET Form中获取FormData。2.1 将 Jquery 库附加到您的 Web 浏览器当前页面
HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0]; HtmlElement scriptEl1 = webBrowser1.Document.CreateElement("script"); scriptEl1.SetAttribute("src", "https://code.jquery.com/jquery-1.11.1.min.js"); head.AppendChild(scriptEl1);
2.2 创建一个新的div HTML 元素,通过脚本接收 postData
HtmlElement scriptEl2 = webBrowser1.Document.CreateElement("script"); mshtml.IHTMLScriptElement element = (mshtml.IHTMLScriptElement)scriptEl2.DomElement; element.text = @" function CreatePostData() { //alert('Jquery online'); var postData = jQuery(document.forms[0]).serialize(); var divPost = document.createElement(""DIV""); divPost.innerText = postData; divPost.id = ""divPost""; document.body.appendChild(divPost); //alert(divPost.innerText); }"; head.AppendChild(scriptEl2); webBrowser1.Document.InvokeScript("CreatePostData"); string postData = webBrowser1.Document.GetElementById("divPost").InnerText;
-
拥有PostData后,您现在需要启用WebClient SSLSecure。
class SecureWebClient : WebClient { protected override WebRequest GetWebRequest(Uri address) { HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address); string certPath = @"C:'TEMP'ClientCertificateFile.cer"; X509Certificate myCert = X509Certificate.CreateFromCertFile(certPath); request.ClientCertificates.Add(myCert); return request; } }
-
现在您必须将相同的WebBrowser状态与WebClient的状态同步,某些网站/系统为此使用HTTPOnly cookie,这就是我的情况。这些 cookie 默认情况下不会在 WebBrowser
Document.Cookie
属性中出现,以克服对var cookies = FullWebBrowserCookie.GetCookieInternal(webBrowser1.Url, false);`
如果您需要如上所述使用 HTTPOnly cookie,请在项目中添加另一个类:
using System; using System.ComponentModel; using System.Net; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Windows.Forms; internal sealed class NativeMethods { #region enums public enum ErrorFlags { ERROR_INSUFFICIENT_BUFFER = 122, ERROR_INVALID_PARAMETER = 87, ERROR_NO_MORE_ITEMS = 259 } public enum InternetFlags { INTERNET_COOKIE_HTTPONLY = 8192, //Requires IE 8 or higher INTERNET_COOKIE_THIRD_PARTY = 131072, INTERNET_FLAG_RESTRICTED_ZONE = 16 } #endregion #region DLL Imports [SuppressUnmanagedCodeSecurity, SecurityCritical, DllImport("wininet.dll", EntryPoint = "InternetGetCookieExW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] internal static extern bool InternetGetCookieEx([In] string Url, [In] string cookieName, [Out] StringBuilder cookieData, [In, Out] ref uint pchCookieData, uint flags, IntPtr reserved); #endregion } /// <SUMMARY></SUMMARY> /// WebBrowserCookie? /// webBrowser1.Document.CookieHttpOnlyCookie /// public class FullWebBrowserCookie : WebBrowser { [SecurityCritical] public static string GetCookieInternal(Uri uri, bool throwIfNoCookie) { uint pchCookieData = 0; string url = UriToString(uri); uint flag = (uint)NativeMethods.InternetFlags.INTERNET_COOKIE_HTTPONLY; //Gets the size of the string builder if (NativeMethods.InternetGetCookieEx(url, null, null, ref pchCookieData, flag, IntPtr.Zero)) { pchCookieData++; StringBuilder cookieData = new StringBuilder((int)pchCookieData); //Read the cookie if (NativeMethods.InternetGetCookieEx(url, null, cookieData, ref pchCookieData, flag, IntPtr.Zero)) { DemandWebPermission(uri); return cookieData.ToString(); } } int lastErrorCode = Marshal.GetLastWin32Error(); if (throwIfNoCookie || (lastErrorCode != (int)NativeMethods.ErrorFlags.ERROR_NO_MORE_ITEMS)) { throw new Win32Exception(lastErrorCode); } return null; } private static void DemandWebPermission(Uri uri) { string uriString = UriToString(uri); if (uri.IsFile) { string localPath = uri.LocalPath; new FileIOPermission(FileIOPermissionAccess.Read, localPath).Demand(); } else { new WebPermission(NetworkAccess.Connect, uriString).Demand(); } } private static string UriToString(Uri uri) { if (uri == null) { throw new ArgumentNullException("uri"); } UriComponents components = (uri.IsAbsoluteUri ? UriComponents.AbsoluteUri : UriComponents.SerializationInfoString); return new StringBuilder(uri.GetComponents(components, UriFormat.SafeUnescaped), 2083).ToString(); } }
-
将 WebControl 状态与 WebClient 同步,发出 PostData 并捕获返回的 byteArray:
SecureWebClient wc = new SecureWebClient(); wc.Headers.Add("Cookie: " + cookies); wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); byte[] result = wc.UploadData("<URL>", "POST", System.Text.Encoding.UTF8.GetBytes(postData)); File.WriteAllBytes(@"C:'Temp'<FileName>", result); wc.Dispose();