Image displaying error from database - asp.net-mvc

After the recent changes in my application still i get this issue while displaying the image using the relative path in the database. Error: 404 NOT FOUND http://localhost:1256/Empdet/%22/Photos/jobs.jpg%22
Controller.js:
$scope.UploadFile = function () {
console.log('UploadFile');
console.log($scope.Empdet.PhotoFile);
var file = $scope.Empdet.PhotoFile;
console.log('file is ' + JSON.stringify(file));
var uploadUrl = "../Photos";
console.log('before file upload');
EmployeeFactory.UploadFile(file, uploadUrl).success(function (response) {
$scope.Empdet.PhotoText = response;
console.log('$scope.Empdet.PhotoText');
console.log(response);
}).error(function () {
console.log('error');
});
console.log('after file upload');
};
service.js:
service.UploadFile = function (file, uploadUrl) {
var fd = new FormData();
fd.append('file', file);
return $http.post('/Empdet/UploadFile', fd, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
});
}
EmpdetController.cs:
[HttpPost]
public ActionResult UploadFile()
{
var file = Request.Files[0];
var path = Path.Combine(Server.MapPath("~/Photos/"), file.FileName);
file.SaveAs(path);
// prepare a relative path to be stored in the database and used to display later on.
var filename = Url.Content("~/Photos/" + file.FileName);
// save to db
return Json(filename.ToString(), JsonRequestBehavior.AllowGet);
}

