将图像用Angular2上传到ASP.NET核心



,所以我有ASP.NET核心应用程序Angular2。现在,我想上传图像,如果我将其上传为字节[],则设法这样做。但是,我无法检查文件是否是后端中的图像是否确实是图像,所以我尝试寻找其他解决方案。我找到了有关文件上传的博客:https://devblog.dymel.pl/2l/2016/09/02/upload---file-image-angular2-aspnetcore/它对我不起作用...

用于文件上传我使用angular2库 angular2-image-upload ,所以我的html图像上传的一部分看起来像这样:

<image-upload [max]="1" [buttonCaption]="'Browse'" [preview]="false" (change)="onFileChange($event)"></image-upload>
<button (click)="onSaveChanges()" class="btn btn-primary float-left" type="submit">Save</button>

然后我的angular2部分看起来像这样:

onFileChange(event: any) {
    this.file = event.target.files[0];
    if (event.target.files && this.file) {
        var reader = new FileReader();
        reader.onload = (event: any) => {
            this.profilePicture = event.target.result;
        }
        reader.readAsDataURL(this.file);
    }
}
onSaveChanges() {
    this.isSaving = true;
    this.country = this.state.user.country;
    this.userService.userChange(this.firstName, this.lastName, this.country, this.file, this.currentPassword, this.newPassword).subscribe(success => {
        this.state.user.profilePicture = this.profilePicture;
        this.state.user.firstName = this.firstName;
        this.state.user.lastName = this.lastName;
        this.isSaving = false;
        this.passwordError = false;
        this.isSuccessful = true;
        this.currentPassword = '';
        this.newPassword = '';
        this.newPasswordRepeat = '';
    }, error => {
        this.isSaving = false;
        this.passwordError = true;
        this.passwordErrorMessage = error._body;
    });
}

我的angular2 api呼叫看起来像这样:

userChange(firstName: string, lastName: string, country: string, file: File, oldPassword: string, newPassword: string) {
    let input = new FormData();
    input.append("File", file);
    var url = this.baseUrl + "updateUser";
    return this.http.post(url, { FirstName: firstName, LastName: lastName, Country: country, File: input, OldPassword: oldPassword, NewPassword: newPassword });
}

我的ASP.NET核心控制器(请注意,我没有显示控制器的主体,因为它是无关的(:

[HttpPost]
public async Task<IActionResult> UpdateUser([FromBody]UserChange userChange)
{ 
}

UserChange类:

public class UserChange
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Country { get; set; }
    public IFormFile File { get; set; }
    public string OldPassword { get; set; }
    public string NewPassword { get; set; }
}

问题是,当我提交图像时,我总是将我的userChange对象作为null。当我添加图像时,它像魅力有什么问题?为什么即使我传递了不是null的文件,我也会始终变得无效?我看到的另一件事是,当我将类型从iformfile更改为FormFile时,我的UserChange对象不再为空,而只有来自对象的文件参数是抛出此错误

'userChange.file.ContentDisposition'抛出了一个例外'System.NullReferenceException'

更新1

以某种方式,我设法使用以下答案将文件发送到ASP.NET控制器:使用ASP.NET Core Web API文件上传文件始终是无效的,但是我必须创建另一个没有参数的操作,但是如何发送在我的情况下,文件仍然未知...

我在想做类似的事情时找到了您的帖子,还开始使用angular2-image-upload库,但决定先尝试简单的方法。出于我的目的,我只需要字节[]图像文件(将尝试为下一个图像标题和字幕添加表单字段(,并在此处找到了Michael Dymel在此博客文章中提出的一些内容,这非常有用并使其正常工作。尽管您无法获得工作方法,但它对我有很大帮助。

我被解开的地方是正确的路由配置,并且有一段时间看起来我的文件在Angular Service上正确拾取了,但是当它到达"上传"控制器时是无效的。一旦我检查了上传服务的路径和控制器的[路由("/api/upload"(属性中定义的路径是相同的,所有这些属性都落在适当的位置,我能够成功上传。与您的问题略有不同,但这对我有用:

我的上传组件方法:

addFile(): void {
    let fi = this.fileInput.nativeElement;
    if (fi.files && fi.files[0]) {
        let fileToUpload = fi.files[0];
        if (fileToUpload) {
            this.uploadService.upload(fileToUpload)
            .subscribe(res => {
                console.log(res);
            });
        }
        else
            console.log("FileToUpload was null or undefined.");
    }
}

调用上传服务:

upload(fileToUpload: any) {
        let input = new FormData();
        input.append("fileForController", fileToUpload);
        return this.http.post("/api/upload", input );
    }

哪些张贴在我的ImagesController的"上传"操作中,看起来像这样(我将图像保存到数据库中,因此"路径"变量实际上是冗余的(。"图像"对象只是URL,标题,图像filecontent和字幕字段的简单模型:

[HttpPost]
[Route("/api/upload")]
public async Task<IActionResult> Upload(IFormFile fileForController)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    if (fileForController == null) throw new Exception("File is null");
    if (fileForController.Length == 0) throw new Exception("File is empty");
    var theImage = new Image();
    var path = Path.Combine("~\ClientApp\app\assets\images\", fileForController.FileName);
    theImage.Url = path + fileForController.FileName;
    theImage.Title = fileForController.Name + "_" + fileForController.FileName;
    theImage.Caption = fileForController.Name + " and then a Surprice Caption";
    using (Stream stream = fileForController.OpenReadStream())
    {
        using (var reader = new BinaryReader(stream))
        {
            var fileContent = reader.ReadBytes((int)fileForController.Length);
            theImage.ImageFileContent = fileContent;
            _context.Images.Add(theImage);
            try
            {
                await _context.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
    }
    return Ok(theImage);
}

和我的HTML模板字段几乎完全像Michael Dymel的帖子一样:

<form action="gallery" name="fileUploadForm" method="post" enctype="multipart/form-data">
    <div class="col-md-6">
        <input #fileInput type="file" title="Choose Image to upload" />
        <button (click)="addFile()" class="btn btn-success">Add</button>
    </div>
</form>

您无法使用JSON向服务器发送二进制数据,因为JSON不支持二进制数据。

描述在这里

但是您可以尝试发送' Multipart/form-data '

示例代码.NET CORE API:

 public class FormModel
 {
        public int Id { get; set; }
        public string Title{ get; set; }
        public string Url { get; set; }
        public bool IsDeleted { get; set; }
        public IFormFile File { get; set; }
 }
 [HttpPost]
 public IActionResult Post([FromForm] FormModel formModel)
 {
        if (!ModelState.IsValid)
            return BadRequest(ModelState);
        //** your server side code **//
        return Ok();
  }

示例代码Angular HTTP发布您的表格数据:

  const formData = new FormData();
  formData.append('File', this.file[0] // your input file data);
  formData.append('Id', this.Id.value // your form id value);
  formData.append('Title', this.Title.value // your form title value);
  formData.append('Url', this.Url.value // your form url value)
  const options = new RequestOptions();
  options.headers = new Headers();
  options.headers.append('enctype', 'multipart/form-data');
  this.http.post('your api url', formData, options) {
     // your return value
  }

最新更新