简体   繁体   English

使用C#控制台应用程序将数据动态发布到ASPX页面

[英]Dynamically POST data to an ASPX page using C# Console Application

I have an .aspx page hosted locally that contains one text field where a user can enter his/her ID and get some information. 我在本地托管一个.aspx页面,其中包含一个文本字段,用户可以在其中输入他/她的ID并获取一些信息。

I understand how HttpWebRequest works and have used it many times to POST to many PHP and JSP pages, but now the problem is that the ASP .NET page that I am trying to POST to has a lot of hidden fields like __VIEWSTATE that are dynamic and sent to the server each time the user enters his/her ID and presses the submit button. 我了解HttpWebRequest工作原理,并多次使用它来发布到许多PHP和JSP页面,但是现在的问题是,我试图发布到的ASP .NET页面具有很多隐藏字段,例如__VIEWSTATE是动态的,每次用户输入其ID并按下“提交”按钮时,都会发送到服务器。

How can I POST the values of those dynamic fields along with the ID? 如何发布这些动态字段的值和ID?

The header looks like this (grabbed from the developer tools in Firefox): 标题如下所示(从Firefox中的开发人员工具中获取):

__EVENTTARGET=&__EVENTARGUMENT=&__LASTFOCUS=&__VIEWSTATE=%2FwEPDwUJMjk5MjYyMjY5D2QWAgIDD2QWBAIHDxcAZAIJDxcGBQZIZWlnaHQHAAAAAAA8kEAFBHJzSUQFFENyeXN0YWxSZXBvcnRTb3VyY2UxBQ9SZXBvcnRWaWV3U3RhdGUXBgUKRGVzaWduTW9kZWgFElBhZ2VSZXF1ZXN0Q29udGV4dBcEBQpQYWdlTnVtYmVyAgEFDVByb21wdGluZ0luZm8UKVhTeXN0ZW0uQnl0ZSwgbXNjb3JsaWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5ygUDPAM%2FA3gDbQNsAyADdgNlA3IDcwNpA28DbgM9AyIDMQMuAzADIgM%2FAz4DDQMKAzwDQQNyA3IDYQN5A08DZgNQA2EDcgNhA20DZQN0A2UDcgNGA2kDZQNsA2QDIAN4A20DbANuA3MDOgN4A3MDaQM9AyIDaAN0A3QDcAM6Ay8DLwN3A3cDdwMuA3cDMwMuA28DcgNnAy8DMgMwAzADMQMvA1gDTQNMA1MDYwNoA2UDbQNhAy0DaQNuA3MDdANhA24DYwNlAyIDIAN4A20DbANuA3MDOgN4A3MDZAM9AyIDaAN0A3QDcAM6Ay8DLwN3A3cDdwMuA3cDMwMuA28DcgNnAy8DMgMwAzADMQMvA1gDTQNMA1MDYwNoA2UDbQNhAyIDPgMNAwoDIAMgAzwDUANhA3IDYQNtA2UDdANlA3IDRgNpA2UDbANkAyADXwNEA2UDZgNhA3UDbAN0A1YDYQNsA3UDZQNEA2kDcwNwA2wDYQN5A1QDeQNwA2UDPQMiAzADIgMgA1ADYQNyA2EDbQNlA3QDZQNyA0YDaQNlA2wDZANOA2EDbQNlAz0DIgNAA1IDZQNnA2kDcwN0A2UDcgNhA3QDaQNvA24DbgN1A20DYgNlA3IDIgMgA1ADcgNvA20DcAN0A1QDZQN4A3QDPQMiAyIDIANSA2UDcANvA3IDdANOA2EDbQNlAz0DIgMiAyADRQNkA2kDdANNA2EDcwNrAz0DIgMiAyADSANhA3MDQwN1A3IDcgNlA24DdANWA2EDbAN1A2UDPQMiA3QDcgN1A2UDIgMgA0UDbgNhA2IDbANlA0EDbANsA28DdwNFA2QDaQN0A2kDbgNnA0QDZQNmA2EDdQNsA3QDVgNhA2wDdQNlAz0DIgN0A3IDdQNlAyIDIANFA24DYQNiA2wDZQNBA2wDbANvA3cDTQN1A2wDdANpA3ADbANlA1YDYQNsA3UDZQM9AyIDZgNhA2wDcwNlAyIDIANFA24DYQNiA2wDZQNOA3UDbANsA1YDYQNsA3UDZQM9AyIDdANyA3UDZQMiAyADVQNQA2EDcgNhA20DZQN0A2UDcgNWA2EDbAN1A2UDSwNpA24DZAM9AyIDMAMiAyADVQNQA2EDcgNhA20DZQN0A2UDcgNUA3kDcANlAz0DIgMwAyIDIANVA0QDaQNzA2MDcgNlA3QDZQNPA3IDUgNhA24DZwNlA0sDaQNuA2QDPQMiAzADIgMgA1UDRANlA2YDYQN1A2wDdANWA2EDbAN1A2UDUwNvA3IDdANPA3IDZANlA3IDPQMiAzADIgMgA1UDRANlA2YDYQN1A2wDdANWA2EDbAN1A2UDUwNvA3IDdANNA2UDdANoA28DZAM9AyIDMAMiAz4DDQMKAyADIAMgAyADPANQA2EDcgNhA20DZQN0A2UDcgNDA3UDcgNyA2UDbgN0A0QDaQNzA2MDcgNlA3QDZQNWA2EDbAN1A2UDIANVA0sDaQNuA2QDPQMiAzADIgM%2BAw0DCgMgAyADIAMgAyADIAM8A0QDZQNzA2MDcgNpA3ADdANpA28DbgMgAy8DPgMNAwoDIAMgAyADIAMgAyADPANWA2EDbAN1A2UDUwN0A3IDaQNuA2cDPgMxAzEDMwMxAzADNgM5AzQDPAMvA1YDYQNsA3UDZQNTA3QDcgNpA24DZwM%2BAw0DCgMgAyADIAMgAzwDLwNQA2EDcgNhA20DZQN0A2UDcgNDA3UDcgNyA2UDbgN0A0QDaQNzA2MDcgNlA3QDZQNWA2EDbAN1A2UDPgMNAwoDIAMgAzwDLwNQA2EDcgNhA20DZQN0A2UDcgNGA2kDZQNsA2QDPgMNAwoDPAMvA0EDcgNyA2EDeQNPA2YDUANhA3IDYQNtA2UDdANlA3IDRgNpA2UDbANkAz4FFUlzTGFzdFBhZ2VOdW1iZXJLbm93bmcFDkxhc3RQYWdlTnVtYmVyAgIFB0ZhY3RvcnkFlgFDcnlzdGFsRGVjaXNpb25zLlJlcG9ydFNvdXJjZS5SZXBvcnRTb3VyY2VGYWN0b3J5LENyeXN0YWxEZWNpc2lvbnMuUmVwb3J0U291cmNlLCBWZXJzaW9uPTEwLjIuMzYwMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTY5MmZiZWE1NTIxZTEzMDQFB1JlZnJlc2hoBQlSZXBvcnRVUkllBQlScHRTb3VyY2UFN0NyeXN0YWxEZWNpc2lvbnMuUmVwb3J0U291cmNlLk5vbkhUVFBDYWNoZWRSZXBvcnRTb3VyY2UFA2Nzc2UFBEJBU0UPFgYeBkhlaWdodBsAAAAAADyQQAEAAAAeBVdpZHRoGwAAAAAAKIhAAQAAAB4EXyFTQgKAA2QFBVdpZHRoBwAAAAAAKIhAFgICAg8XAQUCYnMC3%2F7%2F%2Fw8WAgILDxAPFgIeC18hRGF0YUJvdW5kZ2QPFgFmFgEQBQtNYWluIFJlcG9ydAWoA0FBRUFBQUQvLy8vL0FRQUFBQUFBQUFBRUFRQUFBQnhUZVhOMFpXMHVRMjlzYkdWamRHbHZibk11U0dGemFIUmhZbXhsQndBQUFBcE1iMkZrUm1GamRHOXlCMVpsY25OcGIyNElRMjl0Y0dGeVpYSVFTR0Z6YUVOdlpHVlFjbTkyYVdSbGNnaElZWE5vVTJsNlpRUkxaWGx6QmxaaGJIVmxjd0FBQXdNQUJRVUxDQnhUZVhOMFpXMHVRMjlzYkdWamRHbHZibk11U1VOdmJYQmhjbVZ5SkZONWMzUmxiUzVEYjJ4c1pXTjBhVzl1Y3k1SlNHRnphRU52WkdWUWNtOTJhV1JsY2dqc1VUZy9Bd0FBQUFvS0N3QUFBQWtDQUFBQUNRTUFBQUFRQWdBQUFBTUFBQUFHQkFBQUFBNU1ZWE4wVUdGblpVNTFiV0psY2dZRkFBQUFGVWx6VEdGemRGQmhaMlZPZFcxaVpYSkxibTkzYmdZR0FBQUFDbEJoWjJWT2RXMWlaWElRQXdBQUFBTUFBQUFJQ0FJQUFBQUlBUUVJQ0FFQUFBQUxnFgFmZBgBBR5fX0NvbnRyb2xzUmVxdWlyZVBvc3RCYWNrS2V5X18WCwUgQ3J5c3RhbFJlcG9ydFZpZXdlcjEkY3RsMDIkY3RsMDAFIENyeXN0YWxSZXBvcnRWaWV3ZXIxJGN0bDAyJGN0bDAxBSBDcnlzdGFsUmVwb3J0Vmlld2VyMSRjdGwwMiRjdGwwMgUgQ3J5c3RhbFJlcG9ydFZpZXdlcjEkY3RsMDIkY3RsMDMFIENyeXN0YWxSZXBvcnRWaWV3ZXIxJGN0bDAyJGN0bDA0BSBDcnlzdGFsUmVwb3J0Vmlld2VyMSRjdGwwMiRjdGwwNQUgQ3J5c3RhbFJlcG9ydFZpZXdlcjEkY3RsMDIkY3RsMDYFIENyeXN0YWxSZXBvcnRWaWV3ZXIxJGN0bDAyJGN0bDA3BSBDcnlzdGFsUmVwb3J0Vmlld2VyMSRjdGwwMiRjdGwxMAUgQ3J5c3RhbFJlcG9ydFZpZXdlcjEkY3RsMDIkY3RsMTIFIENyeXN0YWxSZXBvcnRWaWV3ZXIxJGN0bDAyJGN0bDE0jI2pRkImY%2FKY6U%2Fd3%2FdGqZgVpS8%3D&__PREVIOUSPAGE=JxnGN13k9OAmlpqF3Z8SW9w-B2b4vBfG7WIz-XQ5-GZ_4P1GIClbgn0lEpxdarTxDVAekfH3QhOqCwpdtv2ml9I79qLZb5EFP7Nh-zun2qPkprmn0&TextBox1=11310694&Button1=Show&CrystalReportViewer1%24ctl02%24ctl09=&CrystalReportViewer1%24ctl02%24ctl11=AAEAAAD%2F%2F%2F%2F%2FAQAAAAAAAAAEAQAAABxTeXN0ZW0uQ29sbGVjdGlvbnMuSGFzaHRhYmxlBwAAAApMb2FkRmFjdG9yB1ZlcnNpb24IQ29tcGFyZXIQSGFzaENvZGVQcm92aWRlcghIYXNoU2l6ZQRLZXlzBlZhbHVlcwAAAwMABQULCBxTeXN0ZW0uQ29sbGVjdGlvbnMuSUNvbXBhcmVyJFN5c3RlbS5Db2xsZWN0aW9ucy5JSGFzaENvZGVQcm92aWRlcgjsUTg%2FAwAAAAoKCwAAAAkCAAAACQMAAAAQAgAAAAMAAAAGBAAAAA5MYXN0UGFnZU51bWJlcgYFAAAAFUlzTGFzdFBhZ2VOdW1iZXJLbm93bgYGAAAAClBhZ2VOdW1iZXIQAwAAAAMAAAAICAIAAAAIAQEICAEAAAAL&CrystalReportViewer1%24ctl02%24ctl13=&CrystalReportViewer1%24ctl02%24ctl15=100

