FormData can't into the Server, what problem in my Code - c#

What can I do to send FormData to my server, my file is always null in server or return Unsupported Media status 415, I try to solve the problem but have no idea now....
<form enctype="multipart/form-data" name="add_data" id="add_data" method="post" onsubmit="return false" >
<input type="file" multiple="multiple" name="files" value="" id="files" />
<br />
<input type="submit" class="btn btn-success" value="Upload">
<br />
</form>
this my html part and then
ajax
$('#add_data').submit(function () {
var totalFiles;
totalFiles = document.getElementById("files").files[0];
var formData = new FormData();
formData.append("files", totalFiles);
$.ajax({
url: "/api/food/addfile",
type: "Post",
data:myData,
contentType: false,
processData: false,
beforeSend: function (request) {
request.setRequestHeader("Authorization", "Bearer " + token);
},
data: totalFiles ,
dataType: 'json',
success: function () {
alert("success")
},
error: function (jqXHR, exception) {
if (jqXHR.status == 401) {
return alert("請先執行前置作業");
}
alert(jqXHR.responseText);
}
});
});
and Controller
[Authorize]
[HttpPost,Route("addfile")]
public IActionResult GetPicture(/*HttpPostedFileBase[] files*/)
{
#region test1
//if (files != null)
//{
// foreach (HttpPostedFileBase file in files)
// {
// file.SaveAs(Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/upload/"), file.FileName));
// }
//}
#endregion
#region test2
var req = System.Web.HttpContext.Current.Request;
if (req.Files.Count > 0)
{
foreach (string fileName in req.Files.Keys)
{
var file = req.Files["files"];
file.SaveAs(Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/upload/"), file.FileName));
}
}
#endregion
return Json(new { Status = 1 > 0 ? "SUCCESS" : "FAILS" });
that all Code , please who can tell me thanks.

Related

How to pass raw complex object to MVC action?

Problem: Can't parse File object to JSON string, when doing that only null values are gotten, while trying to send complex type to MVC controller.
I tried adding it into FormData object and passing it to controller, however, passing List of them was not successful, because it would either return an empty array or just plain null
model:
public class UploadedDocument
{
public HttpPostedFile File { get; set;}
public string DocumentId { get; set;}
public string DocumentType { get; set; }
}
controller:
[HttpPost]
[ActionName("UploadFile")]
public ActionResult Upload(IEnumerable<UploadedDocument> documents)
{
return View();
}
upload function:
var _documents = [];
for (var i = 0; i < arrayOfFiles.length; i++) {
var document = {
"File": arrayOfFiles[i].file,
"DocumentId": arrayOfFiles[i].documentId,
"DocumentType": arrayOfFiles[i].documentName
};
_documents.push(document);
}
$.ajax({
url: "#Url.Action("UploadFile", "Home")",
type: "POST",
data: {"documents":_documents}
});
}
});
Basically, I manage to handle single upload via ajax like below
Input Element
<input type="file" name="customerpicture" id="customerpicture" />
Formdata
function getFormData() {
var data = new FormData();
var files = $("#customerpicture").get(0).files;
if (files.length > 0) {
data.append("file", files[0]);
}
//data.append("Name", $("#name").val());
return data;
}
Ajax Method
$('#InsertCustomer').click(function () {
debugger;
var antiForgeryToken = $("input[name=__RequestVerificationToken]").val();
var url = '#Url.Action("Add_Customer", "Customer")';
$.ajax({
type: 'POST',
headers: { "__RequestVerificationToken": antiForgeryToken },
url: url,
contentType: false,
processData: false,
data: getFormData(),
success: function (res) {
$('#custinsertmodal').modal('hide');
$('#custinsertmodal').find("input,textarea,select")
.val('')
.end()
.find("input[type=checkbox], input[type=radio]")
.prop("checked", "")
.end();
bootbox.alert({ message: res.result });
}
});
});
Controller
[HttpPost, ValidateHeaderAntiForgeryToken]
public JsonResult Add_Customer()
{
var errMsg = string.Empty;
byte[] tmpImage;
try
{
//Customer Image Processing
var file = Request.Files.Get("file");
if (file != null && file.ContentLength > 0)
{
//Image Saving to Folder
UploadHelper.UploadFile(file);
//Image Saving to Database
tmpImage = new byte[file.ContentLength];
file.InputStream.Read(tmpImage, 0, file.ContentLength);
CustomerModel model = new CustomerModel
{
Signature = tmpImage
};
_setupRepo.CreateSignatory(model);
return Json(new { error = false, result = $"Customer was successfully created" }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
errMsg = ex.Message.ToString();
return Json(new { error = true, result = errMsg }, JsonRequestBehavior.AllowGet);
}
}
If you want to specifically use an ajax call to upload files: you need to use a FormData object. Files must be sent up as a single item within the FormData object and therefore cannot be passed to your ActionResult as part of a list.
Assuming you have a dynamic amount of file inputs on your page with custom fields the user can fill in, your code could look like the following:
HTML / Javascript:
<form id="File_Form">
<input type="file" name="File_1" />
<input type="text" name="DocumentName_File_1" value="doc1" />
<input type="text" name="DocumentId_File_1" value="1" />
<input type="file" name="File_2" />
<input type="text" name="DocumentName_File_2" value="doc2" />
<input type="text" name="DocumentId_File_2" value="2" />
<button>Upload Files</button>
</form>
<script>
$("#File_Form").submit(function() {
var formData = new FormData(this);
$.ajax({
url: '#Url.Action("UploadFiles")',
type: 'POST',
data: formData,
processData: false,
contentType: false,
cache: false
});
return false;
});
</script>
C#:
[HttpPost]
public ActionResult UploadFiles() {
foreach (string fileName in Request.Files) {
HttpPostedFileWrapper file = Request.Files[fileName];
string documentName = Request.Form[$"DocumentName_{fileName}"]?.ToString();
string documentId = Request.Form[$"DocumentId_{fileName}"]?.ToString();
// Do things with your file here.
}
return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
}
It may not automatically serialize into your model object, but you can still obtain the result you want with clever naming of your form elements.
Try this.
var _documents = [];
for (var i = 0; i < arrayOfFiles.length; i++) {
var document = {
"File": arrayOfFiles[i].file,
"DocumentId": arrayOfFiles[i].documentId,
"DocumentType": arrayOfFiles[i].documentName
};
_documents.push(document);
}
var formData = new FormData();
formData.append("documents", documents);
$.ajax({
url: "#Url.Action("UploadFile", "Home")",
type: "POST",
data: formData,
processData: false,
contentType: false,
});
}
});

