Post 数据和文件使用 ASP.NET Core MVC 到 api(ASP.NET Core Web API)
Post data with files using ASP.NET Core MVC to api (ASP.NET Core Web API)
我需要 post 数据和文件,但我遇到了这个问题 - 所有数据都是空的。
当我使用 postman:
时有效
我在 ASP.NET Core Web 中的 post 函数 API:
public async Task<ActionResult<Category>> PostCategory([FromForm]CategoryViewModel model)
{
Category category = new Category()
{
Brief = model.Brief,
Color = model.Color,
IsDraft = model.IsDraft,
Name = model.Name,
Priority = model.Priority,
Update = DateTime.Now
};
if (model.Files != null)
{
category.IconUrl = ApplicationManager.UploadFiles(model.Files, "content/category")[0];
}
_context.Categories.Add(category);
await _context.SaveChangesAsync();
return CreatedAtAction("GetCategory", new { id = category.Id }, category);
}
我的 post 函数在 ASP.NET 核心 MVC 中:
private ApiClient _client;
_client = new ApiClient(new Uri("https:localhost:55436/api/"));
public async Task<IActionResult> Create([FromForm]CategoryViewModel category)
{
var uri = new Uri(_appSettings.WebApiBaseUrl + "Categories");
var response = await _client.PostAsync<Category, CategoryViewModel>(uri, category);
return RedirectToAction("index");
}
我的ApiClient
class:
public partial class ApiClient
{
private readonly HttpClient _httpClient;
private Uri BaseEndpoint { get; set; }
public ApiClient(Uri baseEndpoint)
{
if (baseEndpoint == null)
{
throw new ArgumentNullException("baseEndpoint");
}
BaseEndpoint = baseEndpoint;
_httpClient = new HttpClient();
}
/// <summary>
/// Common method for making GET calls
/// </summary>
public async Task<T> GetAsync<T>(Uri requestUrl)
{
addHeaders();
var response = await _httpClient.GetAsync(requestUrl, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
var data = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(data);
}
public async Task<HttpResponseMessage> PostStreamAsync(Uri requestUrl, object content)
{
using (var client = new HttpClient())
using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
using (var httpContent = CreateHttpContentForStream(content))
{
request.Content = httpContent;
using (var response = await client
.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)
.ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
return response;
}
}
}
public async Task<HttpResponseMessage> PostBasicAsync(Uri requestUrl, object content)
{
using (var client = new HttpClient())
using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
{
var json = JsonConvert.SerializeObject(content);
using (var stringContent = new StringContent(json, Encoding.UTF8, "application/json"))
{
request.Content = stringContent;
using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)
.ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
return response;
}
}
}
}
public static void SerializeJsonIntoStream(object value, Stream stream)
{
using (var sw = new StreamWriter(stream, new UTF8Encoding(false), 1024, true))
using (var jtw = new JsonTextWriter(sw) { Formatting = Formatting.None })
{
var js = new JsonSerializer();
js.Serialize(jtw, value);
jtw.Flush();
}
}
private static HttpContent CreateHttpContentForStream<T>(T content)
{
HttpContent httpContent = null;
if (content != null)
{
var ms = new MemoryStream();
SerializeJsonIntoStream(content, ms);
ms.Seek(0, SeekOrigin.Begin);
httpContent = new StreamContent(ms);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
}
return httpContent;
}
/// <summary>
/// Common method for making POST calls
/// </summary>
public async Task<T> PostAsync<T>(Uri requestUrl, T content)
{
addHeaders();
var response = await _httpClient.PostAsync(requestUrl.ToString(), CreateHttpContent<T>(content));
response.EnsureSuccessStatusCode();
var data = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(data);
}
public async Task<T1> PostAsync<T1, T2>(Uri requestUrl, T2 content)
{
addHeaders();
var response = await _httpClient.PostAsync(requestUrl.ToString(), CreateHttpContent<T2>(content));
response.EnsureSuccessStatusCode();
var data = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T1>(data);
}
public Uri CreateRequestUri(string relativePath, string queryString = "")
{
var endpoint = new Uri(BaseEndpoint, relativePath);
var uriBuilder = new UriBuilder(endpoint);
uriBuilder.Query = queryString;
return uriBuilder.Uri;
}
public HttpContent CreateHttpContent<T>(T content)
{
var json = JsonConvert.SerializeObject(content, MicrosoftDateFormatSettings);
var value = new StringContent(json, Encoding.UTF8, "application/json");
return value;
}
public static JsonSerializerSettings MicrosoftDateFormatSettings
{
get
{
return new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
}
}
public void addHeaders()
{
_httpClient.DefaultRequestHeaders.Remove("userIP");
_httpClient.DefaultRequestHeaders.Add("userIP", "192.168.1.1");
}
}
如果您想 post 使用 HttpClient multipart/form-data,您应该使用 MultipartFormDataContent
作为 HttpContent 类型编写一个单独的 post 方法,如下所示:
PostCategoryAsync
public async Task<Category> PostCategoryAsync(Uri requestUrl, CategoryViewModel content)
{
addHeaders();
var response = new HttpResponseMessage();
var fileContent = new StreamContent(content.Files.OpenReadStream())
{
Headers =
{
ContentLength = content.Files.Length,
ContentType = new MediaTypeHeaderValue(content.Files.ContentType)
}
};
var formDataContent = new MultipartFormDataContent();
formDataContent.Add(fileContent, "Files", content.Files.FileName); // file
//other form inputs
formDataContent.Add(new StringContent(content.Name), "Name");
formDataContent.Add(new StringContent(content.Brief), "Brief");
formDataContent.Add(new StringContent(content.IsDraft.ToString()), "IsDraft");
formDataContent.Add(new StringContent(content.Color), "Color");
formDataContent.Add(new StringContent(content.Priority), "Priority");
response = await _httpClient.PostAsync(requestUrl.ToString(), formDataContent);
var data = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode();
return JsonConvert.DeserializeObject<Category>(data);
}
MVC 控制器
var response = await _client.PostCategoryAsync(uri, category);
网络API
我需要 post 数据和文件,但我遇到了这个问题 - 所有数据都是空的。
当我使用 postman:
时有效我在 ASP.NET Core Web 中的 post 函数 API:
public async Task<ActionResult<Category>> PostCategory([FromForm]CategoryViewModel model)
{
Category category = new Category()
{
Brief = model.Brief,
Color = model.Color,
IsDraft = model.IsDraft,
Name = model.Name,
Priority = model.Priority,
Update = DateTime.Now
};
if (model.Files != null)
{
category.IconUrl = ApplicationManager.UploadFiles(model.Files, "content/category")[0];
}
_context.Categories.Add(category);
await _context.SaveChangesAsync();
return CreatedAtAction("GetCategory", new { id = category.Id }, category);
}
我的 post 函数在 ASP.NET 核心 MVC 中:
private ApiClient _client;
_client = new ApiClient(new Uri("https:localhost:55436/api/"));
public async Task<IActionResult> Create([FromForm]CategoryViewModel category)
{
var uri = new Uri(_appSettings.WebApiBaseUrl + "Categories");
var response = await _client.PostAsync<Category, CategoryViewModel>(uri, category);
return RedirectToAction("index");
}
我的ApiClient
class:
public partial class ApiClient
{
private readonly HttpClient _httpClient;
private Uri BaseEndpoint { get; set; }
public ApiClient(Uri baseEndpoint)
{
if (baseEndpoint == null)
{
throw new ArgumentNullException("baseEndpoint");
}
BaseEndpoint = baseEndpoint;
_httpClient = new HttpClient();
}
/// <summary>
/// Common method for making GET calls
/// </summary>
public async Task<T> GetAsync<T>(Uri requestUrl)
{
addHeaders();
var response = await _httpClient.GetAsync(requestUrl, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
var data = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(data);
}
public async Task<HttpResponseMessage> PostStreamAsync(Uri requestUrl, object content)
{
using (var client = new HttpClient())
using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
using (var httpContent = CreateHttpContentForStream(content))
{
request.Content = httpContent;
using (var response = await client
.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)
.ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
return response;
}
}
}
public async Task<HttpResponseMessage> PostBasicAsync(Uri requestUrl, object content)
{
using (var client = new HttpClient())
using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
{
var json = JsonConvert.SerializeObject(content);
using (var stringContent = new StringContent(json, Encoding.UTF8, "application/json"))
{
request.Content = stringContent;
using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)
.ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
return response;
}
}
}
}
public static void SerializeJsonIntoStream(object value, Stream stream)
{
using (var sw = new StreamWriter(stream, new UTF8Encoding(false), 1024, true))
using (var jtw = new JsonTextWriter(sw) { Formatting = Formatting.None })
{
var js = new JsonSerializer();
js.Serialize(jtw, value);
jtw.Flush();
}
}
private static HttpContent CreateHttpContentForStream<T>(T content)
{
HttpContent httpContent = null;
if (content != null)
{
var ms = new MemoryStream();
SerializeJsonIntoStream(content, ms);
ms.Seek(0, SeekOrigin.Begin);
httpContent = new StreamContent(ms);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
}
return httpContent;
}
/// <summary>
/// Common method for making POST calls
/// </summary>
public async Task<T> PostAsync<T>(Uri requestUrl, T content)
{
addHeaders();
var response = await _httpClient.PostAsync(requestUrl.ToString(), CreateHttpContent<T>(content));
response.EnsureSuccessStatusCode();
var data = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(data);
}
public async Task<T1> PostAsync<T1, T2>(Uri requestUrl, T2 content)
{
addHeaders();
var response = await _httpClient.PostAsync(requestUrl.ToString(), CreateHttpContent<T2>(content));
response.EnsureSuccessStatusCode();
var data = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T1>(data);
}
public Uri CreateRequestUri(string relativePath, string queryString = "")
{
var endpoint = new Uri(BaseEndpoint, relativePath);
var uriBuilder = new UriBuilder(endpoint);
uriBuilder.Query = queryString;
return uriBuilder.Uri;
}
public HttpContent CreateHttpContent<T>(T content)
{
var json = JsonConvert.SerializeObject(content, MicrosoftDateFormatSettings);
var value = new StringContent(json, Encoding.UTF8, "application/json");
return value;
}
public static JsonSerializerSettings MicrosoftDateFormatSettings
{
get
{
return new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
}
}
public void addHeaders()
{
_httpClient.DefaultRequestHeaders.Remove("userIP");
_httpClient.DefaultRequestHeaders.Add("userIP", "192.168.1.1");
}
}
如果您想 post 使用 HttpClient multipart/form-data,您应该使用 MultipartFormDataContent
作为 HttpContent 类型编写一个单独的 post 方法,如下所示:
PostCategoryAsync
public async Task<Category> PostCategoryAsync(Uri requestUrl, CategoryViewModel content)
{
addHeaders();
var response = new HttpResponseMessage();
var fileContent = new StreamContent(content.Files.OpenReadStream())
{
Headers =
{
ContentLength = content.Files.Length,
ContentType = new MediaTypeHeaderValue(content.Files.ContentType)
}
};
var formDataContent = new MultipartFormDataContent();
formDataContent.Add(fileContent, "Files", content.Files.FileName); // file
//other form inputs
formDataContent.Add(new StringContent(content.Name), "Name");
formDataContent.Add(new StringContent(content.Brief), "Brief");
formDataContent.Add(new StringContent(content.IsDraft.ToString()), "IsDraft");
formDataContent.Add(new StringContent(content.Color), "Color");
formDataContent.Add(new StringContent(content.Priority), "Priority");
response = await _httpClient.PostAsync(requestUrl.ToString(), formDataContent);
var data = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode();
return JsonConvert.DeserializeObject<Category>(data);
}
MVC 控制器
var response = await _client.PostCategoryAsync(uri, category);
网络API