【问题标题】:uploading image with angular2 to asp.net core将带有 angular2 的图像上传到 asp.net 核心
【发布时间】:2017-11-30 10:00:23
【问题描述】:

所以我有 angular2 的 asp.net 核心应用程序。现在我想上传图片,如果我将它上传为 byte[],我设法做到了。但后来我无法检查文件是否是后端中的真实图像,所以我试图寻找其他解决方案。我发现这个关于文件上传的博客:https://devblog.dymel.pl/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。 当我将图像添加为 byte[] 时,它就像一个魅力有什么问题?为什么即使我传递的文件不为空,我也总是为空?我看到的其他事情是,当我将类型从 IFormFile 更改为 FormFile 时,我的 UserChange 对象不再为空,但只有来自对象的 File 参数抛出此错误

“userChange.File.ContentDisposition”引发了“System.NullReferenceException”类型的异常

更新 1

不知何故,我设法使用以下答案将文件发送到 asp.net 控制器:File upload using Asp.Net Core Web API file is always null 但为此我必须创建另一个没有参数的操作,但在我的情况下如何发送文件仍然未知......

【问题讨论】:

    标签: c# asp.net image angular file-upload


    【解决方案1】:

    我在想做类似的事情时发现了你的帖子,并且开始使用 angular2-image-upload 库,但决定先尝试简单的方法。出于我的目的,我只需要 byte[] 图像文件(接下来将尝试为图像标题和标题添加表单字段),并发现 Michael Dymel 在他的博客文章中提出的一些建议非常有帮助并使其正常工作。尽管您无法以自己的方式工作,但它对我帮助很大。

    我遇到困难的地方是配置了正确的路由,有一段时间它看起来我的文件在 angular 服务上被正确拾取,但在到达“上传”控制器时为空。一旦我检查了上传服务的路径和控制器的 [Route("/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 );
        }
    

    Which Posts 到我的 ImagesController 的“上传”ActionResult,看起来像这样(我正在将图像保存到数据库中,因此“路径”变量实际上是多余的)。 '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);
    }
    

    而且我的 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>
    

    【讨论】:

      【解决方案2】:

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

      描述Here

      但你可以尝试发送'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
        }
      

      【讨论】:

        猜你喜欢
        • 2017-07-17
        • 2019-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-17
        • 2014-04-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多