c#以POST方式模拟提交表单

这是我一年前写的一个用C#模拟以POST方式提交表单的代码,现在记录在下面,以免忘记咯。那时候刚学C#~忽忽。。很生疏。。代码看上去也很幼稚 臃肿不堪

#region 内容添加函数(Contentinsert)      public string Contentinsert(string bookID, string bookTitle, string bookContent,string taskUrl,string Ztagend)      {                 string uriString = "这里是取VIEWSTATE等值的页面";

         //如果是asp.net页面,最好是先取到VIEWSTATE和EVENTVALIDATION值一并提交                  ///////////////////////////////////////                  // 打开指定的页面                  ///////////////////////////////////////                 XMLRW UpdateBook = new XMLRW();                  WebClient webClient = new WebClient();                  byte[] responseData = webClient.DownloadData(uriString);                  string srcString = Encoding.UTF8.GetString(responseData);                  ///////////////////////////////////////                  // 填写页面并提交                  ///////////////////////////////////////                  webClient = new WebClient();                  webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); //定义关联的标头

                // 获取页面的 VeiwState   这个值和EventValidation 的值在这里用于数据接收页接收数据                              string viewStateFlag = "id=\"__VIEWSTATE\" value=\""; //动态抓取__VIEWSTATE的值                  int i = srcString.IndexOf(viewStateFlag) + viewStateFlag.Length;                  int j = srcString.IndexOf("\"",i);                  string viewState = srcString.Substring(i, j-i);

                // 获取页面的 EventValidation 这个值和EventValidation 的值在这里用于数据接收页接收数据          string eventValidationFlag = "id=\"__EVENTVALIDATION\" value=\""; //动态抓取__EVENTVALIDATION\的值                 i = srcString.IndexOf(eventValidationFlag) + eventValidationFlag.Length;                  j = srcString.IndexOf("\"", i);                  string eventValidation = srcString.Substring(i, j - i);          //获取页面的章数                  string viewmenuid = "<input name=\"txt_menuid\" type=\"text\" value=\""; //动态抓取__VIEWSTATE的值                   i = srcString.IndexOf(viewmenuid) + viewmenuid.Length;                   j = srcString.IndexOf("\"",i);                  string txt_menuid = srcString.Substring(i, j-i);                  /* 提交按钮的文本                  string submitButton = "提交";                   * 这句代码主要用于当数据接收页面是button的情况                   * */                  bookTitle = System.Web.HttpUtility.UrlEncode(bookTitle);                  bookContent = System.Web.HttpUtility.UrlEncode(bookContent);                  viewState = System.Web.HttpUtility.UrlEncode(viewState);                  eventValidation = System.Web.HttpUtility.UrlEncode(eventValidation);                  txt_menuid = System.Web.HttpUtility.UrlEncode(txt_menuid);                   // 要提交的字符串数据。格式形如:user=uesr1&password=123                  //下面开始执行数据的提交 当提交没有错误将返回提交后的页面代码回来                  string postString = "txt_title=" + bookTitle + "&txt_content=" + bookContent + "&txt_menuid=" + txt_menuid + "&cmdSaveConn.x=0&cmdSaveConn.y=0" + "&__VIEWSTATE=" + viewState + "&__EVENTVALIDATION=" + eventValidation;            /*txt_title为标题内容,bookContent为内容txt_menuid为当前章节数cmdSaveConn.x=0&cmdSaveConn.y=0用于传递imagebutton控件传递参数 用于数据接收页面的提交针对不同的按钮用参数实现触发祥见:http://hi.baidu.com/zeratul_bb/blog/item/34d9f7fda770c241d6887deb.html __VIEWSTATE和_EVENTVALIDATION是asp.net特有的隐藏值传递,目前认为作用在于传递数据~待查*/                  // 将字符串转换成字节数组                  byte[] postData = Encoding.ASCII.GetBytes(postString);                  // 上传数据,返回页面的字节数组                  responseData = webClient.UploadData(uriString, "POST", postData); //本函数的核心,这里主要解决了用POST方法传递数据以模拟表单提交~还有就是避免了提交后返回到数据接收指定的页面~是个很好的方法!!详见:http://www.cnblogs.com/anjou/archive/2006/12/25/602943.html (asp.net中webClient填充和提交表单的方法!)                  // 将返回的将字节数组转换成字符串(HTML);                  // ASP.NET 返回的页面一般是Unicode,如果是简体中文应使用                  //   Encoding.GetEncoding("GB2312").GetString(responseData)                  srcString = Encoding.UTF8.GetString(responseData);                  UpdateBook.UpdateXml(taskUrl, bookID, Ztagend);                  return "成功添加数据,返回数据字节为:"+srcString.Length.ToString(); //向主调函数返回数据提交后转到的页面代码长度!

                ///////////////////////////////////////                  // 分析返回的页面                  ///////////////////////////////////////                  // ...... ......  }      #endregion

-----------------------------

根据不同按钮总结如下:

Asp.net 中在客户端触发服务端事件分为两种情况:

一.     WebControls中的Button 和HtmlControls中的Type为submit的HtmlInputButton

