How to pass pdf file to Controller that requires IFormFile - asp.net-core

I've been working on this the whole day and did my research already, I can't seem to find a solution anywhere. I have this function that calls a List in my controller, the List needs a IFormFile parameter,
here's my javascript method
function fileUploader_uploaded(e) {
const file = e.file;
const fileReader = new FileReader();
fileReader.onload = function () {
toggleDropZoneActive($("#dropzone-external")[0], false);
$("#dropzone-item")[0].data = fileReader.result;
}
fileReader.readAsDataURL(file);
const _fileReader = new FileReader();
var r = _fileReader.readAsBinaryString(file);
$("#dropzone-text")[0].style.display = "none";
$.ajax({
url: '#Url.Action("_Index", "FileUploader")',
data: { CFile: r}, // I'm trying to pass the pdf file here
cache: false,
success: function (data) {
console.log(data);
}
});
}
and this is my List in controller
public object _Index(IFormFile CFile)
{
if (CFile != null)
{
try
{
string documentText = "";
using PdfDocumentProcessor documentProcessor = new PdfDocumentProcessor();
documentProcessor.LoadDocument(CFile.OpenReadStream());
documentText = documentProcessor.Text;
string word = #"([0-9]+.[0-9]+-[0-9]+)";
Regex regex = new Regex(word);
foreach (Match match in regex.Matches(documentText))
{
sectionsList.Add(match.Value.ToString());
}
}
catch
{
Response.StatusCode = 400;
}
}
else
{
_logger.LogInformation("empty");
}
return sectionsList;
}
the CFile is always empty i tried different ways already like passing
data: { CFile: e.file}
Does anyone else have idea?

From this code data: { CFile: e.file}, you post it as the string, so it can not be recognized as a file. You need to use FormData and change the contentType.
function fileUploader_uploaded(e) {
const file = e.file;
const fileReader = new FileReader();
fileReader.onload = function () {
toggleDropZoneActive($("#dropzone-external")[0], false);
$("#dropzone-item")[0].data = fileReader.result;
}
fileReader.readAsDataURL(file);
const _fileReader = new FileReader();
var r = _fileReader.readAsBinaryString(file);
$("#dropzone-text")[0].style.display = "none";
//----------edit here---------
var form = new FormData()
form.append('CFile', file)
$.ajax({
url: '#Url.Action("_Index", "FileUploader")',
method:'post',
data: form,
cache: false,
contentType: false,
processData: false,
success: function (data) {
}
});
}
The bakend should add [FromForm].
[HttpPost]
public object _Index([FromForm]IFormFile CFile)

Related

How can I pass JSON formatted data from View to controller action in ASP.NET Core MVC

