站外登录的实现(BS版的无忧登录),不支持验证码
应用场景 客户需求是个网站信息管理中心,保存很多站点后台的用户名及密码,要让中心用户可以通过页面浏览可以直接登录到相应站点后台。
第一种 最简单的方法调用Interop.SHDocVw.dll打开个IE,提交相应数据过去就可以了。
可以参考:使用HttpWebRequest提交ASP.NET表单并保持Session和Cookie
实现如下:
说明:tbUserName={0}&tbPassword={1}&btnLogin={2}是相应控件Name。
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Net; using System.Text; using System.IO; using SHDocVw; namespace WebApplication2 { public partial class Login1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { CookieContainer cookieContainer = new CookieContainer(); /////////////////////////////////////////////////// // 1.打开 MyLogin.aspx 页面,获得 GetVeiwState & EventValidation /////////////////////////////////////////////////// // 设置打开页面的参数 string URI = "***"; HttpWebRequest request = WebRequest.Create(URI) as HttpWebRequest; request.Method = "GET"; request.KeepAlive = false; // 接收返回的页面 HttpWebResponse response = request.GetResponse() as HttpWebResponse; System.IO.Stream responseStream = response.GetResponseStream(); System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.UTF8); string srcString = reader.ReadToEnd(); // 获取页面的 VeiwState string viewStateFlag = "id=\"__VIEWSTATE\" value=\""; int i = srcString.IndexOf(viewStateFlag) + viewStateFlag.Length; int j = srcString.IndexOf("\"", i); string viewState = srcString.Substring(i, j - i); // 获取页面的 EventValidation string eventValidationFlag = "id=\"__EVENTVALIDATION\" value=\""; i = srcString.IndexOf(eventValidationFlag) + eventValidationFlag.Length; j = srcString.IndexOf("\"", i); string eventValidation = srcString.Substring(i, j - i); /////////////////////////////////////////////////// // 2.自动填充并提交 MyLogin.aspx 页面 /////////////////////////////////////////////////// // 提交按钮的文本 string submitButton = "登 录"; // 用户名和密码 string userName = "***"; string password = "***"; // 将文本转换成 URL 编码字符串 viewState = System.Web.HttpUtility.UrlEncode(viewState); eventValidation = System.Web.HttpUtility.UrlEncode(eventValidation); submitButton = System.Web.HttpUtility.UrlEncode(submitButton); // 要提交的字符串数据。格式形如:user=uesr1&password=123 string formatString = "tbUserName={0}&tbPassword={1}&btnLogin={2}&__VIEWSTATE={3}&__EVENTVALIDATION={4}"; string postString = string.Format(formatString, userName, password, submitButton, viewState, eventValidation); OpenNewIe(URI, postString); } public static void OpenNewIe(string url, string postData) { var ie = new InternetExplorer(); object vPost, vHeaders, vFlags, vTargetFrame; vPost = null; vFlags = null; vTargetFrame = null; vHeaders = "Content-Type: application/x-www-form-urlencoded" + Convert.ToChar(10) + Convert.ToChar(13); if (!string.IsNullOrEmpty(postData)) vPost = ASCIIEncoding.ASCII.GetBytes(postData); ie.Visible = true; ie.Navigate(url, ref vFlags, ref vTargetFrame, ref vPost, ref vHeaders); } } }
第二种方法 利用mshtml命名空间实现表单赋值。
可以参考c# 控制IE浏览器
具体实现如下:
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Diagnostics; using System.IO; using SHDocVw; using System.Text; using System.Net; using mshtml; namespace WebApplication2 { public partial class login2 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string URI = "***"; var ie = new InternetExplorer(); object vPost, vHeaders, vFlags, vTargetFrame; vPost = null; vFlags = null; vTargetFrame = null; vHeaders = "Content-Type: application/x-www-form-urlencoded" + Convert.ToChar(10) + Convert.ToChar(13); ie.Visible = true; ie.Navigate(URI, ref vFlags, ref vTargetFrame, ref vPost, ref vHeaders); try { System.Threading.Thread.Sleep(1000); HTMLDocument doc = (HTMLDocument)ie.Document; HTMLInputElement keyword = (HTMLInputElement)doc.getElementById("tbUserName"); keyword.value = "***"; HTMLInputElement keyword1 = (HTMLInputElement)doc.getElementById("tbPassword"); keyword1.value = "***"; HTMLInputElement submit = (HTMLInputElement)doc.getElementById("btnLogin"); submit.click(); } catch (Exception) { return; } } } }
第三种方法 是自己调用底层dll 来实现打开IE,并对表单赋值。调用的类为I ELoginHelper,
客户端实现如下:
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using IELoginHelper; namespace WebApplication2 { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { IEHelper ie = new IEHelper(); ie.OpenAVisibleBlankDocument(); object p = null; string url = @"***"; bool ret = ie.Navigate(url, ref p, ref p, ref p, ref p); ie.SetValueById("txtusername", "***"); ie.SetValueById("txtpwd", "***"); ie.ClickButtonByName("***"); } } }
第一种第二种如果客户端页面JS出错,Button按钮Type不是Submit按钮等可能会出异常。