ASP.Net 核心 3.1 - 使用视图模型上传文件始终为 NULL
ASP.Net Core 3.1 - File Upload With View Model gets always NULL
我正在尝试使用视图模型将文件上传到服务器。
我的模型是这样的:
using Microsoft.AspNetCore.Identity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
namespace XmlSigner.Data.Models
{
public class XmlFile : BaseModel
{
[IgnoreDataMember]
[ConcurrencyCheck] //2 file should not be same
[Column("FileContent", TypeName = "text"), Required(ErrorMessage = "File Content should be given"), MinLength(5), Display(Name = "File Content", Prompt = "Please Give File Content")]
public string FileLocationInServer { get; set; }
[Column("PreviousFileId"), Display(Name = "Previous Signed/Unsigned File", Prompt = "Please select Previous File")]
public long? PreviousFileId { get; set; }
[ForeignKey("PreviousFileId"), Display(Name = "Previous Signed/Unsigned File", Prompt = "Please Select Previous File")]
public virtual XmlFile PreviousSignedFile { get; set; }
}
}
我的视图模型是这样的:
using Microsoft.AspNetCore.Http;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using XmlSigner.Data.Models;
namespace XmlSigner.ViewModels
{
public class XmlFileAddViewModel
{
[Required(ErrorMessage = "File Content should be given"), MinLength(5), Display(Name = "File Content", Prompt = "Please Give File Content")]
public FormFile XmlFile { get; set; }
[Display(Name = "Previous Signed/Unsigned File", Prompt = "Please select Previous File")]
public long? PreviousFileId { get; set; }
[ForeignKey("PreviousFileId"), Display(Name = "Previous Signed/Unsigned File", Prompt = "Please Select Previous File")]
public virtual XmlFile PreviousSignedFile { get; set; }
}
}
View Form是这样的:
<form asp-action="Create" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="XmlFile" class="control-label"></label>
<input class="form-control" asp-for="XmlFile">
<span asp-validation-for="XmlFile" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PreviousFileId" class="control-label"></label>
<select asp-for="PreviousFileId" class="form-control" asp-items="ViewBag.PreviousFileId"></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
控制器是这样的:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(XmlFileAddViewModel xmlFileAddViewModel)
{
.........................
.........................
}
我发现的是:
所以,我得到的是上传的文件为空。
谁能帮我找出为什么我上传的文件为空?
更新:
如果我使用 IFormFile 那么我会得到这个错误-
System.InvalidCastException: The field of type Microsoft.AspNetCore.Http.FormFile must be a string, array or ICollection type.
at System.ComponentModel.DataAnnotations.MinLengthAttribute.IsValid(Object value)
at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value, ValidationContext validationContext)
at System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(Object value, ValidationContext validationContext)
at Microsoft.AspNetCore.Mvc.DataAnnotations.DataAnnotationsModelValidator.Validate(ModelValidationContext validationContext)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.ValidateNode()
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType(IValidationStrategy defaultStrategy)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata metadata, String key, Object model)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitChildren(IValidationStrategy strategy)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType(IValidationStrategy defaultStrategy)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata metadata, String key, Object model)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Validate(ModelMetadata metadata, String key, Object model, Boolean alwaysValidateAtTopLevel)
at Microsoft.AspNetCore.Mvc.ModelBinding.ObjectModelValidator.Validate(ActionContext actionContext, ValidationStateDictionary validationState, String prefix, Object model, ModelMetadata metadata)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.EnforceBindRequiredAndValidate(ObjectModelValidator baseObjectValidator, ActionContext actionContext, ParameterDescriptor parameter, ModelMetadata metadata, ModelBindingContext modelBindingContext, ModelBindingResult modelBindingResult)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
尝试使用 IFormFile
而不是 FormFile
,如下所示:
public class XmlFileAddViewModel
{
[Required(ErrorMessage = "File Content should be given"), MinLength(5), Display(Name = "File Content", Prompt = "Please Give File Content")]
public IFormFile XmlFile { get; set; }
[Display(Name = "Previous Signed/Unsigned File", Prompt = "Please select Previous File")]
public long? PreviousFileId { get; set; }
[Display(Name = "Previous Signed/Unsigned File", Prompt = "Please Select Previous File")]
public IFormFile PreviousSignedFile { get; set; }
}
正如@CodeCaster 所说,MinLengthAttribute
用于指定 property.So 中允许的数组或字符串数据的最小长度,您无法为 IFormFile
.[=14= 声明]
更改如下:
public class XmlFileAddViewModel
{
[Required(ErrorMessage = "File Content should be given"),Display(Name = "File Content", Prompt = "Please Give File Content")]
public IFormFile XmlFile { get; set; }
[Display(Name = "Previous Signed/Unsigned File", Prompt = "Please select Previous File")]
public long? PreviousFileId { get; set; }
}
我正在尝试使用视图模型将文件上传到服务器。
我的模型是这样的:
using Microsoft.AspNetCore.Identity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
namespace XmlSigner.Data.Models
{
public class XmlFile : BaseModel
{
[IgnoreDataMember]
[ConcurrencyCheck] //2 file should not be same
[Column("FileContent", TypeName = "text"), Required(ErrorMessage = "File Content should be given"), MinLength(5), Display(Name = "File Content", Prompt = "Please Give File Content")]
public string FileLocationInServer { get; set; }
[Column("PreviousFileId"), Display(Name = "Previous Signed/Unsigned File", Prompt = "Please select Previous File")]
public long? PreviousFileId { get; set; }
[ForeignKey("PreviousFileId"), Display(Name = "Previous Signed/Unsigned File", Prompt = "Please Select Previous File")]
public virtual XmlFile PreviousSignedFile { get; set; }
}
}
我的视图模型是这样的:
using Microsoft.AspNetCore.Http;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using XmlSigner.Data.Models;
namespace XmlSigner.ViewModels
{
public class XmlFileAddViewModel
{
[Required(ErrorMessage = "File Content should be given"), MinLength(5), Display(Name = "File Content", Prompt = "Please Give File Content")]
public FormFile XmlFile { get; set; }
[Display(Name = "Previous Signed/Unsigned File", Prompt = "Please select Previous File")]
public long? PreviousFileId { get; set; }
[ForeignKey("PreviousFileId"), Display(Name = "Previous Signed/Unsigned File", Prompt = "Please Select Previous File")]
public virtual XmlFile PreviousSignedFile { get; set; }
}
}
View Form是这样的:
<form asp-action="Create" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="XmlFile" class="control-label"></label>
<input class="form-control" asp-for="XmlFile">
<span asp-validation-for="XmlFile" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PreviousFileId" class="control-label"></label>
<select asp-for="PreviousFileId" class="form-control" asp-items="ViewBag.PreviousFileId"></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
控制器是这样的:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(XmlFileAddViewModel xmlFileAddViewModel)
{
.........................
.........................
}
我发现的是:
所以,我得到的是上传的文件为空。
谁能帮我找出为什么我上传的文件为空?
更新:
如果我使用 IFormFile 那么我会得到这个错误-
System.InvalidCastException: The field of type Microsoft.AspNetCore.Http.FormFile must be a string, array or ICollection type.
at System.ComponentModel.DataAnnotations.MinLengthAttribute.IsValid(Object value)
at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value, ValidationContext validationContext)
at System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(Object value, ValidationContext validationContext)
at Microsoft.AspNetCore.Mvc.DataAnnotations.DataAnnotationsModelValidator.Validate(ModelValidationContext validationContext)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.ValidateNode()
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType(IValidationStrategy defaultStrategy)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata metadata, String key, Object model)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitChildren(IValidationStrategy strategy)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType(IValidationStrategy defaultStrategy)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata metadata, String key, Object model)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Validate(ModelMetadata metadata, String key, Object model, Boolean alwaysValidateAtTopLevel)
at Microsoft.AspNetCore.Mvc.ModelBinding.ObjectModelValidator.Validate(ActionContext actionContext, ValidationStateDictionary validationState, String prefix, Object model, ModelMetadata metadata)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.EnforceBindRequiredAndValidate(ObjectModelValidator baseObjectValidator, ActionContext actionContext, ParameterDescriptor parameter, ModelMetadata metadata, ModelBindingContext modelBindingContext, ModelBindingResult modelBindingResult)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
尝试使用 IFormFile
而不是 FormFile
,如下所示:
public class XmlFileAddViewModel
{
[Required(ErrorMessage = "File Content should be given"), MinLength(5), Display(Name = "File Content", Prompt = "Please Give File Content")]
public IFormFile XmlFile { get; set; }
[Display(Name = "Previous Signed/Unsigned File", Prompt = "Please select Previous File")]
public long? PreviousFileId { get; set; }
[Display(Name = "Previous Signed/Unsigned File", Prompt = "Please Select Previous File")]
public IFormFile PreviousSignedFile { get; set; }
}
正如@CodeCaster 所说,MinLengthAttribute
用于指定 property.So 中允许的数组或字符串数据的最小长度,您无法为 IFormFile
.[=14= 声明]
更改如下:
public class XmlFileAddViewModel
{
[Required(ErrorMessage = "File Content should be given"),Display(Name = "File Content", Prompt = "Please Give File Content")]
public IFormFile XmlFile { get; set; }
[Display(Name = "Previous Signed/Unsigned File", Prompt = "Please select Previous File")]
public long? PreviousFileId { get; set; }
}