On the contrary, all the information I have available to POST is TextBox1=11310694 相反,我可用于POST的所有信息都是TextBox1=11310694

If I use the same header as above in my code, I get a 500 INTERNAL SERVER ERROR . 如果我在代码中使用与上面相同的标头, 500 INTERNAL SERVER ERROR收到500 INTERNAL SERVER ERROR

The C# code that I am using to fetch the page: 我用来获取页面的C#代码:

try{
ASCIIEncoding encoding = new ASCIIEncoding();
string post_data = "TextBox1=123456";
byte[] data = encoding.GetBytes(post_data);
WebRequest share_url = WebRequest.Create("http://172.19.2.6:8080/webopac/html/memberlogin");
share_url.Method = "POST";
share_url.ContentLength = data.Length;
share_url.ContentType = "application/x-www-form-urlencoded";
Stream stream = share_url.GetRequestStream();
stream.Write(data, 0, data.Length);
stream.Close();
WebResponse resp = share_url.GetResponse();
stream = resp.GetResponseStream();
StreamReader sr = new StreamReader(stream);
var oup = sr.ReadToEnd();
Console.WriteLine(oup);
Console.ReadLine();
}   
catch (Exception err)
{
Console.WriteLine("ERROR: " + err.Message);
}

How can I POST those VIEWSTATE fields? 如何发布那些VIEWSTATE字段?

