C# C WebBrowser控件下载(无提示+证书SSL+WebForms)

C# C WebBrowser控件下载(无提示+证书SSL+WebForms),c#,asp.net,webforms,webbrowser-control,ssl-certificate,C#,Asp.net,Webforms,Webbrowser Control,Ssl Certificate,问题是: 捕获所有ASP.NET VIEWSTATE回发数据 在已启用SSlenable的WebClient中模拟WebBrowser的会话/Cookie状态 通过已启用的WebClient发送WebForm POSTDATA以自动下载文件 管理文件 为我复杂的问题寻找解决方案,最后我找到了一个解决方案 将对MSHTML的引用添加到项目中 c:\windows\system32或WOW64\mshtml.dll 使用JQuery.serialize,我可以设法从顶级ASP.NET表单获取Form

问题是:

捕获所有ASP.NET VIEWSTATE回发数据 在已启用SSlenable的WebClient中模拟WebBrowser的会话/Cookie状态 通过已启用的WebClient发送WebForm POSTDATA以自动下载文件 管理文件 为我复杂的问题寻找解决方案,最后我找到了一个解决方案

将对MSHTML的引用添加到项目中 c:\windows\system32或WOW64\mshtml.dll

使用JQuery.serialize,我可以设法从顶级ASP.NET表单获取FormData

2.1将Jquery库附加到WebBrowser CurrentPage

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 cookies,这就是我的情况。默认情况下,WebBrowser Document.Cookie属性中不会出现这些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();

你找到解决办法了吗?那么你应该把它作为答案贴出来。可能会把问题解决你来的比我快