Send additional info to server in uploading image process - vue.js

im using filepond 4.25.1 on vue 2.6.11 and everything work without problem until now.
i want to send additional information to my server which is aspnet core 3. i send my request from filepond like below
myServer: {
url: "http://**********/api/CustomerAuth/",
process: {
url: "uploadimages",
method: "POST",
withCredentials: false,
headers: {},
data: {
nationalcode: "1234567890",
typecode:"1"
},
timeout: 7000,
},
load: (source, load) => {
fetch(source)
.then((res) => res.blob())
.then(load);
},
}
and server side
[HttpPost("uploadimages")]
public IActionResult UploadImages()
{
try
{
var file = Request.Form.Files[0];
string folderName = "Upload";
string webRootPath = _hostingEnvironment.WebRootPath;
string newPath = Path.Combine(webRootPath, folderName);
if (!Directory.Exists(newPath))
{
Directory.CreateDirectory(newPath);
}
if (file.Length > 0)
{
string fileName =
ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
string fullPath = Path.Combine(newPath, fileName);
using (var stream = new FileStream(fullPath, FileMode.Create))
{
file.CopyTo(stream);
}
}
return Ok("Upload Successful");
}
catch (System.Exception ex)
{
return NotFound(new { img_upld_error = ex.Message });
}
}
in server side i need to access "nationalcode" and "typecode" which is send as data in process and value of these two parameters always change so its not static value and with interact of user value of this two always change.
I really appreciated if someone give me a some clue or guide me to solve my problem.

FilePond dev here.
data does not exist as a prop on process.
You can add additional FormData parameters with the ondata property. See updated example below:
myServer: {
url: "http://**********/api/CustomerAuth/",
process: {
url: "uploadimages",
method: "POST",
withCredentials: false,
headers: {},
data: {
nationalcode: "1234567890",
typecode:"1"
},
ondata: (formData) => {
formData.append('nationalcode', '1234567890');
formData.append('typecode', '1');
return formData;
}
timeout: 7000,
},
load: (source, load) => {
fetch(source)
.then((res) => res.blob())
.then(load);
},
}
Alternatively you can use the filepond metadata plugin to add metadata to each file (this is automatically sent to the server).
https://pqina.nl/filepond/docs/patterns/plugins/file-metadata/
FilePond.setOptions({
fileMetadataObject: {
'nationalcode': '1234567890',
'typecode': '1'
}
})

You can get file's in model, define your model like this
public class FileWithDataModel
{
public IFormFile File { get; set; }
public string NationalCode { get; set; }
public string TypeCode { get; set; }
}
and controller method will be :
public async Task<IActionResult> UploadFileWithData(FileWithDataModel model)
{
var file = model.File;
//you can save this file...
var nCode = model.NationalCode; //can access data easy
//......
return Ok();
}
Microsoft suggest to use Async method especially for file processing and uploading
here is example of jquery client
var form = new FormData();
form.append("NationalCode", "12345678");
form.append("TypeCode", "1");
form.append("File", fileInput.files[0], "/path/to/file");
var settings = {
"url": "http://**********/api/CustomerAuth/",
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/x-www-form-urlencoded"
},
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form
};
$.ajax(settings).done(function (response) {
console.log(response);
});

Related

ASP.NET Core AJAX POST not returning error, however, not saving data

