简体   繁体   English

将angular2上传到asp.net核心

[英]uploading image with angular2 to asp.net core

So I have asp.net core application with angular2. 所以我有angular2的asp.net核心应用程序。 Now I want to upload image and I managed to do so if I upload it as byte[]. 现在我想上传图片,如果我将其上传为byte [],我就设法这样做了。 But then I can't check if file is realy image in backend so I tried to look for another solutions.. I found this blog about file upload: https://devblog.dymel.pl/2016/09/02/upload-file-image-angular2-aspnetcore/ but it does not work for me... 但后来我无法检查文件是否真的是后端的图像,所以我试图寻找另一种解决方案..我发现这篇关于文件上传的博客: https//devblog.dymel.pl/2016/09/02/upload- file-image-angular2-aspnetcore /但它对我不起作用......

For file upload I use angular2 library angular2-image-upload , so my html part of image upload looks like this: 对于文件上传我使用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>

then my angular2 part looks like this: 然后我的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;
    });
}

my angular2 api call looks like this: 我的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 });
}

my asp.net core controller ( NOTE that I'm not showing the body of controller because it is irrelevant ): 我的asp.net核心控制器(请注意,我没有显示控制器的主体,因为它是无关紧要的 ):

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

UserChange class: 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; }
}

The thing is that when I submit my image, I always getting my UserChange object as null. 问题是,当我提交我的图像时,我总是将我的UserChange对象设为null。 When I was adding image as byte[] it worked like a charm what is the problem?? 当我将图像添加为byte []时,它就像魅力一样有什么问题? Why I am getting always null even if I'm passing the file that is not null? 为什么即使我传递的文件不是null,我也总是为空? Other thing that I saw that when I change the type from IFormFile to FormFile my UserChange object is not null anymore but only File parameter from object is throwing this error 我看到的其他事情,当我将类型从IFormFile更改为FormFile时,我的UserChange对象不再为null,但只有来自object的File参数抛出此错误

'userChange.File.ContentDisposition' threw an exception of type 'System.NullReferenceException' 'userChange.File.ContentDisposition'引发了'System.NullReferenceException'类型的异常

UPDATE 1 更新1

Somehow I managed to send file to asp.net controller using this answer: File upload using Asp.Net Core Web API file is always null but to do so I had to create another action that has no parameters, but how to send file in my situation is still unknown... 不知怎的,我设法使用这个答案将文件发送到asp.net控制器: 使用Asp.Net Core Web API文件的文件上传始终为null但是这样做我必须创建另一个没有参数的操作,但是如何在我的文件中发送文件情况仍然未知......

I found your post when looking to do something similar, and also started out using the angular2-image-upload library, but decided to attempt the simple approach first. 我在寻找类似的东西时找到了你的帖子,并且也开始使用angular2-image-upload库,但是他决定先尝试这个简单的方法。 For my purposes I was only needing the byte[] image file (will attempt adding form fields for image title and caption next), and found some of what Michael Dymel suggests in his blog post here to be very helpful and got it working. 为了我的目的,我只需要byte []图像文件(将尝试添加图像标题和标题的表单字段),并发现Michael Dymel在他的博客文章中建议的一些非常有用并使其正常工作。 Despite that you've not been able to get your approach to work, it has helped me a lot. 尽管你没有能够让你的工作方法得到解决,但它对我帮助很大。

Where I came unstuck was with configuration of the correct routing, and for a time it looked like my file was being correctly picked up on the angular service, but was null when it got to the 'Upload' controller. 我遇到麻烦的地方是配置了正确的路由,有一段时间看起来我的文件在角度服务上被正确拾取,但是当它到达“上传”控制器时它是空的。 Once I checked that the path from the upload service and the path defined in the [Route("/api/upload")] attribute of the controller were the same, it all fell into place and I was able to upload successfully. 一旦我检查到上传服务的路径和控制器的[Route(“/ api / upload”)]属性中定义的路径是相同的,它就全部到位,我能够成功上传。 Slightly different issue to what you've had, but this worked for me: 与你所拥有的问题略有不同,但这对我有用:

My Upload component method: 我的上传组件方法:

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.");
    }
}

Calls the Upload service: 调用上传服务:

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

Which Posts to the 'Upload' ActionResult of my ImagesController, which looks like this (I'm saving my image to a database, so the 'path' variable is actually redundant). 哪个帖子到我的ImagesController的'Upload'ActionResult,看起来像这样(我将我的图像保存到数据库,所以'path'变量实际上是多余的)。 The 'Image' object is just a straightforward model for the Url, Title, ImageFileContent and Caption fields: “Image”对象只是Url,Title,ImageFileContent和Caption字段的简单模型:

[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);
}

And my html template fields were almost exactly as per Michael Dymel's post: 我的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>

You are cannot send binary data to server with json, because Json not supported binary data. 您无法使用json将二进制数据发送到服务器,因为Json不支持二进制数据。

Description Here 这里描述

But you can try send ' multipart/form-data ' 但你可以尝试发送' multipart / form-data '

Example Code .net Core Api: 示例代码.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();
  }

Example Code Angular Http Post Your Form Data: 示例代码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
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM