0

I need to post data with files but I face this problem - all data is null.

It works when I use postman:

e

My post function in ASP.NET Core Web 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);
    }

My post function in ASP.NET Core 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");
    }

My 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");
    }
}
2
  • In your ASP.NET Core Web API can you change [FromForm] and put [FromBody] just to test? Commented Dec 25, 2019 at 14:12
  • not working too Commented Dec 25, 2019 at 15:24

1 Answer 1

2

If you want to post the multipart/form-data using HttpClient, you should write a separate post method using MultipartFormDataContent as HttpContent type as shown:

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 controller

var response = await _client.PostCategoryAsync(uri, category);

Web API enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

thank you very much, you are professional developer. can i get your email to send you the links of my problems in stackoverflow?
hi, my friend please check this problem you will earn more rep with me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.