Я хочу знать, как лучше всего это сделать.
В своем приложении Angular 8 я выбираю файл img и хочу отправить этот файл изображения в. NET Базовый API-интерфейс. Внутренний сервис должен сохранить это изображение в базе данных.
html для моего селектора изображений -
<div class="image-picker" (click)="fileInput.click()">
<mat-icon [class.small]="imageUrl">file_upload</mat-icon>
<canvas width="500" height="380" #canvas hidden="true"></canvas>
<input #fileInput type="file" hidden="true" (change)="imageDataChanged($event)">
</div>
соответствующий .ts код -
imageDataChanged($event) {
var file = $event.target.files[0];
console.log(file);
var reader = new FileReader();
// get data from file input and emit as dataUrl
reader.addEventListener("load", () => {
var ctx = this.canvas.nativeElement.getContext('2d');
this.imageUrl = reader.result;
this.imagePicked.emit(this.imageUrl);
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
Так что я получить в моей консоли, детали, связанные с файлом, который я выбрал. Как имя, размер, дата, дата, измененная ..... После нажатия кнопки отправки я хотел бы опубликовать этот файл в бэкэнд-API. У меня вопрос - в каком формате и как. изображение base64? Какой код для этого. Как бы я это сделал? Как я уже сказал, мой бэкэнд находится в. NET Core.
Вот код, который я попытался -
[HttpPost]
[Route("CaptureSaveImg")]
public IActionResult CaptureSaveImg(HttpContext context)
{
string imageName = null;
var httpRequest = context.Request;
var postedFile = httpRequest.Form.Files["Image"];
try
{
if(postedFile!=null)
{
var fileName = postedFile.FileName;
var myUniqueFileName = Convert.ToString(Guid.NewGuid());
var fileExtension = Path.GetExtension(fileName);
var newFileName = string.Concat(myUniqueFileName, fileExtension);
var filepath = Path.Combine(_environment.WebRootPath, "CameraPics") + $@"\{newFileName}";
if (!string.IsNullOrEmpty(filepath))
{
// Storing Image in Folder
StoreInFolder(postedFile, filepath);
}
var imageBytes = System.IO.File.ReadAllBytes(filepath);
if (imageBytes != null)
{
StoreInDatabase(imageBytes);
}
return Json(new { Success = true, Message = "Image Saved." });
}
else
{
return Json(new { Success = false, Message = "An error occurred while saving the image." });
}
}
catch(Exception exp)
{
return Json(new { Success =false, Message="An unexpected error occurred!"});
}
}
private void StoreInDatabase(byte[] imageBytes)
{
try
{
if (imageBytes != null)
{
string base64String = Convert.ToBase64String(imageBytes, 0, imageBytes.Length);
string imageUrl = string.Concat("data:image/jpg;base64,", base64String);
ImageStore imageStore = new ImageStore()
{
CreateDate = DateTime.Now,
ImageBase64String = imageUrl,
ImageId = 0
};
_context.ImageStores.Add(imageStore);
_context.SaveChanges();
}
}
catch (Exception exp)
{
throw exp.InnerException;
}
}
private void StoreInFolder(IFormFile file, string fileName)
{
try
{
using (FileStream fs = System.IO.File.Create(fileName))
{
file.CopyTo(fs);
fs.Flush();
}
}
catch (Exception exp)
{
throw exp.InnerException;
}
}
html для нажатия кнопки -
<button class="btn btn-primary btn-lg btn-block" type="button" (click)="OnSubmit(Image)" >UPLOAD</button>
.ts для нажатия кнопки -
OnSubmit(file: File)
{
this.userRestService.uploadImage(this.fileToUpload)
.subscribe((data: any) => {
console.log('Done successfully! '+data.Message);
this.imageUrl = null;
});
}
В службе use-rest -
fileToUpload: File = null;
uploadImage(file: File) {
var reqHeader = new HttpHeaders({ 'No-Auth': 'True' });
const formData: FormData = new FormData();
formData.append('Image', file, file.name);
return this.http.post(this.baseUrl +'CaptureSaveImg', formData, { headers: reqHeader });
}
Я хочу сначала сохранить ее в пути к локальной папке, а затем оттуда прочитать файл и сохранить в БД. Я понимаю, что, когда я пытаюсь опубликовать его как fileToUpload, он, вероятно, отправляет значение null.
Проблема, с которой я сталкиваюсь - что мне отправлять / отправлять из внешнего интерфейса в API. Как. Можете ли вы показать мне некоторый код, который достиг бы этого. Можете ли вы дать мне пошаговое руководство для достижения этой цели.
Не стесняйтесь спрашивать более подробную информацию о том, что я пытался, чтобы лучше понять. Спасибо
ОБНОВЛЕНИЕ:
Я забыл упомянуть ранее, что мой компонент выбора изображений в основном является отдельным angular компонентом, который я использую, как на главной странице. Таким образом, код imageDataChanged ($ event) также находится в этом компоненте. Позвольте мне опубликовать.
<input #fileInput type="file" hidden="true" (change)="imageDataChanged($event)">
.ts код -
imageDataChanged($event) {
var file = $event.target.files[0];
this.ds.selectedFile = file;
if (file.length===0) {
return;
}
var reader = new FileReader();
// get data from file input and emit as dataUrl
reader.addEventListener("load", () => {
var ctx = this.canvas.nativeElement.getContext('2d');
this.imageUrl = reader.result;
this.imagePicked.emit(this.imageUrl);
}, false);
if (file) {
reader.readAsDataURL(file);
}
const formData = new FormData();
formData.append(file.name, file);
this.ds.formDataPost = formData;
}
Здесь ds - не что иное, как промежуточный класс для инъекции данных.
@Injectable()
export class DataSharingService {
public selectedFile: any;
public formDataPost: any;
}
Теперь, мой код OnSubmit -
OnSubmit()
{
console.log(this.ds.formDataPost);
const uplRequest = new HttpRequest('POST', this.baseUrl + '/CaptureSaveImg', this.ds.formDataPost, { reportProgress: true });
this.http.request(uplRequest)
.subscribe((data: any) =>
{
if (data.Success == "true")
{
console.log("Upload successful.");
}
else
{
console.log("Problem while uploading file.");
}
})
}
Я просто получаю сообщение об ошибке - core. js: 6014 ОШИБКА TypeError: Вы указали 'undefined', где ожидался поток. Вы можете предоставить Observable, Promise, Array или Iterable.
Я думаю, что я близок. Любое преобразование необходимо? Или формат данных?