AJAX not getting response because of page refresh

I am implementing a feature which allows a user to upload a file which is processed server-side with some information returned as a JsonResult. This worked fine with another AJAX request where I sent only strings. It seems like because FormData is being sent it causes a page refresh, which for me means I never reach the response part of my code. I would appreciate it a lot if someone dug me out of this hole, thanks!
MyPage.cshtml
<input id="readFromFile" type="file"/>
<button class="btn btn-primary" type="submit" onclick="ResultsFromFile()">Get Results</button>
<script>
function ResultsFromFile() {
var temp = $("#readFromFile")[0].files;
if (temp.length > 0) {
if (window.FormData !== undefined) {
var data = new FormData();
for (var x = 0; x < temp.length; x++) {
data.append("file" + x, temp[x]);
}
$.ajax({
type: "POST",
url: 'AlexaIndex?handler=GetResultsFromFile',
headers: { "XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val() },
contentType: false,
processData: false,
data: data,
success: function (response) {
console.log('result is ' + response);
var jsonObj = JSON.parse(response);
PopulateTable(jsonObj);
}
});
}
}
</script>
MyPage.cshtml.cs
public JsonResult OnPostGetResultsFromFile()
{
foreach (var file in Request.Form.Files)
{
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", file.FileName);
using (var stream = new FileStream(path, FileMode.Create))
{
file.CopyTo(stream);
}
var urlList = ReadFileOfUrls(path);
ModelState.Clear();
var results = _alexaExtractorService.GetAwisResults(urlList);
var json = JsonConvert.SerializeObject(results);
return new JsonResult(json);
}
return new JsonResult("FINITO MINITO");
}
The reason it's happening is because your button is wrapped in a form element, and all button elements with type="submit" will post the form to the server. Prevent the submit button from actually submitting by preventing that default action with e.preventDefault();
<input id="readFromFile" type="file"/>
<button class="btn btn-primary" type="submit" onclick="ResultsFromFile(event)">Get Results</button>
<script>
function ResultsFromFile(e) {
e.preventDefault();
var temp = $("#readFromFile")[0].files;
if (temp.length > 0) {
if (window.FormData !== undefined) {
var data = new FormData();
for (var x = 0; x < temp.length; x++) {
data.append("file" + x, temp[x]);
}
$.ajax({
type: "POST",
url: 'AlexaIndex?handler=GetResultsFromFile',
headers: { "XSRF-TOKEN": $('input:hidden[name="__RequestVerificationToken"]').val() },
contentType: false,
processData: false,
data: data,
success: function (response) {
console.log('result is ' + response);
var jsonObj = JSON.parse(response);
PopulateTable(jsonObj);
}
});
}
}
</script>
Change the button type to type="button" instead of type="submit".
<button class="btn btn-primary" type="button" onclick="ResultsFromFile()">Get Results</button>

ASP.NET-MVC ; pass model to $.ajax function to perform server-side validation

I need to do server side validation and that is send model to partial view. I am using $.ajax--> post--> json method to send and handle data, but I am failing to send validation model to partial view.
ajax method
$('#NewFunctionNavigationForm').submit(function (e) {
e.preventDefault();
var DataToPost = JSON.stringify($('#NewFunctionNavigationForm').serializeObject());
var formURL = $(this).attr("action");
$.ajax({
type: "POST",
url: formURL,
dataType: "JSON",
contentType: "application/json; charset=utf-8",
data: DataToPost,
})
.done(function (data, textStatus, jqXHR) {
if (data.Response == "Success") {
$(this).MyMessageDialog({
_messageBlockID: "_StatusMessage",
_messageContent: "Record Been Created Successfully",
_messageBlockWidth: "300px"
});
$('div#_StatusMessage').on('dialogclose', function (event) {
window.location = "/SystemCore/SystemCoreHome";
});
}
})
.fail(function (jqXHR, textStatus, errorThrown) {
$(this).MyMessageDialog({
_messageBlockID: "_StatusMessage",
_messageContent: "Error In Creating Record! "+ textStatus + " "+ errorThrown,
_messageBlockWidth: "350px"
});
$('div#_StatusMessage').on('dialogclose', function (event) {
window.location = "/SystemCore/SystemCoreHome";
});
});
});
razor form
#using (Html.BeginForm("CreateNewFunctionNavigation", "SystemCore", FormMethod.Post, new { id = "NewFunctionNavigationForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
... my fields here
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default _formButton" />
<input type="button" value="Cancel" class="btn btn-default _formButton" onclick="CancelPage();" />
</div>
</div>
}
controller method
[HttpGet]
public ActionResult CreateNewFunctionNavigation()
{
return PartialView("CreateNewNavigation_Partial");
}
[HttpPost]
public ActionResult CreateNewFunctionNavigation(CreateFunctionNavigation_SP_Map model )
{
if(ModelState.IsValid)
{
try
{
_FN_Services_a2.CreateFunctionNavigation(model);
return Json(new { Response = "Success" });
}
catch (DataException ex)
{
ModelState.AddModelError("", "Unable To Create New Function Navigation" + ex);
}
}
else
{
}
return PartialView("CreateNewNavigation_Partial", model);
//return Json(new { Url = Url.Action("CreateNewNavigation_Partial", model) });
} //end

Ajax Submits automatically be invoked in MVC

I have a weird problem.. This is my jquery code
$("#btnRate").click(function (e) {
alert("tık");
e.preventDefault();
var electionId = '#Model.ElectionId';
var profileId = '#Model.ProfileId';
$.ajax({
url: "Profile/Vote", // '#Html.Action("Vote","Profile")',
// data: { electionId: electionId, profileId: profileId },
dataType: "json",
type: "POST",
error: function (error) {
alert('An error occured, please try again! ');
},
success: function (data) {
if (data != null && data.success) {
alert("s1");
alert(data.url);
alert("s2");
window.location = data.url;
} else {
alert('An error occured, please try again. ');
}
}
});
return false;
});
and this is the html side code
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input id="btnRate" type="submit" class="btn btn-default" value="Vote !" />
</div>
</div>
when the detail form is loaded, automatically be invoked as clicked btnRate button. But i do not click..
and this is vote action in profilecontroller
// [HttpPost]
[ChildActionOnly]
public JsonResult Vote() //(int profileId, int electionId)
{
EvoteServicesProviderClient service = new EvoteServicesProviderClient();
// var result= service.createPolls(electionId, profileId);
// if(result ==1)
// return Json(new { success = true, url = "/Home/ProfileStatistic?electionId=" + electionId }, JsonRequestBehavior.AllowGet);
// else
// return Json(new { success = false, url = "/Home/ProfileStatistic?electionId=" + electionId }, JsonRequestBehavior.AllowGet);
return null;
}
even i do not click, vote function is invoked by ajax.. What is the reason?
edit: this is exception
An exception of type 'System.Web.HttpException' occurred in
System.Web.dll but was not handled in user code
Additional information: Error executing child request for handler
'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.
I solved the problem.. very interesting ..
I just deleted the comment
// '#Html.Action("Vote","Profile")',
and it works good now..
this is the last part..
$(document).ready(function () {
$("#btnRate").click(function(e) {
alert("geldi");
alert("tık");
e.preventDefault();
var electionId = '#Model.ElectionId';
var profileId = '#Model.ProfileId';
$.ajax({
url: '#Url.Action("Vote","Profile")',
data: { electionId: electionId, profileId: profileId },
dataType: "json",
type: "POST",
error: function (error) {
alert('An error occured, please try again! ');
},
success: function (data) {
if (data != null && data.success) {
alert("s1");
alert(data.url);
alert("s2");
window.location = data.url;
} else {
alert('An error occured, please try again. ');
}
}
});
return false;
});
});

Request.Files always 0

<body>
<form id="form1" runat="server" enctype="multipart/form-data">
<table id="tblAttachment"> </table>
<input id="btnSubmit" type="button" value="button" />
</form>
</body>
Dynamically inserting a FileUpload Control
<script>
$(document).ready(function () {
var MaxAttachment = 1;
$("#tblAttachment").append('<tr><td><input id=\"Attachment_' + MaxAttachment.toString() + '\" name=\"file\" type=\"file\" /><br><a class=\"MoreAttachment\">Additional Attachment</a></td></tr>');
$("#btnSubmit").on("click", UploadFile);
});
</script>
Sending Data to .ashx using Jquery
function UploadFile() {
var kdata = new FormData();
var i = 0;
//run through each row
$('#tblAttachment tr').each(function (i, row) {
var row = $(row);
var File = row.find('input[name*="file"]');
alert(File.val());
kdata.append('file-' + i.toString(), File);
i = i + 1;
});
sendFile("fUpload.ashx", kdata, function (datad) {
}, function () { alert("Error in Uploading File"); }, true);
}
On .ashx Count always Zero ??
public class fUpload : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
int k = context.Request.Files.Count;
context.Response.Write(UploadMultipleFiles());
}
Ajax Request
function sendFile(requestUrl, dataPayload, successfunc, errorfunc, synchronousMode) {
$.ajax({
url: requestUrl,
type: "POST",
dataType: "json",
contentType: false,
processData: false,
cache: false,
async: synchronousMode,
data: dataPayload,
success: successfunc,
error: errorfunc
});
}
Please Check .. where i m doing wrong
form tag having enctype="multipart/form-data" and each fileUPload control have uniue id and name attribute too
Thanks
You're sending a jQuery object, not a file ?
Shortened down, you're basically doing this
var kdata = new FormData();
var File = row.find('input[name*="file"]'); // jQuery object
kdata.append('file-0', File);
You need the files, not the jQuery objects
var kdata = new FormData();
var File = row.find('input[name*="file"]'); // jQuery object
var files = File.get(0).files[0]; // it not multiple
kdata.append('file-0', Files);

Categories

Resources