c# - 为什么我会收到“无法创建 Microsoft.AspNetCore.Http.IFormFile 类型的实例”错误?
问题描述
我得到了这个非常有用的错误。但是找不到问题。
{"ClassName":"Newtonsoft.Json.JsonSerializationException","Message":"Could not create an instance of type Microsoft.AspNetCore.Http.IFormFile. Type is an interface or abstract class and cannot be instantiated. Path 'file.ContentDisposition', line 1, position 63.","Data":null,"InnerException":null,"HelpURL":null,"StackTraceString":" at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)\r\n at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)\r\n at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)\r\n at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)\r\n at Microsoft.Azure.Cosmos.CosmosJsonDotNetSerializer.FromStream[T](Stream stream)\r\n at Microsoft.Azure.Cosmos.CosmosJsonSerializerWrapper.FromStream[T](Stream stream)\r\n at Microsoft.Azure.Cosmos.CosmosSerializerCore.FromStream[T](Stream stream)\r\n at Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.ToObjectpublic[T](ResponseMessage responseMessage)\r\n at Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.<CreateItemResponse>b__8_0[T](ResponseMessage cosmosResponseMessage)\r\n at Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.ProcessMessage[T](ResponseMessage responseMessage, Func`2 createResponse)\r\n at Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.CreateItemResponse[T](ResponseMessage responseMessage)\r\n at Microsoft.Azure.Cosmos.ContainerCore.CreateItemAsync[T](CosmosDiagnosticsContext diagnosticsContext, T item, Nullable`1 partitionKey, ItemRequestOptions requestOptions, CancellationToken cancellationToken)\r\n at Microsoft.Azure.Cosmos.ClientContextCore.RunWithDiagnosticsHelperAsync[TResult](CosmosDiagnosticsContext diagnosticsContext, Func`2 task)\r\n at SmartLearning_salon.Services.Person.PersonService.AddItemAsync(Person person) in C:\\Users\\knoer\\source\\repos\\SmartLearning_salon\\SmartLearning_salon\\Services\\Person\\PersonService.cs:line 25\r\n at SmartLearning_salon.Controllers.PersonController.Create(Person person) in C:\\Users\\knoer\\source\\repos\\SmartLearning_salon\\SmartLearning_salon\\Controllers\\PersonController.cs:line 67","RemoteStackTraceString":null,"RemoteStackIndex":0,"ExceptionMethod":null,"HResult":-2146233088,"Source":"Newtonsoft.Json","WatsonBuckets":null}
我的 ASP.NET MVC 应用程序中的控制器首先将文件发送到 Azure 存储,然后将记录添加到 Cosmos DB。文件和记录都正确保存/存储。但是在保存页面后返回以下错误“无法创建 Microsoft.AspNetCore.Http.IFormFile 类型的实例”
我知道不可能从接口实例化对象,但这是在哪里发生的呢?
在我的 ASP.NET MVC Core 3.1 中,我有一个看起来像这样的模型
public class Person
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "ssn")]
public string Ssn { get; set; }
//[JsonProperty(PropertyName = "testresult")]
//public bool TestResult { get; set; }
[JsonProperty(PropertyName = "file")]
public IFormFile File { get; set; }
}
我的 PersonController 看起来像这样
// POST: PersonController/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Person person)
{
using (var stream = new MemoryStream())
{
try
{
// assume a single file POST
await person.File.CopyToAsync(stream);
stream.Seek(0, SeekOrigin.Begin);
// now send blob up to Azure
await _blobStorageService.CreateBlobAsync(person.File.OpenReadStream(), person.File.FileName);
// send to Cosmos
await _personService.AddItemAsync(person);
//Ændre dette til at returnere et til detail view
return View("Person");
//return Ok(new { fileuploaded = true });
}
catch (Exception ex)
{
return BadRequest(ex);
}
}
}
我的个人服务
public async Task AddItemAsync(Models.Person person)
{
await container.CreateItemAsync(person, new PartitionKey(person.Id));
}
我的存储服务
public async Task CreateBlobAsync(Stream stream, string filename)
{
try
{
//Opret hvis ikkke eksisterer
await bcc.CreateIfNotExistsAsync();
await bcc.UploadBlobAsync(filename, stream);
}
catch (Exception)
{
throw;
}
}
我真的很感谢我能得到的所有帮助。
谢谢克劳斯
解决方案
IFormFile
是一个接口。没有上下文就无法创建它们。
您正在尝试使用您的表单编码版本来Person
对数据存储进行建模。
您应该有两个独立的模型:一个用于表单提交,另一个用于数据存储:
public class PersonForm
{
public string Id { get; set; }
public string Name { get; set; }
public string Ssn { get; set; }
public IFormFile File { get; set; }
}
public class Person
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("ssn")]
public string Ssn { get; set; }
[JsonProperty("fileName")]
public string FileName { get; set; }
}
然后您的端点将如下所示:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([FromForm] PersonForm personForm)
{
try
{
// now send blob up to Azure
await _blobStorageService.CreateBlobAsync(
personForm.File.OpenReadStream(), personForm.File.FileName);
// send to Cosmos
await _personService.AddItemAsync(new Person
{
Id = personForm.Id,
Name = personForm.Name,
Ssn = personForm.Ssn,
FileName = personForm.File.FileName
});
//Ændre dette til at returnere et til detail view
return View("Person");
}
catch (Exception ex)
{
return BadRequest(ex);
}
}
当许多属性相同时,您可以使用AutoMapper
它来更轻松地复制 DTO 对象。
推荐阅读
- laravel - Laravel 应用程序非常慢 - 启动超过 3 秒,加载超过 2 秒
- javascript - PHP 没有得到 Ajax 的发送值
- android - 调用 startActivityForResult 后是否会发生配置更改?
- swiftui - 在 SwiftUI 中传递 Lat/Long 函数
- javascript - Gatsby Image 查询返回乱序图像
- javascript - 如何从函数内部发送消息(Discord.js)
- python - 丢失的字母,基本转换
- powerbi - 何时在 Power BI 中使用计算字段与度量?
- javascript - 修复了导航栏在不在顶部且不滚动时消失的问题,无法按预期工作
- docker - 如何在 Docker 中通过端点创建不同的端口映射?