Upload data with file - c#

I have to send the files along with some description about those to the server.
So as per above image, I want to upload a file and provide the description of file in a text box on right side of it. After clicking select files link, the user can select another file to upload and it will also have description text box. After clicking upload files, along with the file, description of it neet to upload to the server.
I am using plupload to do it. But it is just uploading file and not description.
Also, I am using MVC. So please suggest any solution to it or suggest any other javascript library which can fulfill my requirements.
Below is the MVC code,
public string Upload(List<HttpPostedFileBase> fileUploads,List<string> fileDescription)
{
int count = 0;
foreach (HttpPostedFileBase file in fileUploads)
{
byte[] fileData = new byte[file.ContentLength];
file.InputStream.Read(fileData, 0, file.ContentLength);
db.UploadedFiles.AddObject(new UploadedFile
{
FileDescription = fileDescription[count],
FileBinary = fileData,
FileName = file.FileName
});
count++;
}
db.SaveChanges();
return "Success";
}
Below is javascript code
var uploadFiles = [];
var descs = [];
var count = 0;
plupload.each(uploader.files, function (file) {
var id = file.id;
var fileUpload = file;
uploadFiles[count] = file;
descs[count] = $("#" + id + "_desc").val();
count++;
});
var da = { fileDescription: descs,fileUploads: uploader.files };
$.ajax({
url: '/LumosQC/Upload',
data: da,
method: 'POST',
}).done(function (data1) {
alert("Success");
}).error(function (a, b, c) {
console.log(a);
});