I am using a button OnClick event to try and save a record to a database using AJAX in ASP.NET Core. The function is not returning an error, however, the data is not being saved. I am just trying to test with hard coded data first. A record with AdapollingProjectProcessStatusId = 1 exists in the database.
function SendHtmlEditorValueToController(data) {
$.ajax({
type: 'POST',
url: '#Url.Action("AJAXPost", "LiveAdapollingProjectProcessStatus")',
contentType: "application/json",
data: JSON.stringify({ "id": 1, "status": 'test'}),
dataType: 'json',
success: () => {
console.log("value is sent");
},
error: (error) => {
console.log(JSON.stringify(error));
}
});
}
LiveAdapollingProjectProcessStatusController:
[HttpPost]
public JsonResult AJAXPost(int id, string status)
{
LiveAdapollingProjectProcessStatus processstatus = new LiveAdapollingProjectProcessStatus
{
AdapollingProjectProcessStatusId = id,
AdapollingProjectProcessStatus = status
};
//save it in database
return Json(processstatus);
}
LiveAdapollingProjectProcessStatus.cs:
namespace CPSPMO.Models.PMO
{
public partial class LiveAdapollingProjectProcessStatus
{
public int AdapollingProjectProcessStatusId { get; set; }
public string AdapollingProjectProcessStatus { get; set; }
}
}
Please let me know if you are able to help me with this AJAX Post.
Thanks
Not sure how do you store it to the database, but the way you pass parameter to backend by ajax should be like below:
function SendHtmlEditorValueToController(data) {
$.ajax({
type: 'POST',
url: '#Url.Action("AJAXPost", "LiveAdapollingProjectProcessStatus")',
//contentType: "application/json", //remove this...
data:{ "id": 1, "status": 'test'}, //modify here...
dataType: 'json',
success: () => {
console.log("value is sent");
},
error: (error) => {
console.log(JSON.stringify(error));
}
});
}
After reviewing the comments regarding missing code for saving the data in the database, I modified the controller:
[HttpPost]
public JsonResult AJAXPost(int id, string status)
{
LiveAdapollingProjectProcessStatus processstatus = new LiveAdapollingProjectProcessStatus
{
AdapollingProjectProcessStatusId = id,
AdapollingProjectProcessStatus = status
};
//save it in database
var result = _context.LiveAdapollingProjectProcessStatuses.Update(processstatus);
_context.SaveChanges();
return Json(processstatus);
}
It is saving the data to the database now. Thanks for the help

ReactNative: uploading image file to server using Axios is not working

I am building a mobile application using ReactNative. My app needs to upload image file to the server. I am using Axios for that. But the file is always empty on the server-side.
This is my code.
const makeMultipartFormDataRequest = async ({
path,
data = null,
headers = null
}) => {
let accessToken = await getAccessToken();
if (accessToken) {
if (headers == null) {
headers = {
'Authorization': `Bearer ${accessToken}`
}
} else {
headers.Authorization = `Bearer ${accessToken}`;
}
}
let formData = new FormData();
if (data) {
for (let prop in data) {
let field = null;
if (typeof data[prop] == "object" && data[prop]?.mime) {
field = {
uri: data[prop].uri,
name: data[prop].name,
type: data[prop].mime
}
} else {
field = data[prop];
}
// here image file is added proof_file field
formData.append(prop, field);
}
}
let url = config.apiEndpoint + path;
return axios.post(url, formData, {
headers: headers
});
}
As you see in the code, I put a comment where I put the file into the request. When I log the value in the console, I got this.
{"name": "IMG_0003.JPG", "type": "image/jpeg", "uri": "/Users/waihein/Library/Developer/CoreSimulator/Devices/ED2E89F7-F8C9-498E-9B80-41E13814A480/data/Containers/Data/Application/6AEBDAD9-A84C-4B33-95E5-0180F09B1AD5/tmp/react-native-image-crop-picker/E3B07A1B-B79D-43A0-A649-E05F8500783B.jpg"}
But the file is never sent in the request. What is wrong with my code and how can I fix it?
As you are sending form data you should specify that in the content type. Something like this,
headers: { "Content-Type": "multipart/form-data" }

I cannot find a way to update calendar events on mssql. Posting to my razor page does not work (400 error)

