sending form data xmlhttprequest - asp.net-mvc

In below code first am allowing the user to select the option from the drop down list and than allows to browse the file.
Code:
function choice() {
var box = dhtmlx.modalbox({
text: "<div id='form_in_box'><div>Choose a File to Convert <hr/><label>Filename: <input type='file' name='file' id='file' style='width: 400px; height: 27px;'></label><br></div><div><span class='dhtmlx_button'><input type='submit' value='Create PDF' style='width: 86px' onclick='Convert(this)'></span><span class='dhtmlx_button'><input type='button' value='Cancel' onclick='close_file(this)' style='width:80px;'></span></label></div></div>",
width: "300px"
});
}
function Convert(box) {
var ch = document.getElementById('choice');
var file = document.getElementById('file');
if (file.value == "") {
alert("Choose a file to convert");
return false;
}
dhtmlx.modalbox.hide(box);
var fd = new FormData();
fd.append('file', file.files[0]);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/FileUpload/Convert', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert('File successfully conveted to PDF');
}
};
xhr.send(fd);
}
In ch the drop down option gets saved.
I want to send ch value to the controller
Controller code:
public ActionResult Convert(HttpPostedFileBase file, FormCollection data)
{
string choice = data["choice"];
how can i send it?

You could add it to the FormData:
var fd = new FormData();
fd.append('file', file.files[0]);
fd.append('choice', ch.value);
and your controller action may now look like this:
public ActionResult Convert(HttpPostedFileBase file, string choice)
{
...
}

Related

uploading file using input field

I created a web app using asp.net-mvc and Jquery
when I added the below code my application automatically stop running without throwing any error, I don't know Whether it is my visual studio 19 or IIS which is being crashed
<label for="myfile">Select a file:</label>
<input type="file" id="myfile" name="myfile">
To verify I created an asp.net mvc sample project and paste the above code in the index page but the same problem comes
Image
what can I do to solve this?
Do you have
enctype="multipart/form-data"
property in your form element?
<form id="upload">
<input type="file" id="file" class="form-control">
</form>
Jquery
$('#upload').submit(function (e) {
e.preventDefault(); // stop the standard form submission
var File_Name = $("#file").prop('files')[0].name;
var ext = File_Name.split('.').pop();
if (ext == "pdf" || ext == "docx" || ext == "doc" || ext == "png" || ext ==
"jpg" || ext == "jpeg" || ext == "txt") {
var lastIndex = $("#file").prop('files')[0].name.lastIndexOf(".") + 1;
var form = new FormData();
form.append("file", $("#file").prop('files')[0]);
$.ajax({
url: '/Main/SaveDocument',
type: 'POST',
data: form,
cache: false,
contentType: false,
processData: false,
success: function (data) {
console.log(data.UploadedFileCount + ' file(s) uploaded successfully');
if (data == "999") {
swal("Note", "Some Error Occurred. File Not uploaded successfully.", "error");
}
},
error: function (xhr, error, status) {
console.log(error, status + " " + xhr);
}
});
}
else {
swal("Note", "File Type Not Supported.", "warning");
}
});
C#
public ActionResult SaveDocument()
{
//file
var file = System.Web.HttpContext.Current.Request.Files["file"];
var CheckCnic = hr_FTPEntities.File_description.Where(x => x.uploader_CNIC == userCNIC).FirstOrDefault();
if(CheckCnic == null)
{
HttpPostedFileBase filebase = new HttpPostedFileWrapper(file);
if (filebase.ContentLength > 0)
{
var fileName = Path.GetFileName(filebase.FileName);
string path = Path.Combine(Server.MapPath(basePath + departmentName) + "/");
File_description file_Description = new File_description();
int fileCount = hr_FTPEntities.File_description.Select(x => x).ToList().Count + 1;
int lastIndexOfDot = fileName.LastIndexOf(".") - 1;
string finalFileName = fileName.Substring(0, lastIndexOfDot) + "_" + fileCount + fileName.Substring(lastIndexOfDot + 1);
file_Description.file_name = finalFileName.ToString();
try
{
filebase.SaveAs(path + (finalFileName));
}
catch(Exception ex)
{
return Json("999");
}
}
return Json("000");
}
else
{
return Json("888");
}
}
You could try to use the below code:
View(Index.cshtml) :
<input type="file" id="FileUpload1" />
<input type="button" id="btnUpload" value="Upload Files" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('#btnUpload').click(function () {
// Checking whether FormData is available in browser
if (window.FormData !== undefined) {
var fileUpload = $("#FileUpload1").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 one more key to FormData object
fileData.append('username', 'test');
$.ajax({
url: '/Home/UploadFiles',
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);
}
});
} else {
alert("FormData is not supported.");
}
});
});
</script>
Controller (HomeController.cs):
[HttpPost]
public ActionResult UploadFiles()
{
// Checking no of files injected in Request object
if (Request.Files.Count > 0)
{
try
{
// Get all files from Request object
HttpFileCollectionBase files = Request.Files;
for (int i = 0; i < files.Count; i++)
{
//string path = AppDomain.CurrentDomain.BaseDirectory + "Uploads/";
//string filename = Path.GetFileName(Request.Files[i].FileName);
HttpPostedFileBase file = files[i];
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;
}
// Get the complete folder path and store the file inside it.
fname = Path.Combine(Server.MapPath("~/Uploads/"), fname);
file.SaveAs(fname);
}
// Returns message that successfully uploaded
return Json("File Uploaded Successfully!");
}
catch (Exception ex)
{
return Json("Error occurred. Error details: " + ex.Message);
}
}
else
{
return Json("No files selected.");
}
}
Make sure your IIS site contains the upload folder and enough permission to access the folder.
If you still face the same issue then try to use the different browser.
check event viewer logs or try to collect the dup and analyze the dump using the DebugDiag tool.

