英文:
ASP.NET 3.0 mvc app crash after file/image upload
问题
我正在使用ASP.Net Core 3.0,我想要创建一个带有图片的新产品,但是当我从文件上传中选择图片并点击'创建'按钮后,我的应用程序崩溃了。我尝试在我的控制器上进行调试,但是在到达控制器之前应用程序就崩溃了。在创建操作上,其他一切都正常工作。当我注释掉文件输入时,其他一切都正常。
我只想将图像与我的ProductModelVM的其余部分一起发布,以便我可以在我的控制器中处理它们。
这是我的ProductPostVM模型:
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")]
// 一个产品有一个制造商
public int ManufacturerId { get; set; }
[Required]
[JsonPropertyName("categories")]
// 产品可以有多个类别
public ICollection<int> Categories { get; set; }
[JsonPropertyName("images")]
// 一个产品可以有多个图像
public IEnumerable<IFormFile> Images { get; set; }
}
}
这是我的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>
这是我的控制器中创建操作的代码:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ProductPostVM productPost)
{
if (ModelState.IsValid)
{
//foreach (string file in Request.)
//{
// var postedFile = Request.Files;
// 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);
}
这是我的视图的样子:
英文:
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;
// 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:
答案1
得分: 22
这个特定行为被归因于浏览器问题,而不是总体上的Visual Studio
。根据这篇文章和这篇文章,通常情况下,在使用像Brave
和Yandex
这样的浏览器时,会观察到这种行为。有时甚至Chrome
也会出现这种行为,但不一致(至少这是我观察到的情况)。
一个可能的解决方案是将浏览器类型更改为使用像Chrome、Firefox或Edge这样的理想浏览器。
对于使用Brave
浏览器的用户,另一种选择是:
> 关闭Shields(向下)会停止崩溃。您可以通过点击URL右侧的盾牌图标来做到这一点。
英文:
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.
答案2
得分: 0
您的 <form>
标签使用了错误的方法属性。method="get"
是默认值。
尝试
<form asp-action="Create" enctype="multipart/form-data" method="post">
英文:
Your <form>
tag is using the wrong method attribute. method="get"
is the default value.
Try
<form asp-action="Create" enctype="multipart/form-data" method="post">
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论