这两种按钮最终到客户端的表现形式为: <input name="Submit1" id="Submit1" type="submit" value=”Submit”>,这是Form表单的提交按钮,点击以后会作为参数发送到服务端,参数是这样的: 控件的name属性=控件的value值,对应上面的例子就是:Submit1= Submit。 服务端会根据接收到的控件的name属性的这个key来得知是这个按钮被点击了,从而在服务端触发这个按钮的点击事件。

二.     ImageButton或者HttpInputImage:

这些控件到客户端的表现类似这样的: <input type=image id=img1>,点击了这样的控件会直接提交表单,作用同提交按钮。点击了这样的控件传到服务端的参数是这样的:id.x=nn&id.y=nn,对应到上面的例子就是:img1.x=nn&img1.y=nn

三.     HtmlControls 中的 Type为button的HtmlInputButton 和其它所有的控件事件,比如LinkButton点击,TextBox的Change事件等等:

这些事件在客户端产生后会经过一个统一的机制发送到服务端。

1.       首先asp.net页框架会使用两个Hidden域来存放表示是哪个控件触发的事件,以及事件的参数:

<!—表示触发事件的控件,一般是这个控件的name -->

<input type="hidden" name="__EVENTTARGET" value="" />

<!—表示触发事件的参数,一般是当某个控件有两个以上的事件时,用来区别是哪个事件 -->

<input type="hidden" name="__EVENTARGUMENT" value="" />

2.       服务端会生成一个jscript的方法来处理所有这些事件的发送,这段代码是:

<script language="javascript">

<!--

function __doPostBack(eventTarget, eventArgument) {

         var theform = document.WebForm2;

         theform.__EVENTTARGET.value = eventTarget;

         theform.__EVENTARGUMENT.value = eventArgument;

         theform.submit();

}

// -->

</script>

3.       每个会引发服务端事件的控件都会在响应的客户端事件中调用上面的代码:

比如,HtmlControls 中的 Type为button的HtmlInputButton的点击事件

<!—客户端的点击事件调用__doPostBack,eventTarget 参数为'Button2',表示是name为'Button2’控件触发的事件,eventArgument 为空,表示这个Type为button的HtmlInputButton只有一个客户端触发的服务端事件-->

<input language="javascript" onclick="__doPostBack('Button2','')" name="Button2" id="Button2" type="button" value="Button" />

又比如,TextBox控件的Change事件

<!—客户端的onchange事件调用__doPostBack,eventTarget 参数为’TextBox1’,表示是name为’TextBox1’控件触发的事件,而TextBox控件只有一个客户端触发的服务端事件TextChanged,故服务器就会去触发这个TextBox的TextChanged事件->

<input name="TextBox1" type="text" id="TextBox1" onchange="__doPostBack('TextBox1','')" language="javascript" />

4.       客户端触发事件后调用__doPostBack方法,将表示触发的控件源的eventTarget 和事件参数eventArgument分别付给两个隐藏域__EVENTTARGET和__EVENTARGUMENT,然后提交Form,在服务端根据__EVENTTARGET和__EVENTARGUMENT来判断是哪个控件的什么事件触发了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逆向技术

win32程序之子窗口编程

  在前边我们已经讲解了窗口的本质.以及如何注册窗口类跟创建窗口. 还讲了消息循环.

2402
来自专栏文大师的新世界

7. 偷用Swiper简改

看这段代码应该就很清楚了,如果是android系统就渲染Pager如果是ios就使用横向的ScrollView,修改后的app首页如下:

1103
来自专栏非著名程序员

基础篇章:关于 React Native 之 Navigator 组件的讲解

(友情提示:RN学习,从最基础的开始,大家不要嫌弃太基础,会的同学请自行略过,希望不要耽误已经会的同学的宝贵时间) 今天我们来讲讲Navigator这个小家伙,...

1947
来自专栏林德熙的博客

WPF 修改图片颜色

在 WPF 可以使用很多图片处理的方法,本文告诉大家的是一个图片处理,可以把处理的图片保存在文件。

3951
来自专栏流媒体人生

内嵌Activex的Activex插件开发

介绍:   如今在许多流媒体视频网站(youku,tudou......)我们都会发现,观看视频之前都会有一段时间的广告,甚至在观看视频途中也会插入一些 广...

993
来自专栏前端布道

前端开发必备之Emmet

·介绍 Emmet (前身为 Zen Coding) 是一个能大幅度提高前端开发效率的一个工具。 基本上,大多数的文本编辑器都会允许你存储和重用一些代码块,我们...

3294
来自专栏有趣的django

博客园美化终极版-(自定义导航栏)----什么CSDN、简书、腾讯云专栏、个人博客和微信公众号都弱爆了

7390
来自专栏张善友的专栏

JQuery相关资料

将SEO,WEB标准与AJAX进行到底 - JQuery(翻译+学习总结) jQuery——JavaScript冲击波 《15天漫游jQuery》 小试牛刀——...

2168
来自专栏哲学驱动设计

OEA 中 WPF 树型表格整体重构

为什么要重构     上两个月主要做了一件事情,那就是把 OEA 框架中的 TreeGrid 控件,从结构上重新设计,并大量重构现有代码。而花较大精力做这件事的...

2186
来自专栏CRPER折腾记

React 折腾记 - (3) 结合Mobx实现一个比较靠谱的动态tab水平菜单,同时关联侧边栏

4612

扫码关注云+社区

领取腾讯云代金券