You can modify the route you use for uploading and use something like
...
[Route("upload/{description}")]
public HttpResponseMessage Upload(string description)
...
Or you can put description into cookie (but I would recomend to use the first approach it's cleaner)
function createCookie(name,value,days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + value + expires + "; path=/";
}
createCookie('desciption', 'your description', 1)
and then
Request.Cookies["description"]
UPDATE
Now I see you need to upload multiple files, for that you can use the same approach with modified route
[Route("upload")]
public string Upload(List<HttpPostedFileBase> fileUploads, [FromUri] string[] fileDescription)

Create view model and use as parameter in action method,
ViewModel :
public class UploadViewModel
{
public List<string> FileDescriptions;
public List<HttpPostedFileBase> Files;
}
Action method :
public string Upload(UploadViewModel model)
{
// ....
}
that will bind the data correctly.

Related

MVC AJAX File Uploading - Ceased To Work

I have a solution for uploading a file and other data via an AJAX request to an MVC controller.
For a long time, this has been working fine, but today, I've been investigating issues people have been reporting with it, and now it appears to not be functioning at all; I am now getting a "Resource not found" error returned.
If I remove "data: fileData," from the AJAX call, then it is able to resolve the URL, but obviously, there is then no data to process.
Would someone be able to shed any light on why this could stop functioning in this way? I am at a loss to explain this.
In Short:
AJAX call no longer able to resolve controller method URL. No obvious recent changes made to this functionality in repository history.
Thank you,
Matthew.
UPDATE
For the sake of those interested, it turns out that the size of the specific PDF file I was given to test was the culprit all along...This solution still works, and can work for larger files by
adding the following to the web.config file:
<system.web>
<httpRuntime maxRequestLength="10240" />
<!--This allows larger files to be uploaded (10MB in KB)-->
</system.web>
...
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="10485760" />
<!--This allows larger files to be uploaded (10MB in Bytes)-->
</requestFiltering>
</security>
</system.webServer>
END UPDATE
In-page Javascript:
function SaveAttachmentData() {
var attachmentID = $('#attachmentrecordid').val();
var servID = $('#servrecordid').val();
var description = $('#txtattachmentdescription').val();
// Checking whether FormData is available in browser
if (window.FormData !== undefined) {
var fileUpload = $("#attachmentfile").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]);
}
// Adding keys to FormData object
fileData.append('service_id', servID);
fileData.append('dataid', attachmentID);
fileData.append('description', description);
var validData = true;
if (!isNormalInteger(servID)){validData = false;}
if (servID < 1) {validData = false;}
if (files.length == 0 && $('#attachmentrecordid').val() < 1){validData = false;}
if (validData){ //All data is valid
$.ajax({
url: '/Service/AttachmentCreate',
type: "POST",
contentType: false, // Not to set any content header
processData: false, // Not to process data
data: fileData,
success: function (result) {
ReloadAttachmentTable();
},
error: function (err) {
ReloadAttachmentTable();
}
});
}
else{
//Data is not valid
alert('Invalid data entered!');
//ShowBannerMessageWarning('Warning!','Invalid data entered!');
}
} else {
alert("FormData is not supported.");
}
}
Controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AttachmentCreate()
{
//Upload file
string message = "";
DataModel dm = new DataModel();
Service.Attachment sa = new Service.Attachment();
//Get request data
string description = Request.Form["description"];
int servid = int.Parse(Request.Form["service_id"]);
HttpFileCollectionBase files = Request.Files;
//Only continue if a file was uploaded
if (files.Count > 0)
{
//Get the file
HttpPostedFileBase file = files[0];
string fname;
// Checking for Internet Explorer
if (Request.Browser.Browser.ToUpper() == "IE" || Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
{
string[] testfiles = file.FileName.Split(new char[] { '\\' });
fname = testfiles[testfiles.Length - 1];
}
else
{
fname = file.FileName;
}
//Update attachment properties
sa.ID = servid;
sa.Description = description;
sa.Filename = fname; //Assign fname before the full path is added to it
//Get full filename from attachment class property
fname = sa.Filename_Structured;
// Get the complete folder path and store the file inside it.
fname = Path.Combine(ConfigurationManager.AppSettings["AttachmentFolderLocation"].ToString(), fname);
//Save file to server
file.SaveAs(fname);
//Create file attachment record against service
message = dm.CreateAttachmentData(ref sa);
message = message == "" ? "Success" : message;
}
else { message = "No file uploaded"; }
return Content(message);
}

how to post httppostedfile to webapi

How do I post a httppostedfile to a webapi?
Basically I want the user to select an excel file and I want to post it to my webapi.
The gui is made with classic asp.net and the webapi is made with new .NET apicontroller.
I have done some api coding before but then I used JSON and that doesn't seem to work very good with this kind of object.
Can someone please just point me in the right direction so that I can continue to search for info. Right now I don't even know what to search for.
I solved this by doing this:
In my controller:
using (var client = new HttpClient())
using (var content = new MultipartFormDataContent())
{
client.BaseAddress = new Uri(System.Configuration.ConfigurationManager.AppSettings["PAM_WebApi"]);
var fileContent = new ByteArrayContent(excelBytes);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
content.Add(fileContent);
var result = client.PostAsync("api/Product", content).Result;
}
And here is my ApiController:
[RoutePrefix("api/Product")]
public class ProductController : ApiController
{
public async Task<List<string>> PostAsync()
{
if (Request.Content.IsMimeMultipartContent())
{
string uploadPath = HttpContext.Current.Server.MapPath("~/uploads");
if (!System.IO.Directory.Exists(uploadPath))
{
System.IO.Directory.CreateDirectory(uploadPath);
}
MyStreamProvider streamProvider = new MyStreamProvider(uploadPath);
await Request.Content.ReadAsMultipartAsync(streamProvider);
List<string> messages = new List<string>();
foreach (var file in streamProvider.FileData)
{
FileInfo fi = new FileInfo(file.LocalFileName);
messages.Add("File uploaded as " + fi.FullName + " (" + fi.Length + " bytes)");
}
return messages;
}
else
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid Request!");
throw new HttpResponseException(response);
}
}
}
public class MyStreamProvider : MultipartFormDataStreamProvider
{
public MyStreamProvider(string uploadPath)
: base(uploadPath)
{
}
public override string GetLocalFileName(HttpContentHeaders headers)
{
string fileName = headers.ContentDisposition.FileName;
if (string.IsNullOrWhiteSpace(fileName))
{
fileName = Guid.NewGuid().ToString() + ".xls";
}
return fileName.Replace("\"", string.Empty);
}
}
I found this code in a tutorial so i'm not the one to be credited.
So here i write the file to a folder. And because of the mysreamprovider i can get the same name of the file as the file i first added in the GUI. I also add the ending ".xls" to the file because my program is only going to handle excel files. Therefor i have added some validation to the input in my GUI to so that i know that the file added is an excel file.

KendoUI: How to get new file name in javascript after renaming uploaded file in controller

I have the following Kendo upload control
#(Html.Kendo().Upload()
.Name("files")
.Async(a => a
.Save("SaveBackgroundImage", "Plans")
.AutoUpload(true))
.Multiple(false)
.Events(events => events.Success("onSuccess")))
My controller:
public ActionResult SaveBackgroundImage(IEnumerable<HttpPostedFileBase> floorplanFiles, string floorplanId)
{
foreach (var file in files)
{
string fileName = "ABC.jpg" //this will be random
var physicalPath = Path.Combine(Server.MapPath("~/Images/Floorplans/Fullsize"), fileName);
file.SaveAs(physicalPath);
}
// Return an empty string to signify success
return Content("");
}
My javascript:
function onSuccess(e) {
var filename = getFileInfo(e);
alert(filename);
}
function getFileInfo(e) {
return $.map(e.files, function (file) {
var info = file.name;
return info;
}).join(", ");
}
How do I get back "ABC.jpg" as my filename in my javascript instead of the original filename that I select to upload?
Solved by doing this in my controller:
var newImageName = "123.jpg";
return Json(new { ImageName = newImageName }, "text/plain");
and in the onSuccess function:
function onSuccess(e) {
var imageName = e.response.ImageName;
}