I am new in.net core MVC. I want to send data from view to controller in JSON format.
I am creating dynamic table for saving data of data. post I want to send this newly added data controller.
Kindly see the logic and update me if anything I doing wrong or how can I achieve my aim.
I want to retrieve the values in SubmitExpense() method
Here is the javascript:
$(function () {
$('#btnSave').on('click', function () {
//alert('1111');
var ExpenseCliamViewModel = {};
var ExpenseClaimLineItems = new Array();
$("#myTable:eq(0) TR").each(function () {
var row = $(this);
var ExpenseClaimLineItem = {};
//ExpenseCliamViewModel.ExpenseClaimLineItem.
ExpenseClaimLineItem.LineItemTitle = row.find("TD").eq(1).html();
ExpenseClaimLineItem.LineItemDescription = row.find("TD").eq(2).html();
ExpenseClaimLineItem.ExpenseTypeName = row.find("TD").eq(3).html();
ExpenseClaimLineItem.LineItemAmount = row.find("TD").eq(4).html();
ExpenseClaimLineItem.LineItemClaimDate = row.find("TD").eq(5).html();
// alert(ExpenseClaimLineItem);
ExpenseClaimLineItems.push(ExpenseClaimLineItem);
});
ExpenseCliamViewModel.ExpenseClaimLineItem = ExpenseClaimLineItems;
ExpenseCliamViewModel.Title = $("#Title").val();
ExpenseCliamViewModel.Description = $("#Description").val();
ExpenseCliamViewModel.TotalAmount = $('#lblGrandTotal').html();
// ExpenseCliamViewModel.Title = $("#Title").val();
console.log(JSON.stringify(ExpenseCliamViewModel));
if (ExpenseCliamViewModel != null) {
$.ajax({
type: "POST",
url: "/Expense/SubmitExpense",
data: JSON.stringify(ExpenseCliamViewModel),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
if (response != null) {
alert('Sucess');
} else {
alert("Something went wrong");
}
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
}
else
alert('failed');
});
});
Here is the controller C# method:
[HttpPost]
public JsonResult SubmitExpense(ExpenseCliamViewModel expenseCliamViewModelData)
{
int insertedRecords = 1;
return Json(insertedRecords);
}
In your ajax, try :
$.ajax({
type:'POST',
url:"/Expense/SubmitExpense",
data:ExpenseCliamViewModel,
success:function(data){alert("success")},
error:function(){alert("error")}
});
Update:
Change your code $("#myTable:eq(0) TR") like below :
$("#myTable").find("tr:gt(0)").each(function () {
...
});
Result:

Future method calling api sometimes returns null sometimes not

In this method, the output is as follows:
I/flutter ( 2928): 200
I/flutter ( 2928): null
I/flutter ( 2928): [Instance of 'Images']
This is causing snapshot.data to be null in my FutureBuilder as well.Any Idea why is this happening?
Future<List<Images>> getData( File f ) async {
List<Images> list;
// String link = "https://clothest.herokuapp.com/";
String link ="https://us-central1-velvety-rookery-274308.cloudfunctions.net/function-1";
var stream = new http.ByteStream(DelegatingStream.typed(f.openRead()));
var length = await f.length();
var postUri = Uri.parse(link);
var request = new http.MultipartRequest("POST", postUri);
var multipartFileSign = new http.MultipartFile('File', stream, length,
filename: basename(f.path));
request.files.add(multipartFileSign);
request.headers.addAll({"content-type": "application/json"});
var response = await request.send();
print(response.statusCode); //200 OK
if (response.statusCode == 200){
response.stream.transform(utf8.decoder).listen((value) {
var data = json.decode(value);
var rest = data["Items"] as List;
list = rest.map<Images>((json) => Images.fromJson(json)).toList();
print(list.toString());
});
}
print(list.toString());
return list;
}
So I managed to solve this problem by using another package instead of the HTTP package. Dios package is the best regarding HTTP requests. Updated code:
Future<List<Images>> getData( File f ) async {
List<Images> lst=[];
String link ="https://us-central1-velvety-rookery-274308.cloudfunctions.net/function-1";
Dio dio = new Dio();
FormData formdata = new FormData(); // just like JS
formdata.add('File', new UploadFileInfo(f, basename(f.path)));
await dio.post(link, data: formdata, options: Options(
method: 'POST',
responseType: ResponseType.JSON // or ResponseType.JSON
)).then((response) {
print(response);
if(response.statusCode==200){ //OK
var responseBody = response.data; //Map
var rest = responseBody["Items"] as List;
//print(rest);
lst = rest.map<Images>((json) => Images.fromJson(json)).toList(); //instances of 'Images' object
//print(lst);
}
}
).catchError((error) => print(error));
return lst;

startRecording not working using RecordRTC with RTCMultiConnection

I am trying to record every new session/user added to RTCMultiConnection.
i am using the following demo url in application
https://rtcmulticonnection.herokuapp.com/demos/Audio+Video+TextChat+FileSharing.html
Now i have added the following cdn reference to the code.
https://cdn.webrtc-experiment.com/RecordRTC.js
and this is the code i am working with but connection.streams[event.streamid].startRecording(); is not working.
// ..................RTCMultiConnection Code.............
// ......................................................
var connection = new RTCMultiConnection();
var btnStopRec = document.getElementById("btnStopRecording");
connection.socketURL = 'https://rtcmulticonnection.herokuapp.com:443/';
connection.enableFileSharing = true;
connection.session = {
audio: true,
video: true,
data: true,
};
connection.sdpConstraints.mandatory = {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true,
};
connection.onstream = function (event)
{
document.body.appendChild(event.mediaElement);
console.log("stream recording starts")
connection.streams[event.streamid].startRecording();
console.log("stream recording started")
}
I included all possible situations in a single snippet, below. Please take only the code that you need:
// global object that contains multiple recorders
var recorders = {};
// auto start recorder as soon as stream starts/begins
connection.onstream = function(event) {
document.body.appendChild(event.mediaElement);
recorders[event.streamid] = RecordRTC(event.stream, {
type: 'video'
});
recorders[event.streamid].startRecording();
};
// auto stop recorder as soon as stream stops/ends
connection.onstreamended = function(event) {
if (recorders[event.streamid]) {
recorders[event.streamid].stopRecording(function() {
var blob = recorders[event.streamid].getBlob();
var url = URL.createObjectURL(blob);
window.open(url);
delete recorders[streamid]; // clear
});
}
if (event.mediaElement.parentNode) {
event.mediaElement.parentNode.removeChild(event.mediaElement);
}
};
// stop single recorder
document.getElementById('manually-stop-single-recording').onclick = function() {
var streamid = prompt('Enter streamid');
recorders[streamid].stopRecording(function() {
var blob = recorders[streamid].getBlob();
var url = URL.createObjectURL(blob);
window.open(url);
delete recorders[streamid]; // clear
});
};
// stop all recorders
document.getElementById('manually-stop-all-recordings').onclick = function() {
Object.keys(recorders).forEach(function(streamid) {
recorders[streamid].stopRecording(function() {
var blob = recorders[streamid].getBlob();
var url = URL.createObjectURL(blob);
window.open(url);
delete recorders[streamid]; // clear
});
});
};
// record outside onstream event
// i.e. start recording anytime manually
document.getElementById('record-stream-outside-the-onstream-event').onclick = function() {
var streamid = prompt('Enter streamid');
var stream = connection.streamEvents[streamid].stream;
recorders[streamid] = RecordRTC(stream, {
type: 'video'
});
recorders[streamid].startRecording();
};

Deferring a Dojo Deferred

I'm having a bit of a problem getting a deferred returned from a method in a widget. The method is itself returns a Deferred as it's an xhrPost. The code is as such (using dojo 1.8)
Calling Code:
quorum = registry.byId("quorumPanel");
var deferredResponse = quorum.updateSelectionCount();
deferredResponse.then(function(data){
console.log("Success: ", data);
}, function(err){
console.log("Error: ", err);
});
and the code in the widget:
updateSelectionCount: function() {
var self = this;
var deferredResponse = xhr.post({
url: "ajxclwrp.php",
content: [arguments here],
handleAs: "json"});
deferredResponse.then(function(response) {
var anotherDeferred = new Deferred();
var _boolA = true;
var _boolB = true;
dojo.forEach(response.result, function(relationshipInfo){
[do a bunch of stuff here too set _boolA and/or _boolB]
});
self._sethasRequiredAttr(_hasRequired);
self._setHasRequestedAttr(_hasRequested);
self.quorumInfo.innerHTML = quorumHtml;
// Below is not working
anotherDeferred.resolve('foo');
return anotherDeferred;
});
}
Do I need to set up another promise and use promise/all. Im confused/frustrated at this point.
TIA.
the .then() method returns another deferred. You just need to put a return statement in.
updateSelectionCount: function() {
var self = this;
var deferredResponse = xhr.post({
url: "ajxclwrp.php",
content: [arguments here],
handleAs: "json"});
return deferredResponse.then(function(response) {
var _boolA = true;
var _boolB = true;
dojo.forEach(response.result, function(relationshipInfo){
[do a bunch of stuff here too set _boolA and/or _boolB]
});
self._sethasRequiredAttr(_hasRequired);
self._setHasRequestedAttr(_hasRequested);
self.quorumInfo.innerHTML = quorumHtml;
return "foo";
});
}

dojo ItemFileReadStore.getValue mixed return value is not handled as string

I'am using dojo.data.ItemFileReadStore to query a json file with data. the main purpose is finding translations at Js level.
The Json data has "id" the word and "t" the translation
function translate(word)
{
var json = '/my/language/path/es.json';
var reader = new dojo.data.ItemFileReadStore({
url: json
});
var queryObj = {};
queryObj["id"] = word;
reader.fetch({
query: queryObj,
onComplete: function(items, request){
if (items.length > 0) {
var t = reader.getValue(items[0], 't');
if (dojo.isString(t)) {
return t;
}
}
return word;
},
onError: function(error, request){
return word;
}
});
}
The return value is always a undefined wether there is a translation or not. any ideas?
I tried typecasting with no success.
You can do it like this:
function translate(wordId) {
var translatedWord= wordId;
var store = new dojo.data.ItemFileReadStore({ data: storeData });
store.fetch({ query: { id: wordId },
onItem: function (item) {
translatedWord= (store.getValue(item, 't'));
}
});
return translatedWord;
}