我正在尝试使用C#中的HttpClient进行多部分表单发布,并且发现以下代码不起作用。
重要:
var jsonToSend = JsonConvert.SerializeObject(json, Formatting.None, new IsoDateTimeConverter());
var multipart = new MultipartFormDataContent();
var body = new StringContent(jsonToSend, Encoding.UTF8, "application/json");
multipart.Add(body);
multipart.Add(new ByteArrayContent(File.ReadAllBytes("test.txt")), "test", "test.txt");
var httpClient = new HttpClient();
var response = httpClient.PostAsync(new Uri("http://localhost:55530"), multipart).Result;
完整计划:
namespace CourierMvc.Worker
{
class Program
{
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Hit any key to make request.");
Console.ReadKey();
try
{
var request = new RestRequest(Method.POST)
{
Resource = "http://localhost:55530"
};
var json = new CourierMessage
{
Id = Guid.NewGuid().ToString(),
Key = "awesome",
From = "khalid@home.com",
To = new[] { "me@test.com", "you@test.com" },
Subject = "test",
Body = "body",
Processed = DateTimeOffset.UtcNow,
Received = DateTime.Now,
Created = DateTime.Now,
Sent = DateTime.Now,
Links = new[] { new Anchor { Link = "http://google.com" }, new Anchor { Link = "http://yahoo.com" } }
};
var jsonToSend = JsonConvert.SerializeObject(json, Formatting.None, new IsoDateTimeConverter());
var multipart = new MultipartFormDataContent();
var body = new StringContent(jsonToSend, Encoding.UTF8, "application/json");
multipart.Add(body);
multipart.Add(new ByteArrayContent(File.ReadAllBytes("test.txt")), "test", "test.txt");
var httpClient = new HttpClient();
var response = httpClient.PostAsync(new Uri("http://localhost:55530"), multipart).Result;
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
}
我真的不知道为什么它不起作用。我把文件发布到端点,但是身体(json)永远不会到达那里。我做错了吗?
服务器端代码请求:
namespace CourierMvc.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return Content("Home#Index");
}
[ValidateInput(false)]
public ActionResult Create(CourierMessage input)
{
var files = Request.Files;
return Content("OK");
}
}
}
路线配置:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Create", id = UrlParameter.Optional }
);
}
答案 0 :(得分:50)
public class CourierMessage
{
public string Id { get; set; }
public string Key { get; set; }
public string From { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public DateTimeOffset Processed { get; set; }
public DateTime Received { get; set; }
public DateTime Created { get; set; }
public DateTime Sent { get; set; }
public HttpPostedFileBase File { get; set; }
}
while (true)
{
Console.WriteLine("Hit any key to make request.");
Console.ReadKey();
using (var client = new HttpClient())
{
using (var multipartFormDataContent = new MultipartFormDataContent())
{
var values = new[]
{
new KeyValuePair<string, string>("Id", Guid.NewGuid().ToString()),
new KeyValuePair<string, string>("Key", "awesome"),
new KeyValuePair<string, string>("From", "khalid@home.com")
//other values
};
foreach (var keyValuePair in values)
{
multipartFormDataContent.Add(new StringContent(keyValuePair.Value),
String.Format("\"{0}\"", keyValuePair.Key));
}
multipartFormDataContent.Add(new ByteArrayContent(File.ReadAllBytes("test.txt")),
'"' + "File" + '"',
'"' + "test.txt" + '"');
var requestUri = "http://localhost:5949";
var result = client.PostAsync(requestUri, multipartFormDataContent).Result;
}
}
}
答案 1 :(得分:6)
所以我看到的问题是MultipartFormDataContent
请求消息将始终将请求的内容类型设置为“multipart / form-data”。将json结束并将其置于请求中仅“看起来”类似于模型绑定器作为字符串。
您的选择是:
如果您将MultipartFormDataContent
替换为MultipartContent
,则可以通过the RFC document和the MSDN documentation阅读这些内容。但我还没有测试过。
答案 2 :(得分:6)
这是如何使用MultipartFormDataContent使用HTTPClient发布字符串和文件流的示例。需要为每个HTTPContent指定Content-Disposition和Content-Type:
这是我的榜样。希望它有所帮助:
private static void Upload() { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("User-Agent", "CBS Brightcove API Service"); using (var content = new MultipartFormDataContent()) { var path = @"C:\B2BAssetRoot\files\596086\596086.1.mp4"; string assetName = Path.GetFileName(path); var request = new HTTPBrightCoveRequest() { Method = "create_video", Parameters = new Params() { CreateMultipleRenditions = "true", EncodeTo = EncodeTo.Mp4.ToString().ToUpper(), Token = "x8sLalfXacgn-4CzhTBm7uaCxVAPjvKqTf1oXpwLVYYoCkejZUsYtg..", Video = new Video() { Name = assetName, ReferenceId = Guid.NewGuid().ToString(), ShortDescription = assetName } } }; //Content-Disposition: form-data; name="json" var stringContent = new StringContent(JsonConvert.SerializeObject(request)); stringContent.Headers.Add("Content-Disposition", "form-data; name=\"json\""); content.Add(stringContent, "json"); FileStream fs = File.OpenRead(path); var streamContent = new StreamContent(fs); streamContent.Headers.Add("Content-Type", "application/octet-stream"); streamContent.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\"" + Path.GetFileName(path) + "\""); content.Add(streamContent, "file", Path.GetFileName(path)); //content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); Task message = client.PostAsync("http://api.brightcove.com/services/post", content); var input = message.Result.Content.ReadAsStringAsync(); Console.WriteLine(input.Result); Console.Read(); } } }
答案 3 :(得分:0)
string path = @"C:\New folder\Test.pdf"; // **ANY FILE**
var formContent = new MultipartFormDataContent
{
{ new ByteArrayContent(File.ReadAllBytes(path)), "file", Path.GetFileName(path) }
};
var client = new HttpClient();
var response = client.PostAsync(_configuration["Url"], formContent).Result;