Remove the .toString() from your function, the FileName property already returns a string.
[HttpPost]
public ActionResult UploadFile()
{
var file = Request.Files[0];
var path = Path.Combine(Server.MapPath("~/Photos/") + file.FileName);
file.SaveAs(path);
// prepare a relative path to be stored in the database and used to display later on.
string filename = Url.Content("~/Photos/" + file.FileName);
// save to db
return Json(filename, JsonRequestBehavior.AllowGet);
}
Parse the return in your controller. This should get rid of the extra quotes(") in your URL.

controller.js:
$scope.UploadFile = function () {
console.log('UploadFile');
console.log($scope.Empdet.PhotoFile);
var file = $scope.Empdet.PhotoFile;
console.log('file is ' + JSON.stringify(file));
var uploadUrl = '/Empdet/UploadFile';
console.log('before file upload');
EmployeeFactory.UploadFile(file, uploadUrl).success(function (response) {
console.log(JSON.parse(response));
console.log('$scope.Empdet.PhotoText');
$scope.Empdet.PhotoText = JSON.parse(response);
}).error(function () {
console.log('error');
});
console.log('after file upload');
};
EmpdetController.cs:
[HttpPost]
public ActionResult UploadFile()
{
var file = Request.Files[0];
var path = Path.Combine(Server.MapPath("~/Photos/") + file.FileName);
file.SaveAs(path);
// prepare a relative path to be stored in the database and used to display later on.
string filename = Url.Content("~/Photos/" + file.FileName);
// save to db
return Json(filename, JsonRequestBehavior.AllowGet);
}

Related

Summernote image upload with .NET Core

Im really struggling to get SummerNote to upload an iamge in .NET core. The trouble is the IFormFile file parameter is null when a new image is uploaded.
I initialise Summernote using the following -
$('#MessageBody').summernote({
height: ($(window).height() - 300),
callbacks: {
onImageUpload: function(image) {
uploadImage(image[0]);
}
}
});
Here is the uploadImage function -
function uploadImage(image) {
var data = new FormData();
data.append("image", image);
$.ajax({
url: '/EmailTemplate/UploadImage',
cache: false,
contentType: false,
processData: false,
data: data,
type: "post",
success: function(url) {
var image = $('<img>').attr('src', 'http://' + url);
$('#MessageBody').summernote("insertNode", image[0]);
alert(url);
var imgNode = document.createElement('img');
imgNode.src = url;
$('#MessageBody').summernote('insertNode', imgNode);
},
error: function(data) {
console.log(data);
}
});
And finally, here is the controller -
[HttpPost]
public async Task<IActionResult> UploadImage(IFormFile file)
{
string message;
var saveimg = Path.Combine(_hostingEnvironment.WebRootPath, "Images", file.FileName);
string imgext = Path.GetExtension(file.FileName);
if (imgext == ".jpg" || imgext == ".png")
{
using (var uploadimg = new FileStream(saveimg, FileMode.Create))
{
await file.CopyToAsync(uploadimg);
message = "The selected file" + file.FileName + " is saved";
}
}
else
{
message = "only JPG and PNG extensions are supported";
}
// return "filename : " + saveimg + " message :" + message;
return Content(Url.Content(saveimg));
}
The parameter is called file while the field name is image. To fix this use the same name, either file or image.
The IFormFile type represents the value of an input type=file field. IFormFile parameters are bound to fields based on their name. There may be many file fields in the same form so the type isn't enough to determine the field.
Field binding is explained in the Sources section of the Model Binding document.

Free text editor with image gallery

Hi i want a free text editor with image or file gallery and i want to insert image or file in the middle of the text.
Please give me your suggestions.
ckeditor(text)+ckfinder(image)
Or
you can use Summernote with server side image upload setup
$('#Editor').summernote({
lang: 'fa-IR',
callbacks: {
onImageUpload: function (files) {
var $editor = $(this);
var data = new FormData();
data.append('imageFile', files[0]);
$.ajax({
url: '/Server/UploadImage',
method: 'POST',
data: data,
processData: false,
contentType: false,
success: function (url) {
$editor.summernote('insertImage', url);
}
});
}
}
});
and MVC5 server side sample action code:
public string UploadImage()
{
HttpPostedFileBase file = null;
string RenameFile = "";
for (int i = 0; i < Request.Files.Count; i++)
{
file = Request.Files[i];
string fileExt = System.IO.Path.GetExtension(file.FileName);
Guid randomFileName = Guid.NewGuid();
RenameFile = randomFileName + fileExt;
var path = Path.Combine(Server.MapPath("~/Content/Uploads/"), RenameFile);
file.SaveAs(path);
}
return #"/Content/Uploads/" + RenameFile;
}

Angular 5 File upload in chunks to ASP NET returns with Unexpected end of MIME multipart stream. MIME multipart message is not complete

So, I am trying to upload big files in chunks using Angular 5 and the fileapi
This is how my request looks like:
const formData: FormData = new FormData();
formData.append('fileKey', this.fileToUpload, this.fileToUpload.name);
FileAPI.upload({
url: 'http://localhost:22166/api/lbx/upload',
headers: { 'authorization' : `Bearer ${this._svc.getToken()}`,
// 'Content-Disposition': `attachment; filename=${this.fileToUpload.name}; name=zip},
files: {
file: formData
},
// formData: true,
// chunkSize: 1.0 * FileAPI.MB,
progress: function (evt){
console.log((evt.loaded / evt.total) * 100);
},
complete: function (err, xhr){
if (err) {
const message = JSON.parse(xhr.responseText).ExceptionMessage;
parent.saving = false;
parent.snack(message);
} else {
console.log('completed');
}
}
});
This is what my Post looks like:
[HttpPost]
[Route("lbx/upload")]
[EnableCors(origins: "*", headers: "*", methods: "*", SupportsCredentials = true)]
public async Task<IHttpActionResult> UploadLBXProject()
{
try
{
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
const string errorMsg = "Request content is not MIME multipart content and is unsupported.";
AppEventLog.Error(string.Format(errorMsg));
return StatusCode(HttpStatusCode.UnsupportedMediaType);
}
var root = HttpContext.Current.Server.MapPath("~/App_Data");
var result = await Request.Content.ReadAsMultipartAsync(new MultipartFormDataStreamProvider(root)); //here it fails
var uploadedFile = result.FileData.First();
var originalFileName = JsonConvert.DeserializeObject(uploadedFile.Headers.ContentDisposition.FileName).ToString();
var uploadedFileInfo = new FileInfo(uploadedFile.LocalFileName);
var part = ".part_1";
//Get the orignal file name that was on the client side for "BodyPart_"
var newZipFileName = uploadedFileInfo.FullName.Replace(uploadedFileInfo.Name, originalFileName + part);
var regex = new Regex("\\d+");
//If a zip file with the original name already exists, rename it
while (File.Exists(newZipFileName))
{
var s = newZipFileName.Split('.');
var np = ".part_" + (int.Parse(regex.Match(s[s.Length - 1]).Value) + 1);
newZipFileName = newZipFileName.Replace(part, np);
part = np;
}
var extractedFolderName = newZipFileName.Replace(".zip", "");
if (Directory.Exists(extractedFolderName))
{
Directory.Delete(extractedFolderName, true);
}
File.Move(uploadedFileInfo.FullName, newZipFileName);
AppEventLog.Info("upload of zip file finished");
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content.Headers.Add("Access-Control-Expose-Headers", "X-Last-Known-Byte");
return ResponseMessage(response);
}
catch (Exception e)
{
//Delete the partially uploaded file if exception occured or if the user aborted
var uploadedFilesPath = HttpContext.Current.Server.MapPath("~/App_Data/");
foreach (var fileInfo in new DirectoryInfo(uploadedFilesPath)
.GetFiles())
{
File.Delete(fileInfo.FullName);
}
return InternalServerError(e);
}
}
This works fine without using the fileapi, but using this clientside code.
uploadLBX(file: File): Observable<any> {
const formData: FormData = new FormData();
formData.append('fileKey', file, file.name);
const query = this._config.WEB_API_BASE_URL + this._config._api_urls.post.lbx.uploadzip;
const headers = this.getHeaders();
return this._http.post(query, formData, { headers: headers })
.do(data => console.log(`file uploaded successfully`))
.catch(this.handleError);
}
However, it does not work with big files, since my web.config already has the maximum value for requests:
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" maxRequestLength="2147483647" />
</system.web>
The exception:
Unexpected end of MIME multipart stream. MIME multipart message is not
complete.
What can I do?
Thanks
EDIT
Added network request

Forms authentication cookie is not persisting or is not getting past through an ajax request?

I am at a loss as to why my authentication cookie disappears. I am using Valums Ajax Upload in conjunction with a couple other ajax requests to build a user's avatar. It is very random as to when the cookie disappears. I can upload 4 files without an issue, then 2 files maybe (after another login). It seems after I call the CreateAvatar method, that is where there might be an issue, but like I said, it doesn't happen all the time. What am I missing?
JavaScript:
$(function () {
//This is the Upload Method
var fileCount = 0;
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
action: '/Admin/Avatar/AvatarUpload',
debug: true,
params: {
'userId': '#ViewBag.UserId'
},
onSubmit: function (id, fileName) {
fileCount++;
},
onComplete: function (id, fileName, responseJson) {
if (responseJson.success) {
//fileCount--;
if (createAvatar(responseJson.file, responseJson.imageId)) {
fileCount--;
} else {
fileCount--;
//alert('There was an error when trying to save ' + fileName);
}
} else {
$("span.qq-upload-file:contains(" + fileName + ")").text(responseJson.errorMessage);
fileCount--;
}
if (fileCount == 0) {
}
},
onCancel: function (id, fileName) {
fileCount--;
if (fileCount == 0) {
parent.$.fn.colorbox.close();
}
}
});
});
//This Creates the Avatar Object
function createAvatar(fileName, imageId) {
var avatarUploadModel = {
UploadFileName: fileName,
UserId: '#ViewBag.UserId',
ImageId: imageId
};
$.ajax({
url: '/Admin/Avatar/CreateAvatar/',
type: 'POST',
cache: false,
timeout: 100000,
data: JSON.stringify(avatarUploadModel),
contentType: 'application/json; charset=utf-8',
dataType: "json",
error: function (xhr, status, error) {
alert(error + " " + status);
},
success: function (data) {
if (data.success) {
loadAvatar(data.avatarModel);
return true;
} else {
return false;
}
}
});
}
//This loads the partial to view the avatar after upload
function loadAvatar(avatarModel) {
$.ajax({
url: '/Admin/Avatar/AvatarEdit',
type: 'GET',
cache: false,
timeout: 100000,
data: avatarModel,
dataType: "html",
error: function (xhr, status, error) {
alert(error + " " + status);
},
success: function (data) {
$("#avatarOriginal").html(data);
}
});
}
Login Method:
var user = _userService.GetByUserName(model.Username);
var authTicket = new
FormsAuthenticationTicket(1, //version
user.Id.ToString(), // user name
DateTime.Now,
DateTime.Now.AddMinutes(40), //Expiration
model.RememberMe, //Persistent,
user.Username);
var encTicket = FormsAuthentication.Encrypt(authTicket);
HttpContext.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
return Json(new {success = true, url = model.ReturnUrl}, JsonRequestBehavior.AllowGet);
Upload Method on Controller:
[HttpPost]
public ActionResult AvatarUpload(HttpPostedFileBase fileData)
{
var id = Guid.NewGuid();
string fileName;
var serverPath = Server.MapPath("~/Areas/Admin/TemporaryUploads/");
if (fileData != null)
{
var fileRenamed = System.IO.Path.GetFileName(id + "_" + fileData.FileName);
fileName = Server.MapPath("~/Areas/Admin/TemporaryUploads/" + fileRenamed);
fileData.SaveAs(fileName);
}
else
{
var ajaxUploadFileData = Request["qqfile"];
fileName = Path.Combine(serverPath, id + "_" + Path.GetFileName(ajaxUploadFileData));
using (var output = System.IO.File.Create(fileName))
{
Request.InputStream.CopyTo(output);
}
}
return Json(new {success = true, file = fileName, imageId = id}, JsonRequestBehavior.AllowGet);
}
Create Avatar Method:
[HttpPost]
public ActionResult CreateAvatar(AvatarModel avatarModel)
{
try
{
var image = new WebImage(avatarModel.UploadFileName).Resize(400, 400, true);
var imageFileName = Path.GetFileName(avatarModel.UploadFileName);
var avatar = new Domain.YogaDiVitaContext.Model.Avatar()
{
CreatedById = Guid.Parse(HttpContext.User.Identity.Name),
ModifiedById = Guid.Parse(HttpContext.User.Identity.Name),
UserId = avatarModel.UserId,
Image = new Image()
{
CreatedById = Guid.Parse(HttpContext.User.Identity.Name),
ModifiedById = Guid.Parse(HttpContext.User.Identity.Name),
OriginalImageRelativePath = "original/" + imageFileName
}
};
var user = UserService.FindById(avatarModel.UserId);
if (user.Avatar != null)
RemoveAvatar(user.Avatar);
avatar = _avatarService.Create(avatar);
user.Avatar = avatar;
UserService.Update(user);
var basePath = Server.MapPath("~/" + avatar.ToAvatarBasePath(GlobalVariables.AvatarPath));
Directory.CreateDirectory(basePath);
Directory.CreateDirectory(basePath + "/thumbnail");
Directory.CreateDirectory(basePath + "/fullsize");
Directory.CreateDirectory(basePath + "/original");
image.Save(Server.MapPath("~/" + avatar.ToAvatarOriginalPath(GlobalVariables.AvatarPath)));
avatarModel.Width = image.Width;
avatarModel.Height = image.Height;
avatarModel.Top = image.Height*0.1;
avatarModel.Left = image.Width*0.9;
avatarModel.Right = image.Width*0.9;
avatarModel.Bottom = image.Height*0.9;
avatarModel.OriginalImagePath = "/" + avatar.ToAvatarOriginalPath(GlobalVariables.AvatarPath);
System.IO.File.Delete(avatarModel.UploadFileName);
return Json(new {success = true, avatarModel}, JsonRequestBehavior.AllowGet);
}
catch (Exception exception)
{
return Json(new {message = exception.Message}, JsonRequestBehavior.AllowGet);
}
}
Load Avatar Partial:
public ActionResult AvatarEdit(AvatarModel avatarModel)
{
return PartialView("AvatarCropPartial", avatarModel);
}

