I am using ASP.Net Core 3.0 and I want to create a new product with images but my app crashes after i choose the image from the file upload and push the 'create' button. I tried to debug on my controller but the app crashes before it reaches the controller. Everything else is working on create action. When I comment out the file input, everything else works fine. I just want the image to be posted with the rest of my ProductModelVM so I can handle then in my controller.
Here is my ProductPostVM model:
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace WebshopAppMVC.Models
{
public class ProductPostVM
{
//[JsonPropertyName("id")]
//public int Id { get; set; }
[Required]
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("description")]
public string Description { get; set; }
[Required]
[JsonPropertyName("price")]
public double Price { get; set; }
[Required]
[JsonPropertyName("manufacturerId")]
// A product has one manufacturer
public int ManufacturerId { get; set; }
[Required]
[JsonPropertyName("categories")]
// products can have many Categories
public ICollection<int> Categories { get; set; }
[JsonPropertyName("images")]
// one product can have many images
public IEnumerable<IFormFile> Images { get; set; }
}
}
Here is my Create.cshtml:
@model WebshopAppMVC.Models.ProductPostVM
@using System.Text.Json;
@using WebshopAppMVC.Models;
@using Microsoft.AspNetCore.Http;
@{
ViewData["Title"] = "Create";
List<ManufacturerVM> manufacturers = JsonSerializer.Deserialize<List<ManufacturerVM>>(@Context.Session.GetString("manufacturers"));
SelectList manufacturersData = new SelectList(manufacturers, "Id", "Name");
List<CategoryVM> categories = JsonSerializer.Deserialize<List<CategoryVM>>(@Context.Session.GetString("categories"));
}
<h1>Create</h1>
<h4>ProductPostVM</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
@*<div class="form-group">
<label asp-for="Id" class="control-label"></label>
<input asp-for="Id" class="form-control" />
<span asp-validation-for="Id" class="text-danger"></span>*@
@*</div>*@
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Price" class="control-label"></label>
<input asp-for="Price" class="form-control" />
<span asp-validation-for="Price" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ManufacturerId" class="control-label"></label>
<select asp-for="ManufacturerId" class="form-control" asp-items=@manufacturersData>
<option value="">Please select</option>
</select>
<span asp-validation-for="ManufacturerId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Categories" class="control-label"></label>
<div class="col-md-offset-2 col-md-10">
<table>
<tr>
@{
int cnt = 0;
foreach (var category in categories)
{
if (cnt++ % 3 == 0)
{
@:</tr><tr>
}
@:<td>
<input type="checkbox"
name="Categories"
value="@category.Id"
@(Html.Raw(category.Assigned ? "checked=\"checked\"" : "")) />
@category.Name
@:</td>
}
@:</tr>
}
</table>
</div>
</div>
<div class="form-group">
<dl>
<dt>
<label asp-for="Images"></label>
</dt>
<dd>
<input asp-for="Images" type="file" multiple>
</dd>
</dl>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
and this is the code in my controller for the create action:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ProductPostVM productPost)
{
if (ModelState.IsValid)
{
//foreach (string file in Request.)
//{
// var postedFile = Request.Files[file];
// postedFile.SaveAs(Server.MapPath("~/UploadedFiles/") + Path.GetFileName(postedFile.FileName));
//}
var client = _httpClientFactory.CreateClient();
var productContent = new StringContent(JsonSerializer.Serialize(productPost), Encoding.UTF8, "application/json");
HttpResponseMessage httpResponseMessage = await client.PostAsync(new Uri("https://localhost:44352/api/products"), productContent).ConfigureAwait(false);
if (httpResponseMessage.IsSuccessStatusCode)
{
return RedirectToAction(nameof(Index));
}
}
return View(productPost);
}
Here is a picture of how my view looks:
This behavior in specific has been attributed to a browser problem and not Visual Studio
in general. As per this article and this article, this behavior was generally observed when using browsers like Brave
in this case and Yandex
. Sometimes even Chrome
shows this behavior but it is not consistent (at least that is what I have observed).
A possible solution would be changing your browser type to use ideal browsers like Chrome, Firefox or Edge.
For users using Brave
browser, an alternative would be:
Turning the Shields off(down) stops the crashing. You can do this by clicking the shield icon to the right of the URL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With