Попытка опубликовать мульти-форму с изображением PNG.
Взял куки для безопасности. Ответ, который мы получаем, - это просто веб-страница, никаких предпринятых действий или чего-то еще, очевидно, что мы неправильно разместили сообщение, когда мы проверяем загруженную область сайта.
Вот необработанный HTML-код в соответствии с запросом:
<form action="/build/upload" enctype="multipart/form-data" id="upload-form" method="post">
<input name="__RequestVerificationToken" type="hidden" value="zLrU9MsixdrkkifJ7aEhOEGvKD0KL5nxaBcEVVukbbc5tKSWHo8xwDabXcSgRD5svi0uudzRyAAPRH7AfBKNlyx9yC81">
<input id="assetTypeId" name="assetTypeId" type="hidden" value="2">
<input id="isOggUploadEnabled" name="isOggUploadEnabled" type="hidden" value="True">
<input data-val="true" data-val-required="The IsTgaUploadEnabled field is required." id="isTgaUploadEnabled" name="isTgaUploadEnabled" type="hidden" value="True">
<input id="groupId" name="groupId" type="hidden">
<input id="onVerificationPage" name="onVerificationPage" type="hidden" value="False">
<input id="captchaEnabled" name="captchaEnabled" type="hidden" value="False"><div id="container">
<div class="form-row">
<label for="file">Find your image:</label>
<input id="file" type="file" name="file" tabindex="1">
<span id="file-error" class="error"></span>
</div>
<div class="form-row">
<label for="name"> Name:</label>
<input id="name" type="text" class="text-box text-box-medium" name="name" maxlength="50" tabindex="2">
<span id="name-error" class="error"></span>
</div>
<div class="form-row submit-buttons">
<a id="upload-button" class="btn-medium btn-primary btn-level-element" tabindex="4">Upload</a>
<span id="loading-container">
<img src="https://images.rbxcdn.com/ec4e85b0c4396cf753a06fade0a8d8af.gif"></span>
</div>
</div>
</form>
Вот класс upload.cs:
// /*!
// * Project: Salient.Web.HttpLib
// * http://salient.codeplex.com
// *
// * Date: April 11 2010
// */
#region
using System;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
#endregion
/// <summary>
/// This class contains methods excepted from Salient.Web.HttpLib.HttpRequestUtility
/// for demonstration purposes. Please see http://salient.codeplex.com for full
/// implementation
/// </summary>
public static class Upload
{
/// <summary>
/// Uploads a stream using a multipart/form-data POST.
/// </summary>
/// <param name="requestUri"></param>
/// <param name="postData">A NameValueCollection containing form fields
/// to post with file data</param>
/// <param name="fileData">An open, positioned stream containing the file data</param>
/// <param name="fileName">Optional, a name to assign to the file data.</param>
/// <param name="fileContentType">Optional.
/// If omitted, registry is queried using <paramref name="fileName"/>.
/// If content type is not available from registry,
/// application/octet-stream will be submitted.</param>
/// <param name="fileFieldName">Optional,
/// a form field name to assign to the uploaded file data.
/// If omitted the value 'file' will be submitted.</param>
/// <param name="cookies">Optional, can pass null. Used to send and retrieve cookies.
/// Pass the same instance to subsequent calls to maintain state if required.</param>
/// <param name="headers">Optional, headers to be added to request.</param>
/// <returns></returns>
/// Reference:
/// http://tools.ietf.org/html/rfc1867
/// http://tools.ietf.org/html/rfc2388
/// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2
///
public static WebResponse PostFile
(Uri requestUri, NameValueCollection postData, Stream fileData, string fileName,
string fileContentType, string fileFieldName, CookieContainer cookies,
NameValueCollection headers, WebBrowser browser)
{
try
{
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(requestUri);
string ctype;
fileContentType = string.IsNullOrEmpty(fileContentType)
? TryGetContentType(fileName, out ctype) ?
ctype : "application/octet-stream"
: fileContentType;
fileFieldName = string.IsNullOrEmpty(fileFieldName) ? "file" : fileFieldName;
if (headers != null)
{
// set the headers
foreach (string key in headers.AllKeys)
{
string[] values = headers.GetValues(key);
if (values != null)
foreach (string value in values)
{
webrequest.Headers.Add(key, value);
}
}
}
webrequest.Method = "POST";
if (cookies != null)
{
webrequest.CookieContainer = cookies;
}
string boundary = "----------" + DateTime.Now.Ticks.ToString
("x", CultureInfo.InvariantCulture);
webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
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)
{
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; z1name=\"{0}\"; {1}\r\n", fileFieldName,
string.IsNullOrEmpty(fileName)
?
""
: string.Format(CultureInfo.InvariantCulture,
"filename=\"{0}\";",
Path.GetFileName(fileName)));
sbHeader.AppendFormat("Content-Type: {0}\r\n\r\n", fileContentType);
}
byte[] header = Encoding.UTF8.GetBytes(sbHeader.ToString());
byte[] footer = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
long contentLength = header.Length + (fileData != null ?
fileData.Length : 0) + footer.Length;
webrequest.ContentLength = contentLength;
using (Stream requestStream = webrequest.GetRequestStream())
{
requestStream.Write(header, 0, header.Length);
if (fileData != null)
{
// write the file data, if any
byte[] buffer = new Byte[checked((uint)Math.Min(4096,
(int)fileData.Length))];
int bytesRead;
while ((bytesRead = fileData.Read(buffer, 0, buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
}
// write footer
requestStream.Write(footer, 0, footer.Length);
var wr = webrequest.GetResponse();
var pageContent = new StreamReader(wr.GetResponseStream())
.ReadToEnd();
Console.WriteLine(pageContent);
browser.DocumentText = pageContent;
return wr;
}
}
catch (WebException wex)
{
var pageContent = new StreamReader(wex.Response.GetResponseStream())
.ReadToEnd();
Console.WriteLine(pageContent);
browser.DocumentText = pageContent;
return null;
}
}
/// <summary>
/// Uploads a file using a multipart/form-data POST.
/// </summary>
/// <param name="requestUri"></param>
/// <param name="postData">A NameValueCollection containing
/// form fields to post with file data</param>
/// <param name="fileName">The physical path of the file to upload</param>
/// <param name="fileContentType">Optional.
/// If omitted, registry is queried using <paramref name="fileName"/>.
/// If content type is not available from registry,
/// application/octet-stream will be submitted.</param>
/// <param name="fileFieldName">Optional, a form field name
/// to assign to the uploaded file data.
/// If omitted the value 'file' will be submitted.</param>
/// <param name="cookies">Optional, can pass null. Used to send and retrieve cookies.
/// Pass the same instance to subsequent calls to maintain state if required.</param>
/// <param name="headers">Optional, headers to be added to request.</param>
/// <returns></returns>
public static WebResponse PostFile
(Uri requestUri, NameValueCollection postData, string fileName,
string fileContentType, string fileFieldName, CookieContainer cookies,
NameValueCollection headers, WebBrowser browser)
{
using (FileStream fileData = File.Open
(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return PostFile(requestUri, postData, fileData,
fileName, fileContentType, fileFieldName, cookies,
headers, browser);
}
}
/// <summary>
/// Attempts to query registry for content-type of supplied file name.
/// </summary>
/// <param name="fileName"></param>
/// <param name="contentType"></param>
/// <returns></returns>
public static bool TryGetContentType(string fileName, out string contentType)
{
try
{
RegistryKey key = Registry.ClassesRoot.OpenSubKey
(@"MIME\Database\Content Type");
if (key != null)
{
foreach (string keyName in key.GetSubKeyNames())
{
RegistryKey subKey = key.OpenSubKey(keyName);
if (subKey != null)
{
string subKeyValue = (string)subKey.GetValue("Extension");
if (!string.IsNullOrEmpty(subKeyValue))
{
if (string.Compare(Path.GetExtension
(fileName).ToUpperInvariant(),
subKeyValue.ToUpperInvariant(),
StringComparison.OrdinalIgnoreCase) ==
0)
{
contentType = keyName;
return true;
}
}
}
}
}
}
// ReSharper disable EmptyGeneralCatchClause
catch
{
// fail silently
// TODO: rethrow registry access denied errors
}
// ReSharper restore EmptyGeneralCatchClause
contentType = "";
return false;
}
}
Вот файл Form.cs:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Clothing_Uploader___CEFSharp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// CefSettings s = new CefSettings();
// Cef.EnableHighDPISupport();
/// Cef.Initialize();
}
private void Form1_Load(object sender, EventArgs e)
{
//var url = "http://api.roblox.com/My/Balance";
string filePath = Path.GetFullPath(@"C:/Users/Kyle/Desktop/841898120.png");
// this represents fields from a form
NameValueCollection postData = new NameValueCollection();
//postData.Add("fieldName", "fieldValue");
// this could be an existing CookieContainer used in a previous request
// to contain session or other cookies. Typically used to maintain
// session state across several requests.
CookieContainer cookies = new CookieContainer();
cookies.Add(new Uri("https://www.roblox.com/"), new Cookie(".ROBLOSECURITY", ""));
//// end
HttpClientHandler h = new HttpClientHandler();
h.CookieContainer = cookies;
HttpClient client = new HttpClient(h);
var response2 = client.GetAsync("https://roblox.com/build/upload").Result;
var resultContent = response2.Content.ReadAsStringAsync().Result;
String rvt = GetRequestVerificationToken(resultContent);
Console.WriteLine("token: " + rvt);
/// end
postData.Add("__RequestVerificationToken", rvt);
postData.Add("assetTypeId", "12");
postData.Add("isOggUploadEnabled", "True");
postData.Add("isTgaUploadEnabled", "True");
postData.Add("groupId", "3656996");
postData.Add("name", "Jeffery StarS");
postData.Add("onVerificationPage", "False");
postData.Add("captchaEnabled", "False");
// you can send additional request headers with the headers collection
NameValueCollection headers = new NameValueCollection();
// headers.Add("x-headerName", "header value");
// content type of the posted file.
// if null, the content type will be determined by the filename.
// defaults to application/octet-stream
const string fileContentType = "png ";
// the key used to identify this file. typically unused.
// if null, 'file' will be submitted.
const string fileFieldName = "file";
string responseText;
WebResponse response = Upload.PostFile(new Uri("https://roblox.com/build/upload/"),
postData, filePath, fileContentType, fileFieldName,
cookies, headers, webBrowser1);
try
{
if (response != null)
{
Stream responseStream = response.GetResponseStream();
StreamReader r = new StreamReader(responseStream, Encoding.UTF8);
Console.WriteLine(r.ReadToEnd());
}
}
catch (WebException wex)
{
var pageContent = new StreamReader(wex.Response.GetResponseStream())
.ReadToEnd();
Console.WriteLine(pageContent);
}
}
public string GetRequestVerificationToken(String find)
{
String val = "name=__RequestVerificationToken";
String readInto = "";
int startRead = find.IndexOf(val, 0) + val.Length + 20;
while (find[startRead] != '>')
{
readInto += find[startRead];
++startRead;
}
return readInto;
}
}
}