Downloading File in ASP mvc .net

I Put The Download Link in jqgrid, my Files are Stored on server not in database, files are of different types(extension)
i want user should download file when he clicks on download link
Code For Loading jqgrid is as Follws
public object GetJSONFormatProjectDetails(List<ProjectMasterDTO> listProjectDTO, int SkipCount)
{
var data = (listProjectDTO.Select(c => new
{
id = c.ProjectID,
cell = new[]
{
c.ProjectName,
c.OfficeName,
c.ProjectType,
c.ProjectNature,
c.EntrepreneurName,
c.Year + " Years " +c.Month + " Months " + c.Day + " Days" ,
c.ConcessionWEFdate,
c.ProjectStartDate,
c.ProjectEndDate,
c.isRoadApplicable,
(c.FilePath != "NA" ) ? "<a href='#' style='color:green' onclick='DownLoadFile(\""+URLEncrypt.EncryptParameters(new string[]{ "filepath =" +c.FilePath.Replace("/","$").Replace(" ","#").Trim()})+"\");return false;'>"+(c.FilePath != "NA" ? "DownLoad":"Not Available") + " </a>" : "<span style='color:Red' >Not Available</span>"
}
})).ToArray().Skip(SkipCount);
return data;
}
JS File Code is As Follows
function DownLoadFile(param) {
$.ajax({
url: "/Home/GetFile?parameter=" + param,
cache: false,
type: "POST",
async: false
});
}
Code in Controller as follows
public ActionResult GetFile(string parameter)
{
string queryStringParameters = Request.QueryString["parameter"];
if (queryStringParameters == null)
{
throw new Exception("Url is tampered");
}
string[] parameterArray = queryStringParameters.Split('/');
string param = null;
string hash = null;
string key = null;
if (parameterArray.Length == 3)
{
param = parameterArray[0];
hash = parameterArray[1];
key = parameterArray[2];
}
if (!(string.IsNullOrEmpty(parameter)))
{
Dictionary<string, string> parameters = URLEncrypt.DecryptParameters(new string[] { param, hash, key });
string FilePath =string.Empty ;
parameters.TryGetValue("filepath", out FilePath);
FilePath = FilePath.Replace('$','\\');
// DownloadFile(FilePath);
string name = Path.GetFileName(FilePath);
string ext = Path.GetExtension(FilePath);
string type = "";
// set known types based on file extension
if (ext != null)
{
switch (ext.ToLower())
{
case ".pdf":
type = "Application/pdf";
break;
case ".doc":
case ".docx":
type = "Application/msword";
break;
case ".jpg":
case ".bmp":
case ".tiff":
case ".png":
case ".gif":
case ".jpeg":
type = "Application/Image";
break;
default:
type = "Application";
break;
}
}
Response.AppendHeader("content-disposition", "attachment; filename=" + name);
if (type != "")
{
Response.ContentType = type;
}
String FullFilePath = #"F:\MHTOLL\ContractUploadDetails\" + name;
//return File(new FileStream(path + fileName, FileMode.Open), "text/plain", fileName);
// return File(new FileStream(FullFilePath, FileMode.Open), type, name);
return File(FullFilePath, type,name);
}
return null;
}
Dont mind now about return null and exception handling
also suggest for displaying .gif animation for downloading file.
I don't think you can use an AJAX call to download a file.
I think this answer will get you what you want. Be sure to read the comments about the download prompt and MIME types. Download File Using Javascript/jQuery
I recently encountered the same issue and realized that AJAX will not work to download a file. Try an ActionLink instead:
#Html.ActionLink("ButtonName", "controllerFunctionName", "controllerName", new { functionParamName = paramValue })
And you would include your function in the controller:
public ActionResult controllerFunctionName(type functionParamName){
// do your download here
}

Resources