There are essentially two ways of going about what you want to accomplish. 基本上有两种方法可以完成您想完成的任务。

The best way: APIs and Web Services 最佳方法:API和Web服务

If you are trying to retrieve information from an ASP .NET web application that is under your control, it is best to use some form of API rather than communicating directly with pages meant to be viewed in browser. 如果您试图从您控制的ASP .NET Web应用程序中检索信息,则最好使用某种形式的API,而不是直接与要在浏览器中查看的页面进行通信。

This does several things (among others): 这可以做几件事(以及其他):

  1. You save yourself a lot of code. 您为自己节省了大量代码。

    Instead of needing to parse/generate/submit form data which is really only meant to assist in giving the user an interactive webpage, the code you write only has to handle sending and receiving the information you want. 无需解析/生成/提交表单数据(实际上仅旨在帮助用户提供交互式网页),而只需编写代码即可处理发送和接收所需信息的过程。

  2. You save yourself bandwidth. 您可以节省带宽。

    This also saves you bandwidth, as the extra data (that your client application does not need) does not have to be transmitted back and forth. 这也节省了带宽,因为不必来回传输额外的数据(客户端应用程序不需要)。 This in turn makes your client application faster, and also saves the web server the extra processing time it would need to render an ASP .NET WebForm. 反过来,这可以使您的客户端应用程序更快,并且还为Web服务器节省了呈现ASP .NET WebForm所需的额外处理时间。

  3. You avoid extra, unnecessary error checks and instability. 您可以避免进行额外的不必要的错误检查和不稳定。

    When you communicate with a web page meant for the end-user, you may often need to implement many error checks in the event that the web page doesn't return what you want. 当您与面向最终用户的网页进行通信时,如果网页未返回您想要的内容,则可能经常需要执行许多错误检查。 In the case, for example, of an error on the page that still results in a 200 OK HTTP status code, you may need to parse the page for error text. 例如,如果页面上的错误仍然导致200 OK HTTP状态代码,则可能需要解析页面以获取错误文本。 This takes up processing time, code, and is prone to breaking when changes are made to the page. 这会占用处理时间,代码,并且在对页面进行更改时容易中断。