Stop process if condition is null and return message

I have a controller like this:
public ActionResult CargaCSV(HttpPostedFileBase archivo)
{
List<string[]> registros = new List<string[]>();
confService = new ConfiguracionService();
if (archivo.ContentLength > 0)
{
StreamReader sR = new StreamReader(archivo.InputStream);
string linea;
string resultado = "";
var f = 0;
while ((linea = sR.ReadLine()) != null)
{
if (f == 0)
{
f++;
continue;
}
else
{
String[] registros_ = linea.Split(',');
registros.Add(registros_);
}
}
sR.Close();
ViewBag.Message = resultado;
confService.GuardarMatrizCsv(registros,usuarioCaptura);
}
return Json(registros);
}
As you can see I return result into div:
ViewBag.Message = resultado;
View:
<div class="" style="height: 150px; overflow: auto; margin-bottom:10px;">
<pre id="resultado">#ViewBag.Message</pre>
</div>
That I want to do is to cancel all proccess if (archivo.ContentLength > 0) return null and return: ViewBag.Message = "you need attach file to load it"; and stop all process
How can I achieve this?
Update:
I call CargaCSV method with ajax call:
$("#btnCargarCsv").on("click", function () {
var data = new FormData();
data.append("archivo", $("#archivo")[0].files[0]);
$.ajax({
"type": "POST",
"url": "/Configuracion/CargaCSV",
"contentType": false,
"processData": false,
"data": data,
success: function (s) {
var result = $("#resultado");
result.text("");
result.append("<table>");
result.append("<tr>");
result.append("<th> Unidad </th>");
result.append("<th> CR Mínimo </th>");
result.append("<th> CR Máximo </th>");
result.append("<th> % Mínimo </th>");
result.append("<th> % Máximo </th>");
result.append("</tr>");
for (var i = 0; i < s.length; i++) {
var val = s[i];
result.append("<tr>");
result.append("<td> " + val[0] + " </td>");
result.append("<td> " + val[1] + " </td>");
result.append("<td> " + val[2] + " </td>");
result.append("<td> " + val[3] + " </td>");
result.append("<td> " + val[4] + " </td>");
result.append("</tr>");
}
result.append("</table>");
}
});
});
So here I append data into table and show data into pre html tag "resultado"
Your returning a JsonResult, not a ViewResult, so setting a ViewBag property is pointless (ViewBag is for passing data to a View) and your
<pre id="resultado">#ViewBag.Message</pre>
element will only ever display the initial value of ViewBag.Message when the page is first rendered.
You need to return the message in your JsonResult and test it in the ajax success method.
Change the controller code to return different values based on your condition
public ActionResult CargaCSV(HttpPostedFileBase archivo)
{
if (archivo.ContentLength = 0)
{
string message = "you need attach file to load it";
return Json( new { message = message });
}
.... // your code to process the file
return Json(new { registros = registros });
}
and change the code in the success callback to test the result
success: function (data) {
if (data.message) {
$('#resultado').text(data.message);
} else if (data.registros) {
var result = $("#resultado");
....
for (var i = 0; i < data.registros.length; i++) {
var val = data.registros[i];
....
}
result.append("</table>");
}
}
As a side note, you could simplify your script by generating the <table> and its headings (which should be in a <thead> element) in the view (and style it using display: none;and just add the <tr> elements inside its <tbody> element (and then show/hide the table in the success callback), for example
<table id="resultstable" style="display:none">
<thead>
....
</thead>
<tbody id="results"></tbody>
<table>
Script
var table = $('#resultstable');
var results = $('#results');
var message = $('#resultado');
$('btnCargarCsv').on('click', function () {
....
$.ajax({
....
success: function (data) {
if (data.message) {
message.text(data.message);
table.hide();
} else if (data.registros) {
results.empty(); //remove any existing rows
table.show();
for (var i = 0; i < data.registros.length; i++) {
var val = data.registros[i];
var row = $('<tr></tr>');
for(int j = 0; j < val.length; j++) {
row.append($('<td></td>').text(val[j]));
}
results.append(row);
}
}
}
});
});
In addition, you should be testing if the value of the file input is null before making the ajax call (and cancel the ajax call and display the message if it is) to prevent an unnecessary call to the server.

Error uploading file in Dart to Redstone Server

I am trying to upload a file in Dart with this code
Reading the file
dom.InputElement uploadInput = dom.querySelector('#upload');
uploadInput.onChange.listen((dom.Event e)
{
// read file content as dataURL
final files = uploadInput.files;
if (files.length == 1)
{
final file = files[0];
final reader = new dom.FileReader();
reader.onLoad.listen((_)
{
dataRequest('upload', reader.result);
});
reader.readAsDataUrl (file);
}
});
Sending the file
Future<dom.HttpRequest> dataRequest (String path, dynamic data)
{
return dom.HttpRequest.request (path, method: "POST",
sendData: data);
}
But I get this error
POST http://localhost:9090/upload 400 (Bad Request) :9090/upload:1
Instance of '_XMLHttpRequestProgressEvent'
STACKTRACE:
null
I receive it in Redstone like this
#app.Route("/upload", methods: const [app.POST], allowMultipartRequest: true)
#Encode()
upload(#app.Body(app.FORM) Map form)
{
var file = form["file"];
print(file.filename);
print(file.contentType);
print(file.runtimeType);
return new Resp()
..success = (file.filename != null);
}
Any ideas?
Dart: 1.9.1
Redstone: 0.5.21
Let's say you have the following html:
<!DOCTYPE html>
<html>
<head>
<title>send_file.html</title>
</head>
<body>
<form id="read">
user: <input type="text" name='user' value='DefaultValue'>
<input type="file" id="file" name="my_file"/> <br>
<input type="button" id="whole_btn" value="Send whole form!">
<input type="button" id="specific_btn" value="Send specific values!">
</form>
<script type="application/dart" src="send_file.dart"></script>
</body>
</html>
Redstone server file:
import 'dart:io';
import 'package:logging/logging.dart';
import 'package:redstone/server.dart' as app;
import 'package:shelf_static/shelf_static.dart';
#app.ErrorHandler(HttpStatus.NOT_FOUND)
handleNotFoundError() => app.redirect("not_found.html");
#app.Route('/post',methods: const [app.POST], allowMultipartRequest: true)
wholeFormPost(#app.Body(app.FORM) Map form) {
var user = form['user'];
var f = form['my_file'];
print('user: $user \n file: \n ${f.content}');
}
#app.Route('/post1',methods: const [app.POST], allowMultipartRequest: true)
specificPost(#app.Body(app.FORM) Map form) {
var specificField = form['specificField'];
var f = form['my_file'];
print('specificField: $specificField \n file: \n ${f.content}');
}
#app.Interceptor(r'/.*')
interceptor1() {
if (app.request.method == 'OPTIONS') {
app.response = app.response.change(headers: CORS);
app.chain.interrupt();
} else {
app.chain.next(() {
return app.response = app.response.change(headers: CORS );
});
}
}
Map CORS = {
"Access-Control-Allow-Origin" : "*, ",
"Access-Control-Allow-Methods": "POST, GET, OPTIONS",
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Content-Disposition"
};
main() {
app.setShelfHandler(createStaticHandler("/home/raz2/dartProjects_linux_1/PR5/cl2/lib",
defaultDocument: 'send_file.html',
serveFilesOutsidePath: true));
app.setupConsoleLog(Level.ALL);
app.start(address: "0.0.0.0", port: 8081);
}
The client dart file: send_file.dart
import 'dart:html';
class UploadFileEx {
FormElement _readForm;
InputElement _fileInput;
File file;
ButtonElement _wholeBtn;
ButtonElement _specificBtn;
UploadFileEx() {
_readForm = document.querySelector('#read');
_fileInput =
document.querySelector('#file')
..onChange.listen(_onFileInputChange);
_wholeBtn =
document.querySelector('#whole_btn')
..onClick.listen((sendForm));
_specificBtn =
document.querySelector('#specific_btn')
..onClick.listen((sendFileAndField));
}
_onFileInputChange(_) {
file = _fileInput.files[0];
}
// Send the whole form
void sendForm(_) {
if(file == null)
return;
FormData fd = new FormData(_readForm);
HttpRequest req = new HttpRequest();
req.open("POST", 'http://127.0.0.1:8081/post');
req.send(fd);
}
// add my own field to FormData
void sendFileAndField(_) {
if(file == null)
return;
FormData fd = new FormData();
fd.append('specificField', 'Lalala');
fd.appendBlob('my_file', file);
HttpRequest req = new HttpRequest();
req.open("POST",'http://127.0.0.1:8081/post1');
req.send(fd);
}
}
void main() {
new UploadFileEx();
}
Should work.
Check out this link for more info: Sending_forms_through_JavaScript

Image Upload using MVC API POST Multipart form

My View :-
<form class="commentform commentright" enctype="multipart/form-data" >
<textarea class="simpleta required" name="Body" placeholder="Discuss this vehicle with other members of Row52."></textarea>
<input type="file" id="fileuploadfield" name="fileuploadfield"/>
<input type="submit" value="Submit" class="btn btn-inverse btn-small"/>
<input type="hidden" name="ParentId" value="0"/>
<input type="hidden" name="VehicleId" value="#Model.VehicleId"/>
<span class="commentcount"><span class="numberofcomments">#Model.Count</span>#count</span>
<div class="feedback"></div>
<img id="img" src="" />
</form>
JQuery :-
submitComment: function (form, type) {
var self = this;
var $this = $(form);
var formData = $this.serialize();
var $message = $this.find('.feedback');
$message.hide();
$message.html('');
var val = validation({ $form: $this });
if (val.checkRequired()) {
$this.indicator({ autoStart: false, minDuration: 100 });
$this.indicator('start');
var files = $("#fileuploadfield").get(0).files;
if (files.length > 0) {
if (window.FormData !== undefined) {
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append("file" + i, files[i]);
}
}
else {
alert("This browser doesn't support HTML5 multiple file uploads!");
}
}
else {
alert("This");
}
$.ajax('/api/v2/comment/Post/', {
type: 'POST',
contentType: 'multipart/form-data',
// I have also use contentType: false,
processData: false,
data: formData
}).done(function (d) {
Controller :-
public Task<HttpResponseMessage> Post()
{
var provider = new MultipartMemoryStreamProvider();
var task1 = Request.Content.ReadAsMultipartAsync(provider);
var userId = User.Id;
return task1.Then(providerResult =>
{
var file = GetFileContent(providerResult);
var task2 = file.ReadAsStreamAsync();
string originalFileName = file.Headers.ContentDisposition.FileName.Replace("\"", "");
string extension = Path.GetExtension(originalFileName);
string fileName = Guid.NewGuid().ToString() + extension;
return task2.Then(stream =>
{
if (stream.Length > 0)
{
var kernel = WindsorContainerFactory.Create(KernelState.Thread, ConfigurationState.Web);
CloudBlobContainer container = GetContainer();
var userRepo = kernel.Resolve<IUserRepository>();
var logger = kernel.Resolve<ILogger>();
logger.Fatal("Original File Name: " + originalFileName);
logger.Fatal("Extension: " + extension);
logger.Fatal("File Name: " + fileName);
var user = userRepo.FirstOrDefault(x => x.Id == userId);
var path = CreateImageSize(stream, 500, fileName, userId, container, logger);
if (user != null)
{
user.AvatarOriginalFileName = fileName;
user.AvatarOriginalAbsolutePath =
ConfigurationManager.AppSettings["CdnUserEndpointUrl"] + path;
user.AvatarOriginalRelativePath = path;
user.AvatarCroppedAbsolutePath = "";
user.AvatarCroppedFileName = "";
user.AvatarCroppedRelativePath = "";
userRepo.Update(user);
}
else
{
Logger.Error("User is null. Id: " + userId.ToString());
}
kernel.Release(userRepo);
kernel.Release(logger);
kernel.Dispose();
}
var response = Request.CreateResponse(HttpStatusCode.Moved);
response.Headers.Location = new Uri("/Account/Avatar", UriKind.Relative);
return response;
});
});
}
Following Error get :-
"Invalid 'HttpContent' instance provided. It does not have a content type header starting with 'multipart/'. Parameter name: content"
There's no standard Task.Then method in .NET framework, and I couldn't find any implementation details in the code you posted. I'd assume it was taken from here:
Processing Sequences of Asynchronous Operations with Tasks
If that's the case, you may be loosing AspNetSynchronizationContext context inside your Task.Then lambdas, because the continuation may happen on a different ASP.NET pool thread without proper synchronization context. That would explain why HttpContent becomes invalid.
Try changing the implementation of Task.Then like this:
public static Task<T2> Then<T1, T2>(this Task<T1> first, Func<T1, Task<T2>> next)
{
if (first == null) throw new ArgumentNullException("first");
if (next == null) throw new ArgumentNullException("next");
var tcs = new TaskCompletionSource<T2>();
first.ContinueWith(delegate
{
if (first.IsFaulted) tcs.TrySetException(first.Exception.InnerExceptions);
else if (first.IsCanceled) tcs.TrySetCanceled();
else
{
try
{
var t = next(first.Result);
if (t == null) tcs.TrySetCanceled();
else t.ContinueWith(delegate
{
if (t.IsFaulted) tcs.TrySetException(t.Exception.InnerExceptions);
else if (t.IsCanceled) tcs.TrySetCanceled();
else tcs.TrySetResult(t.Result);
}, TaskScheduler.FromCurrentSynchronizationContext());
}
catch (Exception exc) { tcs.TrySetException(exc); }
}
}, TaskScheduler.FromCurrentSynchronizationContext());
return tcs.Task;
}
Note how the continuations are now scheduled using TaskScheduler.FromCurrentSynchronizationContext().
Ideally, if you can use .NET 4.5, you should be using async/await: Using Asynchronous Methods in ASP.NET 4.5. This way, the thread's synchronization context is automatically captured for await continuations.
The following may facility porting:
Implementing Then with Await.

How to upload File from URL

In my application am allowing the user to upload file from the URL
code to upload File URL:
function loadURL(box) {
var box = dhtmlx.modalbox({
title: "Load URL",
text: "<div id='form_in_box'><div>Enter the URL of PDF file <hr/><input type='text' name='files' id='files' style='width: 400px; height: 27px;'></label><br></div><div><span class='dhtmlx_button'><input type='submit' value='Load URL' style='width: 86px' onclick='load_file(this)'></span><span class='dhtmlx_button'><input type='button' value='Cancel' onclick='close_file(this)' style='width:80px;'></span></label></div></div>",
width: "300px"
})
}
function load_file(box) {
var file = document.getElementById('files');
if (file == "") {
alert("Enter File URL");
return false;
}
file = file.value;
var filename = file.substring(file.lastIndexOf('/') + 1);
dhtmlx.modalbox.hide(box);
$.post("/FileUpload/UploadURL",
{ file: '' + file + ''
});
}
Controller code
public ActionResult UploadURL(string file)
{
string files = Path.GetFileName(file);
string myStringWebResource = "";
WebClient myWebClient = new WebClient();
myStringWebResource = file;
string path = Server.MapPath(_fileUploadPath + files);
myWebClient.DownloadFile(myStringWebResource, path);
string extFile = Server.MapPath(_fileUploadPath + files);
return View();
}
Files are gettinig downloaded successfully. Now I want to upload the same file How can I do so?
HTML file upload control is for uploading from client's computer only. What you have to do is to download file from another server and save it at yours. This thread should help.

Resources