Show progress of controller action in HTML as text - javascript

I am building .NET Core application and I want to change the text on the website based on the progress of controller actions. I wrote a short example below showing what I want to achieve. Some things are written in pseudo-code.
HomeController.cs
public class HomeController : Controller
{
private readonly IHomeService _homeService;
public HomeController(IHomeService homeService)
{
_homeService = homeService;
}
public IActionResult Detail(int id)
{
_homeService.ShowInfo(id);
return View(model);
}
HomeService.cs
public void FirstFunction()
{
// write "Fetching results from database"
...
// write "Results fetched successfully"
}
public void SecondFunction()
{
// write "Parsing results"
...
// write "Results parsed successfully"
}
public string ShowInfo(int id)
{
FirstFunction();
SecondFunction();
return "Success!";
}
functions.js
$(document).ready(function() {
$.ajax({
'url' : 'Home/Detail',
'type' : 'GET',
'data' : {
'id' : 123
},
'success' : function(data) {
// update some html element based on "write" commands in
// FirstFunction() and SecondFunction()
}
});
}
How can I update HTML elements on web page with strings which FirstFunction and SecondFunctions "write"? The operations are quite long and I want to give the user some sort of information about what is happening right now.

Related

How can I use c# asp.net to get data from url?

I'm trying to get some info I sent by form to angularJS in my c# asp.net backend, and I'm having trouble doing it.
Visual Studio won't let me compile because it says:
Error CS0120: an object reference is required for the nonstatic field, method, or property 'member'
That's is my controller
public class SearchController : ApiController
{
public string Get()
{
string test = HttpContext.Request.QueryString["txt_search"];
return test;
}
}
Here's what I got in my angularjs:
$scope.sendForm = function () {
console.log($scope.model.search);
$http({
method: 'GET',
url: '/api/search?txt_search=' + $scope.model.search
})
.then(function () {
console.log('sucesso a executar o post');
}, function () {
console.log('Erro ao executar o post');
});
};
As suggested in the comments, you should just be able to change your method definition and skip this altogether:
public string Get(string txt_search)
{
return txt_search;
}
Alternatively, to reference the current request, I believe you need to use the following (note the addition of .Current):
string test = HttpContext.Current.Request.QueryString["txt_search"];
The reason is that HttpContext defines Request as an instance property. The only public static property is Current, which returns an instance of HttpContext through which you can reach Request.
Welcome to Stack Overflow,
Your Angular code is correct
You need to pass a parameter on server side to collect txt_search value
Here it is:
[HttpGet]
[Route("/api/search")]
public string mySearchMethod(string txt_search)
{
//something here with txt_search
return "OK";
}
Both of the above solution will work, but for another approach as you are using asp.net web api and router you can make it as below as well
In your Angular code, simple pass the search as below
```
$scope.sendForm = function () {
console.log($scope.model.search);
$http({
method: 'GET',
url: '/api/search/'+ $scope.model.search
})
.then(function () {
console.log('sucesso a executar o post');
}, function () {
console.log('Erro ao executar o post');
});
};
```
Notice
url: '/api/search/'+ $scope.model.search
and change the Action method as below
```
[HttpGet]
[Route("/api/search/{txt_search}")]
public string mySearchMethod(string txt_search)
{
//something here with txt_search
return "OK";
}
```
by doing this you don't have to worry about the name of the parameter txt_search
whatever you mention in route [Route("/api/search/{txt_search}")], you will get the value in same parameter.

Laravel 500 Internal Server Error Ajax

I am developing a website using Laravel and Ajax. I have a problem when I try to return all messages (Messages model) that belong to specific user (User model) using hasMany method.
web.php
Route::get('/test', 'UserController#testFunction');
Route::post('/test', 'UserController#testFunction');
UserController.php
public function testFunction(Request $request) {
if ($request->isMethod('post')) {
$messages = User::find(1)->messages;
return $messages;
} else {
return 'get method';
}
}
User model
class User extends Authenticatable {
use Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function messages() {
$this->hasMany('App\Message', 'from');
}
}
Message model
class Message extends Model {
protected $fillable = [
'from', 'to', 'content'];
}
Then I have two buttons (just for testing - POST and GET). They are handled by this JavaScript code
window.onload = function() {
// AJAX Setup
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
// Post Method
$('#postMethod').click( function() {
$.post('test', function (data) {
console.log(data);
});
});
// Get Method
$('#getMethod').click(function() {
$.get('test', function(data) {
console.log(data);
});
});
}
Tables in the databse have a structure as shown below:
users table
messages table
When I click on POST button (handled by above javascript code), I receive this error in console: error in console
If I change $messages = User::find(1)->messages; to $messages = User::find(1)->name;, for example, I get the name of the user with ID 1 returned to the console normally.
I assume that something is wrong with messages() function in UserController.php. Maybe 'from' as foreign key? This is just my guess, maybe the error is somewhere else, please take a look yourself.
Here is your fix, you need to call messages like this messages() that will return relationship instance.
public function testFunction(Request $request) {
if ($request->isMethod('post')) {
$messages = User::find(1)->messages();
return $messages;
} else {
return 'get method';
}
}
Hope this helps.
test with /.
Try this
// Post Method
$('#postMethod').click( function() {
$.post('/test', function (data) {
console.log(data);
});
});
// Get Method
$('#getMethod').click(function() {
$.get('/test', function(data) {
console.log(data);
});
});

How to make requestbody controller works?

So actually everything is working well, except the fact that i can't get access to "inscrit" which is supposed to be the one which is sent to have the information user
This is my function in javascript and it does go into success for ajax.
function fbLogin() {
FB.login(function (response) {
if (response.authResponse) {
var inscrit = {
"prenom": response.first_name,
"nom": response.last_name,
"email": response.email
}
$.ajax({
method: 'post',
url: '/hello/facebookconnection',
contentType : 'application/json; charset=utf-8',
data: JSON.stringify(inscrit),
datatype: "json",
success: function() {
window.alert('User data sent');}
,
error: function(){
window.alert('Error in sending ajax data');}
});
} else {
document.getElementById('status').innerHTML = 'User cancelled login or did not fully authorize.';
}
}, {scope: 'email'});
}
And this is my java controller (whatever i do, the "inscrit.getEmail()" is always null)
#RequestMapping(value = "/facebookconnection", method = RequestMethod.POST)
#ResponseBody public void createUser(#RequestBody inscrit inscrit, ModelMap model) throws Exception {
//System.out.println(inscrit.getNom());
//System.out.println(inscrit.getPrenom());
System.out.println(inscrit.getEmail());
try {
user.adduser(inscrit);
} catch (Exception e) {
e.printStackTrace();
}
}
This is my inscrit class with all the getter and setter correctly set (i know that there's no problem with it)
#Entity
#Table(name="inscrit")
public class inscrit implements Serializable {
#Id
#Column(name="email")
private String email;
#Column(name="nom")
private String nom;
#Column(name="prenom")
private String prenom;
}
So i would like to know if someone could help me understand why it's not working in my controller (how to do so the data is sent properly from the ajax to the controller) :(
Thx !
EDIT : i did write the answer of that question below. The problem was the fact that response.first_name was really blank... and had to pass through the function userdata() which had the real informations. So that means i don't have any real error in my code, all the informations between the controller and my jsp page works correctly. Be free to use it as an example of how this works
#ResponseBody public void createUser(#RequestParam(value="inscrit") String inscrit) throws Exception {
//System.out.println(inscrit.getNom());
//System.out.println(inscrit.getPrenom());
Inscrit ins = JSON.parseObject(inscrit, Inscrit.class);
System.out.println(ins.getEmail());
try {
user.adduser(ins);
} catch (Exception e) {
e.printStackTrace();
} }
The class of inscrit.java is nonstandard.You should change it to Inscrit.java.
I hope this helps.
I'll answer to my own question since i found the answer, So this is for people who tries to have a facebook api and want to get informations of the profil to put into database.
My error was the fact that i thought response in login was the same asthe UserData(), which is not the case... So that's how i was supposed to do it.
function fbLogin() {
FB.login(function (response) {
if (response.authResponse) {
// Get and display the user profile data
getFbUserData();
} else {
document.getElementById('status').innerHTML = 'User cancelled login or did not fully authorize.';
}
}, {scope: 'email'});
}
// Fetch the user profile data from facebook
function getFbUserData(){
FB.api('/me', {locale: 'en_US', fields: 'id,first_name,last_name,email,link,gender,locale,picture'},
function (response) {
/*document.getElementById('fbLink').setAttribute("onclick","fbLogout()");
document.getElementById('fbLink').innerHTML = 'Logout from Facebook';
document.getElementById('status').innerHTML = 'Thanks for logging in, ' + response.first_name + '!';
document.getElementById('userData').innerHTML = '<div class="fbprofile"><p><b>FB ID:</b> '+response.id+'</p><p><b>Name:</b> '+response.first_name+' '+response.last_name+'</p><p><b>Email:</b> '+response.email+'</p><p><b>Gender:</b> '+response.gender+'</p><p><b>Locale:</b> '+response.locale+'</p></div><p><b>Picture:</b> <img src="'+response.picture.data.url+'"/></p>';*/
var inscrit = {
"prenom": response.first_name,
"nom": response.last_name,
"password": "1234",
"status": 0,
"email": response.email
}
$.ajax({
method: 'post',
url: '/hello/facebookconnection',
contentType : 'application/json; charset=utf-8',
data: JSON.stringify(inscrit),
datatype: "json",
success: function() {
document.location.href = "accueilmember";
},
error: function(){
window.alert('Error in sending ajax data');}
});
});
}
This is my controller class.This just logs the post request send to the server:(You may modify this if you need something more like adding a Response Body)
#RestController
public class EmailController {
#RequestMapping(value = "/facebookconnection", method = RequestMethod.POST)
public void createUser(#RequestBody inscrit inscrit) throws Exception {
System.out.println(inscrit.getNom());
System.out.println(inscrit.getPrenom());
System.out.println(inscrit.getEmail());
}
This is my inscrit.java class(I personally think naming the class would not affect but better follow standard naming Practices like Inscrit.java)
import java.io.Serializable;
public class inscrit implements Serializable {
private static final long serialVersionUID = -8445943548965154778L;
private String email;
private String prenom;
private String nom;
public inscrit() {
super();
}
public inscrit(String email,String prenom,String nom) {
this.setEmail(email);
this.setPrenom(prenom);
this.setNom(nom);
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
}
I did a post request from Advanced Rest Client and set the payload as
{
"email":"agdfae#gmail.com",
"prenom":"qewrwe",
"nom":"qwer"
}
the results were
qwer
qewrwe
agdfae#gmail.com
You can modify this to suit your own needs.Hope this helps
EDIT:
You will need more two classes in spring boot as below:
ServletInitializer.java
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(PostDataApplication.class);
}
}
PostDataApplication .java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class PostDataApplication {
public static void main(String[] args) {
SpringApplication.run(PostDataApplication.class, args);
}
}
PostDataApplication is the name of the application.
These four classes will do the trick (with pom.xml only no other xml configuration needed since this is springboot).Let me know if you have any problem.

Posting to ASP.NET WebApi server from AngularJS client

I'm trying to post strings from an AngularJS application (using $http) to a server built on ASP.NET WebApi, but I get 404 as soon as I add a parameter.
The client code is this
$scope.add = function () {
// ...cut...
$http({ method: "POST", url: url, data: { fileString: "test string" }}).then(
function successCallback(response) {
$log.info(response.data);
}
);
}
The server code is
[HttpPost]
public IHttpActionResult UploadExcel(string fileString) {
// cut
}
I get a 404, but if I remove the parameter on server side it works, so i can use a server side code like this
[HttpPost]
public IHttpActionResult UploadExcel() {
// cut
}
What is wrong? Should I pass the data in a different way? I tried different combination but I can't get it work.
What you want to do is send a string, not a JSON object as you are doing right now with { fileString: "test string" }. When I want to send a string, what I normally do is that I send data from Angular like this:
$http.post("/Search/QuickSearch?searchQuery="+ searchString);
And my controller I make ready to receive a string like this:
[HttpPost]
public IHttpActionResult QuickSearch(string searchQuery)
{
// cut
}
If I want to send a JSON object, I tell my controller what it should expect, like this:
[HttpPost]
public IHttpActionResult SaveActivity(ActivityEditForm form);
{
// cut
}
public class ActivityEditForm
{
public int? Id { get; set; }
[Required]
public string Title { get; set; }
public string Description { get; set; }
}
And then send my JSON from Angular like this:
$http.post("/Activity/SaveActivity", { form: activity });
I suggest you should capture the request send by Angular. By default, Angular send parameters in a json string in request body.
I'm not sure wether Asp.net can parse them from json string in body.
So, you can try to add the below codes (also need jQuery)
angular.module('yourApp').config(function ($httpProvider) {
$httpProvider.defaults.transformRequest = function(data){
if (data === undefined) {
return data;
}
return $.param(data);
}
});
The first error is in the controller, [FromBody] should be used with the input parameter.
public IHttpActionResult UploadExcel([FromBody]string fileString)
Then the data variable on the client should be a single string, so
$http({ method: "POST", url: url, data: "test string" }).then(
Anyway I found some issue with this solution later, it seems the simplest but I suggest to avoid it.
Best solution
Thank to #Squazz answer and this SO answer I strongly suggest a change in the webapi controller, client was correct. Just introduce a class to handle a single string and adapt the input parameter
// new class with a single string
public class InputData {
public string fileString { get; set; }
}
// new controller
[HttpPost]
public IHttpActionResult UploadExcel([FromBody] InputData myInput) {
string fileString = myInput.fileString;
// cut
}
This way JSON code from the client is automatically parsed and it's easy to change the data input.
Extra tip
$scope.add angular function was correct as in the question, but here is a more complete example
$scope.testDelete = function () {
var url = "http://localhost/yourAppLink/yourControllerName/UploadExcel";
var data = ({ fileString: "yourStringHere" });
$http({ method: "POST", url: url, data: data }).then(
function successCallback(response) {
console.log("done, here is the answer: ", response.data);
}, function errorCallback(response) {
console.log("an error occurred");
}
);
}

Send JS object to C# Controller using Ajax

I am trying to send multiple objects in js to a controller in C# using an Ajax call.
I have a object in C# called "Person"
which is the next :
public class Person
{
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
and I have the same object In JavaScript.
Then create two persons and I send to the controller.
This is the Ajax call
$.ajax({
url: baseUrl + "/controller/TestPeople",
type: "POST",
data: {
people: people
},
success: function (resp) {
alert("ok");
}
});
This is the post
people[0][Title]:"Mr."
people[0][FirstName]:"fname1"
people[0][LastName]:"Lname1"
people[0][Age]:23
people[1][Title]:"Mr."
people[1][FirstName]:"fname2"
people[1][LastName]:"Lname2"
people[1][Age]:25
but when i receive it in the controller, everything is null
public string TestPeople(Person[] people){
//some code
}
the controller knows that there are 2 people but all the information inside is null.
Any idea why?
To "solve" the problem i change the controller to use FormCollection and it is working, but i would like to know why the other is not working.
Thanks for all.
Try with:
data : JSON.stringify(peopleArray)
In your controller try:
public string Get(Person[] people){
//some code
}

Categories