ASP.net Razor return image URL in JSON from upload

Below I have code from my image upload returning JSON information about the image. Near the assignment of the name parameter I am trying to return the URL of the image although it is not working. Currently the below code does not work as nothing is returned to the browser upon return. The code works fine albeit for the line to add to the Name property near the end.
How can I return the URL of the image so as to display the image URL to the user on return?
[HttpPost]
public ContentResult UploadFiles()
{
var r = new List<UploadFilesResult>();
foreach (string file in Request.Files)
{
HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
if (hpf.ContentLength == 0)
continue;
string savedFileName = Url.Content(Path.Combine(Server.MapPath("~/Images"), Path.GetFileName(hpf.FileName)));
hpf.SaveAs(GetNewPathForDupes(savedFileName));
r.Add(new UploadFilesResult()
{
Name = Path.Combine(Server.MapPath("~/Images"), Path.GetFileName(hpf.FileName)),
Length = hpf.ContentLength,
Type = hpf.ContentType
});
}
return Content("{\"name\":\"" + r[0].Name + "\",\"type\":\"" + r[0].Type + "\",\"size\":\"" + string.Format("{0} bytes", r[0].Length) + "\"}", "application/json");
}
EDIT
my Javascript to process the form in the done parameter i am trying to read the JSON but cant get it to work with the new Jsonresult:
$(document).ready(function () {
$('#fileupload').fileupload({
dataType: 'json',
url: "UploadFiles",
autoUpload: true,
done: function (e, data) {
var json = JSON.parse(data);
$('.file_name').html(json.name);
$('.file_type').html(json.type);
$('.file_size').html(json.size);
}
}).on('fileuploadprogressall', function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('.progress .progress-bar').css('width', progress + '%');
});
});
So instead of
return this.Content("{\"name\":\"" + r[0].Name + ...
you could simply do this:
return this.Json(r[0]);
When reading the JSON in your jQuery you will need to do
var jsonString = // from the response
var json = $.parseJSON(jsonString);
var name = json.someElement;

Issues with HttpContext.Current.Response.Redirect in a class

I have written a class which gets the post data using jquerypost and then perform some crud operations. Its works fine adding stuff to the database , but it doesnt redirects to the page when passing certain data , below is the code :
$('#clickme').click(function (e) {
e.preventDefault();
indx = $("#DropDownList1 option:selected").index();
indx += 1;
var test = $("#DropDownList" + (indx + 1));
var url = "/Base/performOperations/shootme/"
jQuery.post(url, { name: jQuery("#name").val(), email: jQuery("#email").val(), federation: jQuery(test).val(), selectedscheme: jQuery("#DropDownList1").val() },
function (data) {
if (data == scheme1) {
window.location = "http://www.openme.com"
}
});
});
namespace pw
{
public class performOperations
{
public static string ShootMe() {
HttpRequest post = HttpContext.Current.Request;
string name = post["name"];
string email = post["email"];
string selectedscheme = post["selectedscheme"];
string federation = post["federation"];
string conn = System.Configuration.ConfigurationManager.AppSettings["mydb"];
string sql = "INSERT INTO dbo.mydb(Email,Name,schemes,LoginDate,schemeType) VALUES(#email,#name,#scheme,#dateTime,#federation)";
SqlHelper.ExecuteNonQuery(conn, CommandType.Text, sql,
new SqlParameter("#email", email),
new SqlParameter("#name", name),
new SqlParameter("#scheme", selectedscheme),
new SqlParameter("#dateTime", DateTime.Now),
new SqlParameter("#federation", federation));
return selectedscheme;
}
}
}
Any ideas why the redirect doesnt takes place, or am i doing it in a wrong way , i need to redirect to a particular page once the data is injected to the db.
Any assistance will be appreciated
If you are calling the POST method using AJAX, redirection at server side will not work.
You will have to redirect it at client side after request completion using javascript the request.
$('#clickme').click(function (e) {
e.preventDefault();
indx = $("#DropDownList1 option:selected").index();
indx += 1;
var test = $("#DropDownList" + (indx + 1));
var url = "/Base/sample/Hello/"
jQuery.post(url, { name: jQuery("#name").val(), email: jQuery("#email").val(), federation: jQuery(test).val(), selectedscheme: jQuery("#DropDownList1").val() },
function (data) {
if (data == "shoothim") {
window.location = "http://www.cuthishead.com"
}
else if(data == "shoother")
{
window.location = "http://www.chopherbody.com"
}
else if(data == "shootboth")
{
window.location = "http://www.fulldeath.tv"
}
});
return selectedscheme or URL from your page method
set window.location based on web method result on jquery
need to set WebMethod attribute for your C# method
Check Using jQuery to Call ASP.NET AJAX Page Methods – By Example

Categories

Resources