Как получить файл в [FromBody] ASP.NET CORE 2 & Angular 5 - PullRequest
0 голосов
/ 01 июня 2018

Я хочу отправить изображение файла из моей формы Angular 5 Reactive в мой ASP.NET, пока я делал это:

мой Angular:

Интерфейс организации:

export interface Organization {
    id: number;
    organizationName: string;
    legalName: string;
    logoUrl: string;
    logoFile: any;
    ....
}

organization.form.html

<form [formGroup]="editForm" (ngSubmit)="save()" class="form-horizontal">
  ...
  <div class="form-group  required" [ngClass]="{'has-error': editForm.get('legalName').touched && editForm.get('legalName').hasError('required')}">
    <label class="col-sm-2" for="legalName">Legal/Trading Name</label>
    <div class="col-sm-7">
      <input class="form-control" placeholder="Legal/Trading Name" formControlName="legalName">
      <span class="help-block" *ngIf="editForm.get('legalName').touched && editForm.get('legalName').hasError('required')">Legal/Trading Name is required</span>
    </div>
  </div>
  <div class="form-group  required" [ngClass]="{'has-error': editForm.get('logoUrl').touched && editForm.get('logoUrl').hasError('required')}">
    <label class="col-sm-2" for="logoUrl">Logo</label>
    <div class="col-sm-7">
      <input type="file" accept="image/*" name="logoFile" placeholder="Logo" (change)="showPreviewImage($event)">
      <img [src]="localUrl" width="150" *ngIf="localUrl" class="imagePlaceholder">
      <input type="hidden" name="fileHidden" formControlName="logoUrl" />
      <!-- Validation Field -->

      <span class="help-block" *ngIf="editForm.get('logoUrl').touched && editForm.get('logoUrl').hasError('required')">Logo is required</span>
    </div>
  </div>

organization-form.component.ts

// i want to display a upload image so I put on localImg

showPreviewImage(event: any) {
  if (event.target.files && event.target.files[0]) {
    var reader = new FileReader();
    var file = event.target.files[0];
    reader.readAsDataURL(file);
    reader.onload = () => {
      this.localImg= reader.result;

      this.editForm.patchValue({
        logoUrl: file.name,
        logoFile: reader.result,
      });
      this.editForm.markAsDirty();
    }
  }

}

при нажатии кнопки сохранения:

save() {
  this.onSubmit.emit(this.editForm.value); 
}

Далее я отправляю на свой сервер asp.net core 2 с HttpClient:

create(org: Organization) {
  return this.httpClient.post(this.baseUrl + 'organization/create', org);
}

Я отправляю изображение и данные и вижу в своей сети Chrome Inspection: data sent to asp.net server

На сервереконтроллер:

[HttpPost("create")]
        public async Task<IActionResult> CreateOrganization([FromBody] OrganizationDto orgDto)
        {
            // check the same name of organization
            if (await _orgRepo.OrganizationExist(orgDto.OrganizationName))
            {
                ModelState.AddModelError("OrganizationName", "Organization Name already exists");
            }
            if (!ModelState.IsValid)
                return BadRequest(ModelState);
            var orgToCreate = _mapper.Map<Organization>(orgDto);
            var file = orgDto.LogoFile;
            if(file != null) {
                using (var stream = new FileStream(this.logosFolderPath, FileMode.Create))  
                {  
                    await file.CopyToAsync(stream);  
                    orgToCreate.LogoUrl = Path.GetFileName(file.FileName);
                    throw new Exception(orgDto.LogoUrl);
                }  
            }
            // var createdOrg = await _orgRepo.CreateOrganization(orgToCreate);
            // var orgToReturn = _mapper.Map<OrganizationDetailedDto>(createdOrg);

            // return Ok(orgToReturn);
            return Ok(orgDto);
        }

my OrganizationDto:

public class OrganizationDto
    {
        [Required]
        public int Id { get; set; }
        [Required]
        public string OrganizationName { get; set; }
        [Required]
        public string LegalName { get; set; }
        [Required]
        public string LogoUrl { get; set; }
        public IFormFile LogoFile {get;set;}

, но когда я отлаживаю это, переменная orgDto имеет значение null (не инициализируется или не получает данные из angular).Если в Angular установить для logoFile пустое значение, оно будет работать ... но когда я добавлю в него файл ... оно не будет работать.

Есть идеи, как с этим справиться?Я читал в Интернете, мы не можем использовать multipart / form-data в форме ... я до сих пор понятия не имею об этом.пожалуйста помоги.спасибо

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Согласно моему опыту, вы не можете отправить данные файла как обычный запрос Json.Для этого вы должны использовать данные формы.Тогда ваш запрос будет выглядеть так:

let formToPost = new FormData();
//stringify your normal request
let requestToPost = JSON.stringify({id:1; organizationName: ABC; legalName: DEF}); 

formToPost .append("request", requestToPost);
formToPost .append("logoFile", YOUR_IMAGE_FILE);

Тогда на уровне контроллера вы можете сделать что-то вроде этого:

[HttpPost]
public async Task<YOUR_RESPON> AddTicketAsync(string request, List<IFormFile> logoFile)
{
  var request = JsonConvert.DeserializeObject<YOUR_TYPE>(request);
}

Здесь вы можете напрямую получить доступ к вашему файлу изображения.

Надеюсь, это поможет:)

0 голосов
/ 01 июня 2018

Я считаю, что ваш вызов Http немного упрощен.Попробуйте добавить Content-Type:

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type':  'application/json',
    'Authorization': 'my-auth-token' // if you have one
  })
};

addOrganization (org: Organization): Observable<Organization> {
  return this.httpClient.post<Organization>(this.heroesUrl, org, httpOptions)
    .pipe(
      catchError(this.handleError('addOrganization ', org))
    );
}

Затем вы вызываете его, подписавшись на него, что-то вроде этого:

this.addOrganization(org).subscribe(
  (data: any) => {
     console.log(data, 'returned data');
  },
  (error: any) => {
     console.error(error, 'error received');
  }
);
...