Code to update with a custom button in the calendar:
myCustomButton: {
text: 'Save Events',
click: () => {
var allevents = calendar.getEvents();
$.ajax({
type: 'POST',
contentType: 'application/json',
dataType: 'json',
data: allevents,
url: '/Wishes/Individual/Update',
headers: {
'RequestVerificationToken': '#antiforgery.GetAndStoreTokens(HttpContext).RequestToken'
},
success: function (response) {
alert: ('success');
},
failure: function (response) {
alert: ('failure');
}
});
}
},
According to your description and code, it seems that you'd like to post all events within FullCalendar to your Razor Page handler by making AJAX Post Request(s), and then save/update events on database.
To achieve the requirement, you can refer to the following example.
On JavaScript Client
customButtons: {
myCustomButton: {
text: 'Save Events',
click: function () {
var allevents = calendar.getEvents();
var events = [];
$.each(allevents, function (index, event) {
//console.log(event);
// include only expected data (such as title, start and end etc) in json object `newevent`
// instead of all information of calendar event
var newevent = { "title": event.title, "start": event.start, "end": event.end };
events.push(newevent);
});
$.ajax({
type: 'POST',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify(events),
url: '/Wishes/Individual/Update',
headers: {
'RequestVerificationToken': '#antiforgery.GetAndStoreTokens(HttpContext).RequestToken'
},
success: function (response) {
alert: ('success');
},
failure: function (response) {
alert: ('failure');
}
});
alert('clicked the custom button!');
}
}
},
Razor page handler method
public IActionResult OnPostUpdate([FromBody]List<Event> events)
{
//code logic here
return Content("ok");
}
Custom Event class
public class Event
{
public string title { get; set; }
public string start { get; set; }
public string end { get; set; }
// defind other properties
// such as groupId, url etc based on your requirements
}
Test Result

How do I send the JavaScript Array to the Controller from Ajax

Cannot get object values in the controller from the ajax post.
I have a jQuery data table with the first column being checkbox's and I need to return the selected row ids to the controller. I can get everything I need but it is always null in the controller.
Model:
public class Values
{
public Guid ID { get; set; }
}
View JS & Ajax on button click:
function SubAll() {
var values = [];
$('#timesheet').find('input[type="checkbox"]:checked').each(function (index, rowId) {
//this is the current checkbox
var temp = $(this).closest('tr').attr('id');
if (String(temp) === String("undefined")) {
//skip; it is the select all box
}
else {
//push to array
values.push(temp);
}
});
console.log(values);
var data = { ID: values };
console.log(data);
$.ajax({
url: "#Url.Action("ApproveAllTimesheets", "Admin")",
type: 'POST',
data: JSON.stringify(data),
dataType: 'json',
success: function (result) {
alert(result);
},
error: function (xhr, textStatus) {
if (xhr.status == 401) { alert("Session Expired!"); window.location = "/Account"; }
else {
alert('Content load failed!', "info");
}
}
});
};
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public void ApproveAllTimesheets(List<Values> value)
{}
On button click the array 'values' gets filled with the id if a box was selected (works fine), then it is turned into an object 'data' to match the method signature and model and stringify'd. When the breakpoint is hit on the controller method the values are never there. What am I missing?
**UPDATE:**
function SubAll() {
var values = [];
$('#timesheet').find('input[type="checkbox"]:checked').each(function (index, rowId) {
//this is the current checkbox
var temp = $(this).closest('tr').attr('id');
if (String(temp) === String("undefined")) {
//skip; it is the select all box
}
else {
//push to array
values.push({ Id: temp });
}
});
console.log(values);
$.ajax({
url: "/Admin/ApproveAllTimesheets",
type: "POST",
data: values,
dataType: "html",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (result) {
alert(result);
},
error: function (xhr, textStatus) {
if (xhr.status == 401) { alert("Session Expired!"); window.location = "/Account"; }
else {
alert('Content load failed!', "info");
}
}
});
};
**Method Signature:**
public IActionResult ApproveAllTimesheets( List<Value> values)
**Class**
public class Value
{
public Guid ID { get; set; }
}
UPDATE #3
Model:
public class Value
{
public string TimeId { get; set; }
}
Ajax:
function SubAll() {
//var selectedValues = $('#timesheet').DataTable().column(0).checkboxes.selected().toArray();
var dataJSON = { TimeId: "test" };
console.log(dataJSON);
$.ajax({
url: "/Admin/ApproveAllTimesheets",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(dataJSON),
success: function (result) {
alert(result);
},
error: function (xhr, textStatus) {
if (xhr.status == 401) { alert("Session Expired!"); window.location = "/Account"; }
else {
alert('Content load failed!', "info");
}
}
});
};
Controller:
public ActionResult ApproveAllTimesheets([FromBody]Value information)
You should insert the ids like javascript normal objects :
values.push({
ID: "d88b44e4-1009-47d6-9f2f-f675dca89fe8",
});
Code below is for your reference :
function SubAll() {
var values = [];
values.push({
ID: "d88b44e4-1009-47d6-9f2f-f675dca89fe6",
});
values.push({
ID: "d88b44e4-1009-47d6-9f2f-f675dca89fe7",
});
values.push({
ID: "d88b44e4-1009-47d6-9f2f-f675dca89fe8",
});
$.ajax({
type: "POST",
url: "/Admin/ApproveAllTimesheets",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(values),
success: function (result) {
alert(result);
},
error: function (xhr, textStatus) {
if (xhr.status == 401) { alert("Session Expired!"); window.location = "/Account"; }
else {
alert('Content load failed!', "info");
}
}
});
};
Controller :
public void ApproveAllTimesheets([FromBody]List<Values> value)
{
}
Model :
public class Values
{
public Guid ID { get; set; }
}
If this is your JSON
{ <-- This here is the start of your object
"id": 1;
}
This would need to get bound to a Model
class AnyModel {
public int Id {get; set;}
}
If you have a list in JSON
{
[
...Some objects
]
}
You would need to accept a model of in your controller
class AnyModel {
public List<SomeOtherModel> ListObject {get; set;}
}
Update
You want to store the list of 'Values' in another model.
class Value {
public Guid Id {get;set;}
}
class ValueContainer {
public List<Value> Values {get; set;}
}
Now you want to bind your JSON to your ValueContainer object. When you send JSON you need the [FromBody] for the JSON to get bound to your Model.
public IActionResult ApproveAllTimesheets([FromBody] ValueContainer values) {}
Update 2
Apologies looking through your JS code (old one) a little bit closer you should be using the following structure:
class ValueContainer {
public List<Guid> Id {get; set;}
}
List<Guid> is your values array which you bind to id in your JSON object. Controller stays the same.
public IActionResult ApproveAllTimesheets([FromBody] ValueContainer values) {}
So my Update #3 is working and now I have a different issue so I will post a new question for that.