To avoid all these problems, you can set up an API or web service that will act as a special point of communication which your web application uses to talk to your client application. 为了避免所有这些问题,您可以设置一个API或Web服务,将其用作Web应用程序用来与客户端应用程序进行通信的特殊通信点。 You send only the data you need, simplify your code, and make your application more reliable. 您只发送所需的数据,简化代码,并使应用程序更可靠。

What it looks like 看起来像什么

If you just query a WebForm or other web page for the form values you need, your program will have to sort through all this: 如果仅在WebForm或其他网页上查询所需的表单值,则程序将必须对所有这些内容进行排序:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" >
  <head><script type="text/javascript" charset="UTF-8">
(function (global) {
    global.outsystems = global.outsystems || {};
    global.outsystems.internal = global.outsystems.internal || {};
})(this);

outsystems.internal.timerspolyfillResponseStart = new Date().getTime();
outsystems.internal.beaconURL = '/PerformanceProbe/Beacon.aspx';
</script><title>
    Login
</title><link rel="apple-touch-icon" href="apple-touch-icon.png" /><link type="image/x-icon" rel="shortcut icon" href="/WodifyUI/img/favicon.png" /><script type="text/javascript" src="/wodify/js/libs/modernizr-2.5.3.min.js"></script><script type="text/javascript" src="/WodifyUI/js/pusher.min.js"></script>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" /><meta http-equiv="Content-Style-Type" content="text/css" />
</head>
  <body>
    <form name="WebForm1" method="post" action="Login.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="WebForm1">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__OSVSTATE" id="__OSVSTATE" value="eNp1jcEKgkAURXOwFi1yE1MRzB+0SGrhUloJJSK0lodvNEFnZGbM+vpSQaigzYN3D/eel+WgM53vXPfged7ePTp0xtaFiEBB5ZelbP3GyJhjoXhqcrZpzVVzFULFA1E3JrmAQDBSPQcWgdatVPjLKCGdiJJsPPb4977l6KvrskjBFFIESCy2uoM6px9pzNNuXNMJ2/5BCZdZjkjsfv3L6VDCFkPrVHIQIX+YG+Ib9DFO1Q==" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="" />
