从C#应用程序发送数据到网站/ Web服务器是否可行?

3

我希望有人能帮助我解决一个困扰我已久的问题。

在打开浏览器时,是否可以从C#应用程序向网页发送数据?例如,如果您在线上有一个登录表单,并希望从C#应用程序将用户名和密码发布到该表单,则会发生什么。

我看到类似于打开浏览器到表单页面并从程序中发布登录详细信息,然后页面可以立即处理表单,从而使其登录并将其发送到主页。这可能吗?

先感谢您的帮助。

保罗


发布到 Apache PHP 服务器 - Jason Jong
是的,确实是这样我创建页面的,表单将通过PHP进行处理。 - AdrenalineJunky
2个回答

9

是的。

您可以使用HttpWebRequest与网页或Web服务器(或Web服务)进行通信。以下是我用于从Facebook URL获取数据的实际代码:

internal static string FbFetch(string url)
{
    var request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "GET";
    using (var response = (HttpWebResponse)request.GetResponse())
    {
        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            var responseText = reader.ReadToEnd();
            return responseText;
        }
    }
}

但是,你所描述的被称为“HTML屏幕抓取”,这种方法在构建应用程序时可能是一个繁琐而脆弱的方法。 繁琐是因为很难浏览所有UI元素,如果页面设计师更改他的页面,您的屏幕抓取将不再起作用,因此是脆弱的。

祝好运。


很好,简洁明了。我本来想建议使用“WebClient”,但这段代码已经足够短了,没有必要再改了。 - 3Dave
谢谢,看起来很有用,但我还需要打开用户的默认网络浏览器,这可行吗? - AdrenalineJunky
还有使用GET的,有POST等效吗? - AdrenalineJunky
1
我使用HTML Agility Pack来解析HTML代码,该工具可以在http://htmlagilitypack.codeplex.com/找到。我发现它非常适合这项工作,所以如果你需要解析HTML代码,可以去那里查看。 - Jason Jong
@AdrenalineJunky - 将GET更改为POST,你就完成了POST请求。当然,你还需要格式化并编写请求参数。至于在Windows上打开默认的Web浏览器,可以使用System.Diagnostics.Process.Start(url) - Cheeso
@cheeso 谢谢,我用它来处理链接,但是你不能使用它进行发布,不过我发现Jason建议的解决方案很好用。 - AdrenalineJunky