CollectionFS/Meteor-CollectionFS uploading files of 0 bytes

I am trying to upload files to a dropbox app. Using the package CollectionFS/Meteor-CollectionFS with the cfs:dropbox adapter and my problem is that the files being uploaded is 0 bytes. I am not sure what I am missing or doing wrong here.
On server:
var registrationImageStorage = new FS.Store.Dropbox("registrationStorage", {
key: "****",
secret: "****",
token: "****",
transformWrite: function (fileObj, readStream, writeStream) {
gm(readStream, fileObj.name()).stream().pipe(writeStream);
}
});
RegistrationImages = new FS.Collection("registrations", {
stores: [registrationImageStorage],
filter: {
allow: {
contentTypes: ['image/*']
}
}
});
RegistrationImages.allow({
insert: function () {
return true;
},
update: function () {
return true;
}
});
On client:
var registrationImageStorage = new FS.Store.Dropbox("registrationStorage");
RegistrationImages = new FS.Collection("registrations", {
stores: [registrationImageStorage],
filter: {
allow: {
contentTypes: ['image/*']
}
}
});
On client to start the upload:
var file = new FS.File($('#badgeImage').get(0).files[0]);
RegistrationImages.insert(file, function (err, fileObj) {
if (err) {
console.log(err);
} else {
console.log(fileObj);
});
Ok, I did not need this part of the code and after removing it, it worked:
transformWrite: function (fileObj, readStream, writeStream) {
gm(readStream, fileObj.name()).stream().pipe(writeStream);
}