</div>

<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['WebForm1'];
if (!theForm) {
    theForm = document.WebForm1;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
...

If you use an API or a web service, you end up something like the code below, which is much easier to work with: 如果使用API​​或Web服务,则最终会得到类似于以下代码的代码,使用起来更容易:

<?xml version="1.0" encoding="UTF-8"?>
<member>
    <id>12345</id>
    <name>Jane Doe</name>
    <dob>01/01/1980</dob>
</member>

Option 1: Small-scale 选项1:小规模

Personally, I feel that this is the best option for you, as it seems you only intend to transmit a small bit of data. 我个人认为这对您来说是最佳选择,因为您似乎只打算传输少量数据。

If you only have a couple pieces of data that you need to communicate, and you generally don't rely on communicating with your web application from a client application, you may consider using a Generic Handler (.ashx) . 如果您只需要通信几个数据,并且通常不依赖于从客户端应用程序与Web应用程序通信,则可以考虑使用通用处理程序(.ashx) This is a quick and easy way of transferring data from your web application to your client application. 这是将数据从Web应用程序传输到客户端应用程序的快速简便的方法。

Pros: 优点:

  1. Very easy to implement, especially for developers not as familiar with MVC and RESTful services. 非常容易实现,特别是对于不熟悉MVC和RESTful服务的开发人员。
  2. Requires very little time to complete. 只需很少的时间即可完成。

Cons: 缺点:

  1. Not easily scalable. 不容易扩展。 If you plan on increasing the amount of data you need to communicate between server and client, consider a full-fledged web service or API. 如果计划增加服务器与客户端之间进行通信所需的数据量,请考虑使用完整的Web服务或API。
  2. Can lead to unstandardized code without care. 可能会导致不规范的代码。 In other words, because there is no set standard way of communicating with Generic Handlers, if you don't keep to a certain set of rules (such as, every time I need to access a member's name, I'll use a Name field, and for their date of birth, DOB), you may end up with a lot of code that is very different from one another and hard to maintain when changes are needed. 换句话说,由于没有与通用处理程序进行通信的固定标准方法,因此,如果您不遵守某些规则(例如,每次我需要访问成员的姓名时,我都会使用“姓名”字段) ,以及他们的出生日期(DOB),最终可能会导致许多代码彼此之间非常不同,并且在需要进行更改时很难维护。

Here's some pseudocode that shows you just how easy it is to create a Generic Handler: 这是一些伪代码,向您显示创建通用处理程序有多么容易:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml;
using MyDatabase;

namespace MyWebApplication
{
    public class MemberHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            Member requestedMember = null;
            Exception error = null;

            try
            {
                requestedMember = MyDatabaseClient.GetMemberByID(int.Parse(context.Request.QueryString["id"]));
            }
            catch (Exception ex)
            {
                error = ex;
            }

            context.Response.ContentType = "text/xml";
            context.Response.ContentEncoding = Encoding.UTF8;

            using (XmlTextWriter xmlTextWriter = new XmlTextWriter(context.Response.OutputStream, Encoding.UTF8) { Formatting = Formatting.Indented })
            {
                xmlTextWriter.WriteStartDocument();
                if (requestedMember != null)
                {
                    xmlTextWriter.WriteStartElement("member");

                    xmlTextWriter.WriteStartElement("id");
                    xmlTextWriter.WriteValue(requestedMember.ID);
                    xmlTextWriter.WriteEndElement();

                    xmlTextWriter.WriteStartElement("name");
                    xmlTextWriter.WriteValue(requestedMember.Name);
                    xmlTextWriter.WriteEndElement();

                    xmlTextWriter.WriteStartElement("dob");
                    xmlTextWriter.WriteValue(requestedMember.DOB);
                    xmlTextWriter.WriteEndElement();

                    xmlTextWriter.WriteEndElement();
                }
                else
                {
                    xmlTextWriter.WriteStartElement("error");
                    xmlTextWriter.WriteValue(error.Message);
                    xmlTextWriter.WriteEndElement();
                }
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

Now, with a simple web request to /MemberHandler.ashx?id=12345 , you can retrieve just the right information you need from your console application. 现在,通过对/MemberHandler.ashx?id=12345的简单Web请求,您可以从控制台应用程序中检索所需的正确信息。 Now, this is just an example, so, for example, it doesn't send a 404 if the member could not be found. 现在,这只是一个示例,因此,例如,如果找不到该成员,则不会发送404。 But, these are really easy features to implement! 但是,这些都是非常容易实现的功能!

Then, from your client application, you would simply retrieve the XML and parse it using the classes in System.Xml . 然后,从客户端应用程序中,您只需检索XML并使用System.Xml的类对其进行解析。 This makes the work you have to do close to nothing, and is a easy, quick and fast implementation of communicating between server and client. 这使您要做的工作几乎没有,并且是服务器,客户端之间通信的轻松,快速和快速实现。

There are a number of good resources online that will help you making handlers if you do a good search, one such is .NET: A simple AJAX service using Plain Old XML (POX) 网上有很多不错的资源,如果您做的很好,就可以帮助您创建处理程序。.NET就是其中之一。NET:使用Plain Old XML(POX)的简单AJAX服务

Option 2: Large-scale 选项2:大规模

If you plan to have a lot of data that needs to be communicated between a client application and your web application, it's best to use a technology such as the ASP .NET Web API to facilitate communication between the two, as it gives you an easy way to create a web service that has a programmable API. 如果您打算在客户端应用程序和Web应用程序之间传递大量数据,则最好使用ASP .NET Web API之类的技术来促进两者之间的通信,因为它使您轻松创建具有可编程API的Web服务的方法。

Pros: 优点:

  1. Very easy to scale and make changes to. 非常容易扩展和更改。 You can easily add and remove different pieces of information as you wish with minimal effort and time. 您可以根据需要轻松地添加和删除不同的信息,而所需的时间和精力却很少。
  2. Less work and code for you to write in the long run. 从长远来看,您可以减少工作量和编写代码。 Many times code will be partially generated for you based off of your database or other data source, and templates are readily available to get you started. 很多时候,将基于数据库或其他数据源为您生成部分代码,并且可以使用模板快速入门。 You also don't have to reinvent the wheel, as many classes and utility methods are given to you, so you can focus on what's important: your data. 您也不必重新发明轮子,因为提供了许多类和实用程序方法,因此您可以专注于重要的事情:数据。

Cons: 缺点:

  1. Takes a while to get set up initially and adapt to. 最初需要一段时间才能适应。 As you get used to using something like the Web API, it becomes much more familiar, but in the beginning it might feel like entering a whole new world. 随着您习惯使用诸如Web API之类的东西,它变得越来越熟悉,但是一开始它可能就像进入了一个全新的世界。
  2. Can be cumbersome and bulky for small projects. 对于小型项目可能会很繁琐。 If all you need is to have a single page or two that sends/receives a limited amount of information, it might be better to make a simple handler instead. 如果您只需要一个或两个页面来发送/接收有限的信息,那么最好改用一个简单的处理程序。

Going into depth with frameworks such as the Web API is a very long ordeal, and not best suited for being dealt with right here. 深入了解诸如Web API之类的框架是一个长期的考验,并不是最适合在此处进行处理的。 However, there are extensive amounts of resources ready to help you out, such as the official Getting Started with ASP.NET Web API 2 tutorial. 但是,有大量资源可以帮助您,例如官方的《 ASP.NET Web API 2入门》教程。

The not-so-great way: Scraping information 不太好用:收集信息

I highly recommend, that, whenever possible, you try to avoid this method. 强烈建议您尽可能避免使用这种方法。 If you're not in control of the web application you need to talk to, first check to see if the developer/company that supplied the web application provides a documented API. 如果您无法控制要与之交谈的Web应用程序,请首先检查提供该Web应用程序的开发人员/公司是否提供了文档化的API。 It will be much easier to develop that way instead. 相反,开发这种方式会容易得多。

However, sometimes there is little of a choice, and usually this is the case when 但是,有时别无选择,通常在这种情况下

  1. You are not in control of the web application's code, and 您不受Web应用程序代码的控制,并且
  2. There is no documented API available. 没有可用的文档化API。

In this case, you must rely on "scraping" the information you need off of the web page. 在这种情况下,您必须依靠从网页上“抓取”所需的信息。 The theory is simple, but the execution gets rather nasty. 理论很简单,但是执行起来很讨厌。

In your example, if you had to rely on scraping, you would first dispatch a request to the web page in question to retrieve its VIEWSTATE and any other form values you may need. 在您的示例中,如果必须依靠抓取,则首先将请求发送到有问题的网页,以检索其VIEWSTATE和您可能需要的任何其他表单值。 In addition, if the web application relies on cookies, you may need to store them and reuse them on the next request, when you try to retrieve the data you need. 另外,如果Web应用程序依赖Cookie,则当您尝试检索所需的数据时,可能需要存储它们并在下一个请求中重用它们。

This requires trial and error and careful analysis of the web page and the requests/responses that are sent/received when you browse the site normally (which is what you've done in finding the form data that gets sent). 这需要反复试验并仔细分析网页以及在正常浏览站点时发送/接收的请求/响应(这是在查找要发送的表单数据时所做的事情)。

In addition, you have to run two requests to the server, which introduces more points of failure and also makes the client run more slowly. 另外,您必须向服务器运行两个请求,这会引入更多的故障点,并使客户端的运行速度变慢。

There are many resources available which detail how to scrape information off of a web page. 有许多可用资源详细介绍了如何从网页上抓取信息。 Many of them that deal with .NET will mention the HtmlAgilityPack library (available on NuGet), which is a wonderful tool that lets you get pieces and bits of information off of an HTML page without having to run inaccurate and expensive searches through the raw text. 许多使用.NET的人会提到HtmlAgilityPack库(在NuGet上可用),这是一个很棒的工具,它使您可以从HTML页面中获取零碎的信息,而不必通过原始文本运行不准确且昂贵的搜索。

Imagine it as though you have a version of the Javascript DOM available on your server, so instead of searching through the HTML as a string, you would use something like: 想象一下,好像您的服务器上有一个可用的Javascript DOM版本一样,因此,与其使用HTML作为字符串搜索,不如使用以下代码:

HtmlAgilityPack.HtmlNode FormElement = htmlResponse.DocumentNode.SelectSingleNode("//form");

If you need help getting started with scraping, Scraping HTML DOM elements using HtmlAgilityPack (HAP) in ASP.NET and How to use HTML Agility pack are good starting points. 如果您需要刮板入门方面的帮助,则在ASP.NET中使用HtmlAgilityPack(HAP)刮取HTML DOM元素如何使用HTML Agility包是不错的起点。

Choosing which way to go 选择要走的路

As I mentioned before, the method you choose to use really depends on the situation you're in. 如前所述,您选择使用的方法实际上取决于您所处的环境。

  • If this application is under your control, I strongly recommend using some form of API: 如果此应用程序在您的控制之下,则强烈建议您使用某种形式的API:
    • If you really only need to transmit a couple pieces of information, use something like a Generic Handler 如果您真的只需要传输几条信息,请使用通用处理程序
    • If you plan to make communication between client and server an important piece of your solution, use something like the ASP .NET Web API. 如果计划将客户端与服务器之间的通信作为解决方案的重要组成部分,请使用ASP .NET Web API之类的方法。
  • If you're not in charge of the web application: 如果您不负责Web应用程序:
    • If there is any API available, look up the documentation and use it! 如果有可用的API,请查阅文档并使用它!
    • If there is no API available, and no other way, as a last resort, use the scraping technique. 如果没有可用的API,也没有其他方法,请使用抓取技术。

Best of luck! 祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM