I have an Angular application, written in Typescript, with an ASP.Net Web Api backend. I am trying to use the ng-file-upload (see this link for details) directive to upload an image file.
I receive an exception in my Web API Post method:
"Unexpected end of MIME multipart stream. MIME multipart message is not complete."
I've done my research and found similar issues here - I have tried to implement Landuber Kassa's answer but without success.
Also this although my project is not MVC and in any case it did not work.
I am fresh out of ideas and would appreciate the community's thoughts. I am happy to consider any other alternatives if I can be pointed in the right direction.
Ash
My .Net Post method (implementing Landuber Kassa's idea):
[RoutePrefix("BeaufortAppStore/api/Image")]
public class ImageController : ApiController
{
#region Methods
#region Posts
[Route("UploadImage")]
[HttpPost]
public async Task<IHttpActionResult> UploadImage()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var provider = new MultipartMemoryStreamProvider();
Stream reqStream = Request.Content.ReadAsStreamAsync().Result;
MemoryStream tempStream = new MemoryStream();
reqStream.CopyTo(tempStream);
tempStream.Seek(0, SeekOrigin.End);
StreamWriter writer = new StreamWriter(tempStream);
writer.WriteLine();
writer.Flush();
tempStream.Position = 0;
StreamContent streamContent = new StreamContent(tempStream);
foreach (var header in Request.Content.Headers)
{
streamContent.Headers.Add(header.Key, header.Value);
}
// Read the form data and return an async task.
await streamContent.ReadAsMultipartAsync(provider); // FAILS AT THIS POINT
foreach (var file in provider.Contents)
{
var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
var buffer = await file.ReadAsByteArrayAsync();
//Do whatever you want with filename and its binary data.
}
return Ok();
}
#endregion
#endregion
My angular controller method:
public upload(): void {
//Create config used in ng-file-upload
var config: IFileUploadConfigFile = {
data: this.file, url: "BeaufortAppStore/api/Image/UploadImage/", method: "POST" };
this._dataService.uploadImage(config).then((result: any) => {
this.thumbnail = result.data;
});
}
My angular view (partial view for a directive):
<div class="form-group">
<label for="file" class="control-label col-xs-2">Choose a file</label>
<input id="file" type="file" name="file" class="form-control" ngf-select ngf-pattern="'image/*'"
ng-model="vm.file" />
<img style="width:100px;" ngf-thumbnail="thumbnail || '/thumb.jpg'" />
<button type="submit" ng-click="vm.upload()">Upload</button>
Try this in C#:
[HttpPost]
[Route("Profile/Image")]
public Task<HttpResponseMessage> UploadImgProfile()
{
try
{
if (!ModelState.IsValid) return null;
var currentUser = _userUtils.GetCurrentUser(User);
if (currentUser == null) return null;
HttpRequestMessage request = this.Request;
if (!request.Content.IsMimeMultipartContent())
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.UnsupportedMediaType));
string root = HttpContext.Current.Server.MapPath("~" + Constant.Application.User_Image_Directory);
bool exists = Directory.Exists(root);
if (!exists)
Directory.CreateDirectory(root);
var provider = new MultipartFormDataStreamProvider(root);
var task = request.Content.ReadAsMultipartAsync(provider).
ContinueWith<HttpResponseMessage>(o =>
{
var finfo = new FileInfo(provider.FileData.First().LocalFileName);
string guid = Guid.NewGuid().ToString();
var fileName = guid + "_" + currentUser.IdOwin + ".jpg";
File.Move(finfo.FullName, Path.Combine(root, fileName));
return new HttpResponseMessage()
{
Content = new StringContent(Path.Combine(Constant.Application.User_Image_Directory, fileName))
};
}
);
return task;
}
catch (Exception ex)
{
_logger.LogException(ex);
return null;
}
}
Angular Controller:
//Upload Func
$scope.upload = function (files) {
if (files && files.length) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
$scope.uploading = true;
// $scope.imageName = file.name;
$upload.upload({
url: enviroment.apiUrl + '/api/CurrentUser/Profile/Image',
//fields: { 'username': $scope.username },
file: file
}).progress(function (evt) {
$scope.uploading = true;
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
console.log('progress: ' + progressPercentage + '% ' + evt.config.file.name);
$scope.progress = progressPercentage;
}).success(function (data, status, headers, config) {
console.log('file ' + config.file.name + 'uploaded. Response: ' + data);
$scope.imageName = data;
$scope.uploading = false;
$scope.loadSuccess = true;
vm.uploadImage = false;
//AR
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function ($scope) {
$scope.myImage = evt.currentTarget.result;
});
};
reader.readAsDataURL(files[0]);
//END AR
});
}
}
};
// Stay on Listen upload file
$scope.$watch('files', function (evt) {
$scope.upload($scope.files);
});
HTML:
<div class="row">
<!--UPLOAD-->
<div class="up-buttons">
<div class="clearfix visible-xs-block"></div>
<div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center box-upload-image" data-ng-show="profileCtrl.uploadImage">
<br />
<div id="imgDragDrop" ng-file-drop ng-model="files"
drag-over-class="dragover"
accept="image/*">
<div class="cropArea-bkg">
<h4>
<span class="mdi mdi-account mdi-48px"></span>
<br /><br />
Carica immagine profilo
</h4>
<p>Trascina qui la tua immagine, oppure</p>
<div ng-file-select="" ng-model="files" class="btn btn-secondary" ng-accept="'*.pdf,*.jpg,*.png'" tabindex="0">
Sfoglia sul tuo computer
</div><br>
</div>
</div>
<div ng-no-file-drop class="well bg-danger">File Drag/Drop non è supportato da questo browser</div>
<br />
<div class="text-center">
<div class="progress" ng-show="uploading">
<div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="{{ ::progress }}" aria-valuemin="0" aria-valuemax="100" style="width: {{::progress}}% ">
<span class="sr-only">{{ ::progress }}% Complete</span>
</div>
</div>
</div>
</div>
<!--END UPLOAD-->
</div>
</div>
Related
So I'm trying to build an virtual file storage, im stuck at the part where I have to upload files and after that display them in a File-s view so that the user can download, delete or see them. The form input together with the file upload is in a modal box. To process the modal form I have used #Html.BeginForm and to process the file upload I have used ajax. What I have achieved until now is that I can upload the files to the server folder, but I dont konw how I can save the file name and the file path to the database of file-s table. And I also need help on how to display these files in a specific view. Thank you in advance.
Html
<div class="modal-body">
#using (Html.BeginForm("SaveRecord", "NgarkoDokument", FormMethod.Post, new { enctype = "mulptiple/form-data" }))
{
<div class="form-group">
<label for="exampleFormControlSelect1">Lloji i dokumentit</label><br />
<select title="Lloji i dokumentit" name="lloji" class="form-control col-md-3 box" id="tipiDropdown"> </select>
<input type="button" title="Ngarko dokument" name="ngarko" value="Ngarko" id="uploadPop" class="btn btn-info col-md-3" onclick="document.getElementById('file').click();" />
<input type="file" onchange="javascript: updateList()" multiple="multiple" style="display:none;" id="file" name="postedFiles"/>
<div id="fileList"></div>
</div>
<br /><br />
<div class="form-group">
<label for="formGroupExampleInput">Fusha indeksimi</label> <br />
#*<input title="Indeksimi dokumentit" id="indeksimi" class="form-control col-md-3" type="text" name="indeksimi" placeholder="indeksimi" required />*#
#Html.TextBoxFor(a => a.Fusha_Indeksimit.Emri_Indeksimit, new { #class = "form-control", #placeholder = "indeksimi" })
#* <button title="Shto indeksim" id="modalPlus" type="submit" class="btn btn-info"><i class="glyphicon glyphicon-plus"></i></button>*#
</div>
<label for="formGroupExampleInput">Vendndodhja fizike e dokumentit</label><br>
<div id="zyraModal" class="form-group col-md-4">
#*<input title="Zyra fizike" id="zyra" class="form-control" type="text" name="zyra" placeholder="Zyra" />*#
#Html.TextBoxFor(a => a.Vendndodhja_fizike.Zyra, new { #class = "form-control", #placeholder
= "Zyra" })
</div>
<div class="form-group col-md-4">
#* <input title="Kutia fizike" id="kutia" class="form-control" type="number" name="kutia" placeholder="Nr i kutisë" />*#
#Html.TextBoxFor(a => a.Vendndodhja_fizike.Nr_Kutise, new { #class = "form-control", #placeholder = "Nr i kutisë" })
</div>
<div class="form-group col-md-4">
#* <input title="Rafti fizik" id="rafti" class="form-control" type="text" name="rafti" placeholder="Rafti" />*#
#Html.TextBoxFor(a => a.Vendndodhja_fizike.Rafti, new { #class = "form-control", #placeholder = "Rafti" })
</div>
<br /><br />
<div class="row" id="ruaj">
<button title="Ruaj dokumentin" type="submit" class="btn btn-success">Ruaj</button>
</div>
}
</div>
Ajax script
<script type="text/javascript">
$(document).ready(function () {
$("#file").change(function () {
console.log("Image selected!");
var formData = new FormData();
var totalFiles = document.getElementById("file").files.length;
for (var i = 0; i < totalFiles; i++) {
var file = document.getElementById("file").files[i];
formData.append("file", file);
}
$.ajax({
type: "POST",
url: '/UploadFile/Upload',
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: function (response) {
alert('succes!!');
}
});
});
});
</script>
Controller
public ActionResult Dokument()
{
return View();
}
[HttpPost]
public void Upload()
{
Dokumenti dok = new Dokumenti();
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/File/"), fileName);
file.SaveAs(path);
}
}
public ActionResult SaveRecord(NgarkoDokument model)
{
try
{
Vendndodhja_Fizike vendndodhja = new Vendndodhja_Fizike();
vendndodhja.Zyra = model.Vendndodhja_fizike.Zyra;
vendndodhja.Rafti = model.Vendndodhja_fizike.Rafti;
vendndodhja.Nr_Kutise = model.Vendndodhja_fizike.Nr_Kutise;
db.Vendndodhja_Fizike.Add(vendndodhja);
Fusha_Indeksimit indeksimi = new Fusha_Indeksimit();
indeksimi.Emri_Indeksimit = model.Fusha_Indeksimit.Emri_Indeksimit;
db.Fusha_Indeksimit.Add(indeksimi);
Dokumenti dok = new Dokumenti();
dok.Emer = model.Dokumenti.Emer;
db.Dokumenti.Add(dok);
db.SaveChanges();
//int lastUserId = dok.UserID;
}
catch(Exception ex)
{
throw ex;
}
return RedirectToAction("Dokument");
}
}
First of all, you may need to specify this because you send FormData to your controller. For example:
public async Task CreateAsync([FromForm] CreateBookDto input)
{
...
}
I care about a lot of things while uploading the file so my js file is a bit long but you can get what works for you:
$(function () {
var fileInput = document.getElementById('Book_CoverImageFile');
var file;
fileInput.addEventListener('change', function () {
var showModal = true;
file = fileInput.files[0];
document.getElementById("choose-cover-image").innerHTML = file.name;
var permittedExtensions = ["jpg", "jpeg", "png"]
var fileExtension = $(this).val().split('.').pop();
if (permittedExtensions.indexOf(fileExtension) === -1) {
showModal = false;
alert('This extension is not allowed')
$('#Book_CoverImageFile').val('');
$("#choose-cover-image").html("Choose a cover image...");
}
else if(file.size > 5*1024*1024) {
showModal = false;
alert('The file is too large');
}
var img = new Image();
img.onload = function() {
var sizes = {
width:this.width,
height: this.height
};
URL.revokeObjectURL(this.src);
if (sizes.width > 1920 && sizes.height > 1080){
alert('Height and Width must not exceed 1920*1080.')
$('#Book_CoverImageFile').val('');
$("#choose-cover-image").html("Choose a cover image...");
}
var aspectRatio = sizes.width / sizes.height;
aspectRatio = Number (aspectRatio.toFixed(1));
if (aspectRatio !== 1.8){
alert("The picture you uploaded is not in 16:9 aspect ratio!")
$('#Book_CoverImageFile').val('');
$("#choose-cover-image").html("Choose a cover image...");
}
}
if(showModal === true) {
readURL(this);
$('#myModal').modal('show');
}
var objectURL = URL.createObjectURL(file);
img.src = objectURL;
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img-upload').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$('form#CreateBookForm').submit(function (e) {
e.preventDefault();
var title = $('#Book_Title').val().trim();
var formData = new FormData();
formData.append("Title", title);
formData.append("CoverImageFile", file);
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
if(percentComplete !== 100){
$( '#Book_CoverImageFile' ).prop( "disabled", true );
$( '#Book_Title' ).prop( "disabled", true );
$( '#btnSubmit' ).prop( "disabled", true );
}
}
}, false);
return xhr;
},
url: app.appPath + `api/app/Book`,
data: formData,
type: 'POST',
contentType: false,
processData: false,
success: function(data){
alert("The Book has been successfully submitted. It will be published after a review from the site admin.");
window.location.href = "/books";
},
error: function (data) {
alert(data.responseJSON.error.message);
}
});
});
This does many things, for example; file permitted extension control, control of file size, checking whether the file is more than 1920 * 1080 pixels, whether the file has 16:9 aspect ratio, disabling form elements while sending the file, etc...
And if you really care about security, you should;
To only accept permitted extensions:
public class AllowedExtensionsAttribute : ValidationAttribute
{
private readonly string[] _extensions;
public AllowedExtensionsAttribute(string[] extensions)
{
_extensions = extensions;
}
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
if (value == null) // If uploading a file is optional on the form screen, it should be added == CanBeNul
{
return ValidationResult.Success;
}
var file = value as IFormFile;
var extension = Path.GetExtension(file.FileName);
if (file.Length > 0 && file != null)
{
if (!_extensions.Contains(extension.ToLower()))
{
return new ValidationResult(GetErrorMessage());
}
}
return ValidationResult.Success;
}
public string GetErrorMessage()
{
return $"This extension is not allowed!";
}
}
To limit the uploaded file size:
public class MaxFileSizeAttribute : ValidationAttribute
{
private readonly int _maxFileSize;
public MaxFileSizeAttribute(int maxFileSize)
{
_maxFileSize = maxFileSize;
}
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
if (value == null) // If uploading a file is optional on the form screen, it should be added == CanBeNull
{
return ValidationResult.Success;
}
var file = value as IFormFile;
if (file.Length > 0)
{
if (file.Length > _maxFileSize)
{
return new ValidationResult(GetErrorMessage());
}
}
return ValidationResult.Success;
}
public string GetErrorMessage()
{
return $"Maximum allowed file size is { _maxFileSize} bytes.";
}
}
And you must add them to Dto:
public class CreateBookDto
{
[Required]
[StringLength(64)]
public string Title { get; set; }
[CanBeNull]
[DataType(DataType.Upload)]
[MaxFileSize(5*1024*1024)] // 5mb
[AllowedExtensions(new string[] { ".jpg", ".png", ".jpeg" })]
public IFormFile CoverImageFile { get; set; }
}
Finally, your HTML file should look like this:
<form method="post" id="CreateBookForm" asp-page="/Book/Create" enctype="multipart/form-data">
<div class="form-group">
<div class="custom-file">
<input asp-for="Book.CoverImageFile" type="file" name="file" class="custom-file-input" id="Book_CoverImageFile"
required="required">
<label id="choose-cover-image" class="custom-file-label" for="customFile">Choose a cover image...</label>
<small class="form-text text-muted">#L["CreateBookCoverInfo"].Value</small>
</div>
</div>
...
<button id="btnSubmit" type="submit" class="btn btn-primary btn-block">Submit</button>
</form>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<img class="img-fluid" id="img-upload" alt=""/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-block" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
I have setup a Blazor WebAssembly ASP.Net Core hosted PWA project and am using Azure Cognitive Services in it. Therefore I have in one of my client-views a form where the user can upload an image and this will be referred to Azure.
In the razor-view I have this:
#inject HttpClient client;
#inject IFileReaderService FileReader;
#inject NavigationManager navi;
<div class="text-center">
<input class="btn btn-secondary " name="file" #ref="InpReference" type="file" id="file-selector" placeholder="Brows" accept="image/*" capture="camera" #onclick="InputFile">
#if (_fileSelected != false)
{
<input class="btn btn-primary" type="button" role="button" id="startbutton" #onclick="Upload" value="upload" />
}
</div>
#code {
private async Task Upload()
{
// content base structure
MultipartFormDataContent content = new MultipartFormDataContent();
content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data");
foreach (/*IFileReference*/var fileReference in fileReferences)
{
Console.WriteLine("test1");
// getting the file size
IFileInfo fileinfo = await fileReference.ReadFileInfoAsync();
Stream fileStream;
var fileReferencesArray = fileReferences.ToArray();
using (var fs = await fileReference.CreateMemoryStreamAsync((int)fileinfo.Size))
{
Console.WriteLine("test2");
fileStream=new MemoryStream(fs.ToArray());
}
Console.WriteLine("test4" + fileinfo.Size);
StreamContent sc = new StreamContent(fileStream, (int)fileStream.Length);
content.Add(sc, "file", fileinfo.Name);
Console.WriteLine("test5");
}
Console.WriteLine("test6");
var response = await client.PostJsonAsync<List<Prediction>>("api/Azure/Prediction", content);
Console.WriteLine(response.Count + " : " + response.GetType().ToString());
foreach (var prediction in response)
{
Console.WriteLine(prediction.Id + ":" + prediction.Name + "," + prediction.Probability.ToString());
}
navi.NavigateTo("detailView/");
}
}
My WebApi Controller for the handling:
...
[HttpPost]
public List<Prediction> getPrediction([FromForm]IFormFile file)
{
if (file == null)
{
return new List<Prediction>();
}
List<Prediction> predicitions = azure_Client.GetPrediction(file.OpenReadStream());
return predicitions;
}
...
The problem is that the [FromForm]IFormFile file in the controller is always null. This is only null in the PWA project. I have set the same project up without PWA and it works, it is not null and it is getting the selected image from the view! What is the difference there and why isn't the HttpClient doing the same as in the Blazor WebAssembly ASP.Net Core hosted?
According to my test, if you want to upload file in Blazor WebAssembly ASP.Net Core hosted PWA, please refer to the following steps
Client(I use the sdk Tewr.Blazor.FileReader)
a. update Program.cs
builder.Services.AddFileReaderService(options => {
options.UseWasmSharedBuffer = true;
});
builder.Services.AddTransient(sp =>
new HttpClient
{
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});
b. upload file razor-view
#using System.IO
#using Blazor.FileReader
#inject HttpClient client;
#inject IFileReaderService fileReader
<h1>File uplaod Blzaor WebAssembly!</h1>
<div class="row">
<div class="col-4">
<div class="form-group">
<input type="file" name="image" #ref="inputReference" #onchange="async() =>await OpenFile()" />
<ul>
<li>File Name: #fileName</li>
<li>Size: #size</li>
<li>Type: #type</li>
</ul>
</div>
<button class="btn btn-block btn-success" #onclick="async() =>await UploadFile()"> Upload File</button>
#if (!string.IsNullOrWhiteSpace(message))
{
<div class="alert alert-success">
File has been uplaoded
</div>
}
</div>
</div>
#code{
ElementReference inputReference;
string message = string.Empty;
string fileName = string.Empty;
string type = string.Empty;
string size = string.Empty;
Stream fileStream=null;
async Task UploadFile()
{
var content = new MultipartFormDataContent();
content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data");
var sc = new StreamContent(fileStream, (int)fileStream.Length);
content.Add(sc, "image", fileName);
var response = await client.PostAsync("/upload", content);
if (response.IsSuccessStatusCode) {
message = "OK";
}
}
async Task OpenFile()
{
var file = (await fileReader.CreateReference(inputReference).EnumerateFilesAsync()).FirstOrDefault();
if (file == null) {
return;
}
var fileInfo=await file.ReadFileInfoAsync();
fileName = fileInfo.Name;
type = fileInfo.Type;
size = $"{fileInfo.Size} Bytes";
using (var ms = await file.CreateMemoryStreamAsync((int)fileInfo.Size)) {
fileStream = new MemoryStream(ms.ToArray());
}
}
}
Server
API COntroller
[HttpPost]
public async Task<IActionResult> Post([FromForm(Name ="image")]IFormFile file) {
if (file == null || file.Length == 0) {
return BadRequest("do not receive file");
}
var fileName = file.FileName;
var extension = Path.GetExtension(fileName);
var newFileName = $"{Guid.NewGuid()}{extension}";
var filePath = Path.Combine(_env.ContentRootPath, "Images", newFileName);
if (!Directory.Exists(Path.Combine(_env.ContentRootPath, "Images"))) {
Directory.CreateDirectory(Path.Combine(_env.ContentRootPath, "Images"));
}
using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) {
await file.CopyToAsync(stream);
}
return Ok(filePath);
}
Result
I'm developing a system in .NET and I need to send a json controller msg to the view and show it in modal.
The user will import a spreadsheet and the spreadsheet will be inserted in the database, at the end of the modal it should appear with the message whether it was sent or not.
Or backend is already working.
I need help on the front because when I import, it loads a new page with
["Sent with success"]
(the messages are in portuguese) = ["Enviado com sucesso"]
Follows the controller code.
public JsonResult UploadExcel(HttpPostedFileBase FileUpload)
{
List<string> data = new List<string>();
if (FileUpload != null)
{
// tdata.ExecuteCommand("truncate table OtherCompanyAssets");
if (FileUpload.ContentType == "application/vnd.ms-excel" || FileUpload.ContentType == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
string filename = FileUpload.FileName;
string targetpath = "C:/Users/70561/Documents";
FileUpload.SaveAs(targetpath + filename);
string pathToExcelFile = targetpath + filename;
var connectionString = "";
if (filename.EndsWith(".xls"))
{
connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", pathToExcelFile);
}
else if (filename.EndsWith(".xlsx"))
{
connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";", pathToExcelFile);
}
var adapter = new OleDbDataAdapter("SELECT * FROM [Planilha1$]", connectionString);
var ds = new DataSet();
adapter.Fill(ds, "ExcelTable");
DataTable dtable = ds.Tables["ExcelTable"];
string sheetName = "Planilha1";
var excelFile = new ExcelQueryFactory(pathToExcelFile);
var dados = from a in excelFile.Worksheet<RETORNO_CM>(sheetName) select a;
foreach (var a in dados)
{
try
{
if (a.CM_CODIGO != null && a.CM_QM_COMPONENTE_RMA != null && a.CM_NS != null && a.CM_DESCRICAO != null &&
a.CM_DEFEITO != null && a.J_FALHA != null &&
a.CM_TIPO_DEFEITO != null && a.J_PLACA_RETRABALHO != null &&
a.J_PLACA_RESTESTADA != null && a.J_STATUS != null && a.CM_NOME_TESTE != null && a.CM_NOME_DEBUG != null)
{
RETORNO_CM CM = new RETORNO_CM();
CM.CM_CODIGO = a.CM_CODIGO;
CM.CM_QM_COMPONENTE_RMA = a.CM_QM_COMPONENTE_RMA;
CM.CM_NS = a.CM_NS;
CM.CM_DESCRICAO = a.CM_DESCRICAO;
CM.CM_DATA_REPARO = a.CM_DATA_REPARO;
CM.CM_DEFEITO = a.CM_DEFEITO;
CM.J_FALHA = a.J_FALHA;
CM.CM_TIPO_DEFEITO = a.CM_TIPO_DEFEITO;
CM.CM_COMPONENTE = a.CM_COMPONENTE;
CM.J_PLACA_RETRABALHO = a.J_PLACA_RETRABALHO;
CM.J_PLACA_RESTESTADA = a.J_PLACA_RESTESTADA;
CM.J_STATUS = a.J_STATUS;
CM.CM_NOME_TESTE = a.CM_NOME_TESTE;
CM.CM_NOME_DEBUG = a.CM_NOME_DEBUG;
db.RETORNO_CM.Add(CM);
db.SaveChanges();
}
else
{
data.Add("<ul>");
data.Add("</ul>");
data.ToArray();
return Json(data, JsonRequestBehavior.AllowGet);
}
}
catch (DbEntityValidationException ex)
{
foreach (var entityValidationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in entityValidationErrors.ValidationErrors)
{
Response.Write("Property: " + validationError.PropertyName + " Error: " + validationError.ErrorMessage);
}
}
}
}
//deleting excel file from folder
if ((System.IO.File.Exists(pathToExcelFile)))
{
System.IO.File.Delete(pathToExcelFile);
}
data.Add("Enviado com sucesso");
return Json(data, JsonRequestBehavior.AllowGet);
}
else
{
//alert message for invalid file format
data.Add("Apenas arquivos excel sao suportados");
return Json(data, JsonRequestBehavior.AllowGet);
}
}
else
{
if (FileUpload == null) data.Add("Selecione um arquivo");
return Json(data, JsonRequestBehavior.AllowGet);
}
}
my view code
<div class="box">
<div class="box-body">
<hr />
<article class="table-responsive" style="overflow:hidden">
<p class="lead">Teste de importação.</p>
<hr />
#using (Html.BeginForm("UploadExcel", "RetornoCM", FormMethod.Post, new { enctype = "multipart/form-data", onsubmit = "return myFunction()" }))
{
<div class="form-horizontal">
<div class="form-group">
<div class="control-label col-md-2">Escolha o Arquivo:</div>
<div class="col-md-10">
<input type="file" id="FileUpload" name="FileUpload" class="" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Enviar" id="btnSubmit" class="btn btn-primary" />
</div>
</div>
</div>
}
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
<p>
<b>Message:</b><br>
<input class="message-edit-text" type="text" size="20">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</article>
</div>
You should not return JSON, as you are performing a full page postback. Instead, you should return a View.
If you do not want to perform a full page postback, you want to use Ajax since the beginning of the request.
For example,
View
Please make sure button is type="button" to avoid full page postback.
#using (Html.BeginForm("UploadExcel", "RetornoCM", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-horizontal">
<div class="form-group">
<div class="control-label col-md-2">Escolha o Arquivo:</div>
<div class="col-md-10">
<input type="file" id="FileUpload" name="FileUpload" class="" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="button" id="btnSubmit" class="btn btn-primary">
Enviar
</button>
</div>
</div>
</div>
}
<script>
$(function () {
$('#btnSubmit').click(function() {
// Checking whether FormData is available in browser
if (window.FormData !== undefined) {
var fileUpload = $("#FileUpload").get(0);
var files = fileUpload.files;
// Create FormData object
var fileData = new FormData();
// Looping over all files and add it to FormData object
for (var i = 0; i < files.length; i++) {
fileData.append(files[i].name, files[i]);
}
$.ajax({
url: '#Url.Action("UploadExcel", "RetornoCM")',
type: "POST",
contentType: false, // Not to set any content header
processData: false, // Not to process data
data: fileData,
success: function(result) {
alert(result);
},
error: function(err) {
alert(err.statusText);
}
});
}
});
});
</script>
Action Method
[HttpPost]
public ActionResult UploadExcel()
{
if (Request.Files.Count > 0)
{
try
{
HttpFileCollectionBase files = Request.Files;
for (int i = 0; i < files.Count; i++)
{
HttpPostedFileBase file = files[i];
// Do somethig with file
}
return Json("File Uploaded Successfully!");
}
catch (Exception ex)
{
return Json("Error occurred. Error details: " + ex.Message);
}
}
else
{
return Json("No files selected.");
}
}
Source: File Upload Through JQuery AJAX In ASP.NET MVC
I am attempting to upload a file. The code below works on my local machine or running on a remote server running the dll from a command line, but when I try and publish to my test environment and run under iis it fails.
<form method="post" asp-action="Upload" asp-controller="Prebook" enctype="multipart/form-data">
<div class="form-inline">
<div class="col-md-2">
<div class="form-group">
<input type="file" name="files" data-input= "false" multiple class="filestyle" data-buttonName="btn-primary">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input type="submit" value="Upload File" class="btn btn-primary" />
</div>
</div>
</div>
</form>
Controller logic
[HttpPost]
public async Task<IActionResult> Upload(ICollection<IFormFile> files)
{
if (await _contextPB.UploadRow.AnyAsync())
{
Danger(string.Format("Please LOAD the existing containers before uploading another file"), true);
return View();
}
int rowCount = 0;
var uploads = Path.Combine(_environment.WebRootPath, "uploads");
var _viewModel = new UploadViewModel();
foreach (var file in files)
{
using (var streamReader = System.IO.File.OpenText(Path.Combine(uploads, file.FileName)))
{
var line = streamReader.ReadLine();
var columnNames = line.Split(new[] { ',' });
if (!ValidateColumnNames(columnNames))
{
Danger(string.Format("Invalid Column Name in Upload file"), true);
return View(_viewModel);
}
while (!streamReader.EndOfStream)
{
var data = line.Split(new[] { ',' });
var uploadRow = new UploadRow();
// validation & assignment logic removed
try
{
_contextPB.Add(uploadRow);
rowCount++;
}
catch (Exception e)
{
Danger(string.Format("<b>{0},{1}</b> database error", uploadRow.Container_Id, e), true);
}
line = streamReader.ReadLine();
}
}
}
}
Try adding a catch block to see what the error is.
I'm assuming a permission issue.
[HttpPost]
public async Task<IActionResult> Upload(ICollection<IFormFile> files)
{
try
{
if (await _contextPB.UploadRow.AnyAsync())
{
Danger(string.Format("Please LOAD the existing containers before uploading another file"), true);
return View();
}
// your code
}
catch (Exception ex)
{
// what is the error?
// add a breakpoint to see
throw;
}
}
Here is my html part I want to choose and post a file to method in the server.
<div class="control-group">
<input type="hidden" name="id" data-bind="value: id" />
<div class="controls">
<div class="fileupload fileupload-new" data-provides="fileupload">
<div class="fileupload-new thumbnail" style="width: 200px; height: 150px;">
<embed height="50" width="100" data-bind="attr: { src: mediaUrl() }" />
</div>
<div class="fileupload-preview fileupload-exists thumbnail" style="max-width: 200px; max-height: 150px; line-height: 20px;">
</div>
<div>
<span class="btn btn-file"><span class="fileupload-new">Choose a Audio/Voice</span> <span class="fileupload-exists">Change</span>
<input type="file" name="photoFile" class="default" />
</span><a data-bind="click: addMediaFile" href="#" class="btn fileupload-exists"
data-dismiss="fileupload">Save</a>
</div>
</div>
</div>
</div>
And here is addMediaFile javascript function in my ViewModel file
self.addMediaFile = function () {
utils.UIBlock();
$("#mediaForm").ajaxSubmit({
url: "api/Work/EditLibraryItemForMedia",
type: "POST",
success: function (result) {
self.mediaFilePath(result);
utils.UIUnBlock();
utils.showSuccess("Dosya kaydedilmiştir");
},
error: function () {
utils.UIUnBlock();
}
});
}
And finally here is my EditLibraryItemForMedia method in the server.
private Task<List<string>> UploadMediaFile()
{
string folderPath = ConfigurationManager.AppSettings["mediaFilesFolder"].ToString();
MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider(folderPath);
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
return Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(r => { return new List<string>(); });
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
}
string resizedImagesFolderPath = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/Images/UploadedMedias/"));
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
return Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(
readTask =>
{
MultipartFormDataStreamProvider provider = readTask.Result;
return provider.FileData.Select(fileData =>
{
string itemId = provider.FormData["id"];
FileInfo fileInfo = new FileInfo(itemId);
string mimeType = GetMimeType(fileData.Headers.ContentDisposition.FileName);
string extension = "";
if (mimeType == "audio/mpeg3" || mimeType == "audio/x-mpeg-3" || mimeType == "video/mpeg" || mimeType == "video/x-mpeg")
{
extension = ".mp3";
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
}
// Add extensions to files
string fileName = itemId + extension;
string filePath = Path.Combine(folderPath, fileName);
if (File.Exists(filePath))
{
File.Delete(filePath);
}
File.Move(fileData.LocalFileName, filePath);
WorkService.UpdateMediaFile(itemId, Path.GetFileName(filePath));
return fileName;
}).ToList();
});
}
Actually problem is that I can't upload an audio and video using this procedure.