1
回答你关于HTTP post(带附件)的问题,这更加困难 - 因为有附件。这是我用来将图片发布到Facebook的实际代码。
    /// <summary>
    /// Create a new HttpWebRequest with the default properties for HTTP POSTS
    /// </summary>
    /// <param name="url">The URL to be posted to</param>
    /// <param name="referer">The refer</param>
    /// <param name="cookies">CookieContainer that should be used in this request</param>
    /// <param name="postData">The post data</param>
    private string CreateHttpWebUploadRequest(string url, string referer, CookieContainer cookies, NameValueCollection postData, FileInfo fileData, string fileContentType)
    {
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        string boundary = "----------" + DateTime.UtcNow.Ticks.ToString("x", CultureInfo.InvariantCulture);

        // set the request variables
        request.Method = WebRequestMethods.Http.Post;
        request.ContentType = "multipart/form-data; boundary=" + boundary;
        request.CookieContainer = cookies;
        request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.55 Safari/533.4";
        request.Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, */*";
        request.Headers.Add("Accept-Encoding: gzip,deflate");
        request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
        request.Headers.Add("Accept-Language: en-us");
        request.Referer = referer;
        request.KeepAlive = true;
        request.AllowAutoRedirect = false;

        // process through the fields
        StringBuilder sbHeader = new StringBuilder();

        // add form fields, if any
        if (postData != null)
        {
            foreach (string key in postData.AllKeys)
            {
                string[] values = postData.GetValues(key);
                if (values != null) 
                {
                    foreach (string value in values)
                    {
                        if (!string.IsNullOrEmpty(value))
                            sbHeader.AppendFormat("--{0}\r\n", boundary);
                            sbHeader.AppendFormat("Content-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}\r\n", key, value);
                    }
                }
            }
        }

        if (fileData != null)
        {
            sbHeader.AppendFormat("--{0}\r\n", boundary);
            sbHeader.AppendFormat("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n", "media", fileData.Name);
            sbHeader.AppendFormat("Content-Type: {0}\r\n\r\n", fileContentType);
        }

        byte[] header = Encoding.UTF8.GetBytes(sbHeader.ToString());
        byte[] footer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
        long contentLength = header.Length + (fileData != null ? fileData.Length : 0) + footer.Length;

        // set content length
        request.ContentLength = contentLength;

        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(header, 0, header.Length);

            // write the uploaded file
            if (fileData != null)
            {
                // write the file data, if any
                byte[] buffer = new Byte[fileData.Length];
                var bytesRead = fileData.OpenRead().Read(buffer, 0, (int)(fileData.Length));
                requestStream.Write(buffer, 0, bytesRead);
            }

            // write footer
            requestStream.Write(footer, 0, footer.Length);
            requestStream.Flush();
            requestStream.Close();

            using (var response = request.GetResponse() as HttpWebResponse)
            {
                using (var stIn = new System.IO.StreamReader(response.GetResponseStream()))
                {
                    return stIn.ReadToEnd();
                }
            }
        }
    }

更新 为了让它更完整,这里是不需要文件附件的帖子代码。我再次使用这个代码发布到FaceBook。

    /// <summary>
    /// Create a new HttpWebRequest with the default properties for HTTP POSTS
    /// </summary>
    /// <param name="url">The URL to be posted to</param>
    /// <param name="referer">The refer</param>
    /// <param name="cookies">CookieContainer that should be used in this request</param>
    /// <param name="postData">The post data (needs to be formatted in name=value& format</param>
    private string CreateHttpWebPostRequest(string url, string referer, CookieContainer cookies, NameValueCollection postData)
    {
        var sbPostData = new StringBuilder();

        if (postData != null)
        {
            foreach (string key in postData.AllKeys)
            {
                string[] values = postData.GetValues(key);
                if (values != null)
                {
                    foreach (string value in values)
                    {
                        if (!string.IsNullOrEmpty(value))
                            sbPostData.Append(string.Format("{0}={1}&", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value)));
                    }
                }
            }
        }

        var parameterString = Encoding.UTF8.GetBytes(sbPostData.ToString());
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        request.Method = WebRequestMethods.Http.Post;
        request.CookieContainer = cookies;
        request.ContentLength = parameterString.Length;
        request.ContentType = "application/x-www-form-urlencoded";
        request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.55 Safari/533.4";
        request.Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, */*";
        request.Headers.Add("Accept-Encoding: gzip,deflate");
        request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
        request.Headers.Add("Accept-Language: en-us");
        request.Referer = referer;
        request.KeepAlive = true;
        request.AllowAutoRedirect = false;

        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(parameterString, 0, parameterString.Length);
            requestStream.Close();

            using (var response = request.GetResponse() as HttpWebResponse)
            {
                using (var stIn = new System.IO.StreamReader(response.GetResponseStream()))
                {
                    return stIn.ReadToEnd();
                }
            }
        }
    }  

嘿,这不是类似于C# facebooksdk中的代码吗?http://facebooksdk.codeplex.com - Shekhar_Pro
谢谢,Jason。我尝试使用这段代码,但好像无法在HTTPS登录中使其工作,是不是在HTTPS上发布与HTTP有所不同?或者问题可能是cookie没有被正确创建,或者可能没有正确重定向,某些东西肯定是出了问题/表现异常。你有什么想法? - AdrenalineJunky
@Shekhar_Pro - 不,我特意创建了这个来与Facebook Graph API通信。没有使用facebooksdk。不过我确实从http://skysanders.net/subtext/archive/2010/04/12/c-file-upload-with-form-fields-cookies-and-headers.aspx得到了帮助。 - Jason Jong
@AdrenalineJunky - 当我在Facebook上发布内容时,它使用的是HTTPS,所以没有什么区别。可能是因为cookies的问题,但如果没有看到你的代码,就无法确定。另外,请注意在CreateHttpWebUploadRequest方法中,我设置了request.AllowAutoRedirect = false; 根据你的情况,你需要将其设置为true吗? - Jason Jong
谢谢,这一切似乎都很合理并且适用于本地页面,我认为我的防火墙阻止了它在在线页面上的工作,所以至少我知道它是有效的,只需要解决防火墙问题。 - AdrenalineJunky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接