ASP.NET Calling Server Side Method from Client Side on keypress - javascript

To put it simply, I need a way for client side code to be able to trigger a server side method in my project. The way that I'm trying to use such functionality is when a user inputs their email address into a textbox, after each character is typed I want the project to trigger the method shown below which uses a class to query my database.
private void EmailCheck()
{
lblEmailError.Text = null;
Customer y = new Customer();
int counter = 0;
y.Email = Email.Text;
counter = y.CheckEmail();
if (counter.Equals(1))
{
lblEmailError.Text = "Email is already in use";
}
else
{
lblEmailError.Text = null;
}
}
I currently have almost no experience of any kind with JavaScript or any form of client side scripting. As I understand, AJAX may be of use to me here but again I am clueless about how I would implement it. I've also heard about onkeydown/press/up but again I am not sure how to alter online solutions to my specific need. Any help?

The most straightforward way would be to make a button in HTML5, use jQuery $.ajax() function to invoke a server side REST API (implementation could be anything C# Web API, Python Flask API, Node.JS API).
In your client side:
<label> Enter something into the textbox </label>
<input type = "text" id = "myTextBox" placeholder="Enter something"/>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script>
$(function(){
//On button click query the server
$("#myTextBox").change(function(){
var textBoxValue = $("#myTextBox).val();
var dataToBeSent = {
"data": textBoxValue
};
$.ajax(function(){
url: "http://localhost:9999/api/YourAPIName",
method: "POST",
data: JSON.stringify(dataToBeSent),
success: function(data){
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown){
console.log("Failed because" + errorThrown);
}
}); //end .ajax
}); //end click
}); //end jQuery
</script>
In your Server side (Assuming C#):
Make a model class, with properties the same name as the JSON key you constructed for the [FromBody] attribute to deserialize it correctly.
public class SomeModelClass
{
public string data { get; set; }
}
[HttpPost]
[Route("api/YourAPIName")]
public HttpResponseMessage YourMethod([FromBody] SomeModelClass modelClass)
{
//perform logic and return a HTTP response
}

Related

How Can I send Clients value in ASP.NET Controller?

I have written a code in c#, javascript, using client library SignalR to refresh a page in database value change. My code is
<form asp-action="Start" method="post" class="form-stacked">
<button type="submit" id="startPractice" class="button-primary">Start Practice</button>
</form>
<script src="~/js/ignalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>
My API method is which is called while clicking start practice is
public async Task<IActionResult> Index(long sessionId)
{
// Database change logic
SignalRClientHub sr = new SignalRClientHub();
await sr.SendMessage();
// Rest of the logic
return this.View();
}
public class SignalRClientHub : Hub
{
public async Task SendMessage(string user = null, string message = null)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
code of chat.js
"use strict";
var connection = new signalR.HubConnectionBuilder().withUrl("/SignalRClient").build();
connection.on("ReceiveMessage", function (user, message) {
location.reload();
});
When I click the button start practice it hits SendMessage Method, but I got an error
object reference not set to an instance
because the value of the Client was null. How Can I fix this?
You cannot new up a hub manually. In order to send to clients from outside of the hub you need to use the IHubContext<THub>. See the docs for details https://learn.microsoft.com/aspnet/core/signalr/hubcontext?view=aspnetcore-5.0

How to send value from jsp page to database without refreshing the page

I am developing a spring+hibernate webapp for practicing translation skill from Russian to English.
In one of my jsp pages I am retrieving all the questions from database and placing them into a table with the following columns: text in Russian, field for user's translation, button for checking the result. The goal is to save user's input into database without refreshing the page. How can I do it?
I tried several options, but none of them worked for me.
I used the solution from Send javascript variables to spring controller in my project, but nothing happened at all.
Part of "firstPage.jsp" ("/first" path in the controller):
<head>
<title>Title</title>
<script>
function searchViaAjax(id) {
var tempId = id;
alert("Start");
$.ajax({
type : "POST",
url : "./search/api/getSearchResult",
data : {id:tempId},
timeout : 100000,
success : function(id) {
alert("success");
console.log("SUCCESS: ", id);
display(id);
alert(response);
},
error : function(e) {
alert("error");
console.log("ERROR: ", e);
display(e);
},
done : function(e) {
alert("done");
console.log("DONE");
}
});
}
</script>
</head>
<body>
<button onclick="searchViaAjax(1)">Simple button</button>
</body>
Controller class:
#Controller
public class DemoController {
#RequestMapping("/first")
public String getFirst(){
return "firstPage";
}
#ResponseBody
#RequestMapping(value = "/search/api/getSearchResult", method=RequestMethod.POST)
public String getSearchResultViaAjax(#RequestParam("id") Integer id) {
System.out.println("come to ajax"+ id);
return "hello";
}
}
The "Start" message gets printed, but other messages from searchViaAjax() don't. And controller method doesn't start.
You can pass id in controller as it is no issue in your 'id', and also you can skip value attribute in #RequestParam.
#ResponseBody
#RequestMapping(value = "/search/api/getSearchResult")
public String getSearchResultViaAjax(#RequestParam("id") integer id) {
System.out.println("come to ajax"+ id);
return "hello";
}
Specify the methodType
#RequestMapping(value = "/search/api/getSearchResult", methodType=RequestMethod.POST)
It is also a good practice to use wrapper instead of primitive
#RequestParam("tempId") Integer id
the problem is in your ajax url attribute.
It should be url : "./search/api/getSearchResult",
Root Cause:
When you are about to hit your controller, it construct the url like this
http://localhost:8080/search/api/getSearchResult
and hence such resource is not available and it causes 404 not found error.
In actual the url should be
http://localhost:8080/contextroot/search/api/getSearchResult
here contextroot refers your project name.
Now if you hit url ./search/api/getSearchResult then ./ refers the base url i,e localhost:8080/contextroot and the entire url will be constructed properly.
I would like to recommend you to create global variable in JavaScript say baseUri and assign./ into it.
<script>
var baseUri="./";
</script>
In your AJAX it becomes
url : baseUri+"search/api/getSearchResult",
Hope this will help
The code from user9634982 was fine, thanks to him. The problem was because I was using slim jQuery version so my browser was giving me "$.ajax is not a function" error. And I didn't see it for hours because I didn't know where to look :facepalm: Thanks again to user9634982 for discovering browser inspector to me :D After replacing slim version to usual it still didn't work because of spring security. I added _csrf token and all worked fine.
.jsp:
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
<script>
function searchViaAjax(id) {
var csrfHeaderName = "X-CSRF-TOKEN";
var csrfTokenValue;
var metaTags = document.getElementsByTagName('meta');
for(var i = 0; i < metaTags.length; i++) {
var metaTagName = metaTags[i].getAttribute("name");
if(metaTagName === "_csrf_header")
csrfHeaderName = metaTags[i].getAttribute("content");
if(metaTagName === "_csrf")
csrfTokenValue = metaTags[i].getAttribute("content");
}
$.ajax({
type : "POST",
url : "./addAnsweredQuestion",
data : {id:id},
timeout : 100000,
beforeSend:function(xhr){xhr.setRequestHeader(csrfHeaderName, csrfTokenValue);},
success : function(id) {
alert("success");
console.log("SUCCESS: ", id);
display(id);
alert(response);
},
error : function(e) {
alert("error");
console.log("ERROR: ", e);
display(e);
},
done : function(e) {
alert("done");
console.log("DONE");
}
});
}
</script>
Controller:
#PostMapping(value = "/addAnsweredQuestion")
public void getSearchResultViaAjax(#RequestParam("id") Long id) {
System.out.println("come to ajax"+ id);
}

send/update integer to flask with Javascript

I created a website using flask with a running sqlite-db (SQLAlchemy). I want to send an integer with javascript to flask and back. I know AJAX can be used to accomplish that, but I don't know how to send the integer whenever my if/else-statement within my javascript game is met.
games.html
if (loc == unicornloc) {
money = 5000;
alert("\n\nBRAVO! You found the Unicorn! :)");
}else {
money = -250;
alert("The unicorn isn't here :(")
}
<FORM method="POST" name="searchb">
<input type=checkbox onClick="javascript:search('x1y1');">
<input type=checkbox onClick="javascript:search('x1y2');">
<input type=checkbox onClick="javascript:search('x1y3');">
games.py
#app.route('/games/<money>',methods=['GET'])
#login_required
def games(money):
print(request.args.get('money', type=int))
return render_template('games.html',money)
I want to get the money-value to flask, calculate a new value, pass it to my db and show the updated value on my website without reloading the page.
first set up jquery in your html.
make sure that the jquery is included in your head section of the html page:
You won't need to submit a form to update the server it is enough if you put a listener on one of your buttons that sends an ajax request every time it is clicked:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
var sendServerNotification = function(status){
var urlToCall = '/games/' + status;
$.ajax({
url : urlToCall, // the endpoint
type : "GET", // http method
// handle a successful response
success : function(parentDescriptions) {
console.log('success'); // log the returned json to the console
// update the page with jquery
},
// handle a non-successful response
error : function(xhr,errmsg,err) {
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
}
$( document ).ready(function() {
$('#obsevervedbutton').click(function{
//we read the value that the user wants to submit:
var valueToSubmit = $('#valueToSubmit').val()
// here you can check if you want to submit the value
// or not
if(true){
sendServerNotification(valueToSubmit);
}
});
});
</script>
</head>
<body>
<button id="obsevervedbutton">notify server</button>
<input id="valueToSubmit"></input>
</body>
and on your server side it is important to return a json response instaed of a normal http response to finish the ajax request and invoke either the success or error url:
def games(money):
print(request.args.get('money', type=int))
# update the database here
return json.dumps({"result":"operation successfull!"})
I hope this will get you going.

How to insert values into database from textbox and dropdownlist

I am not that good at either .net or sql.
The thing is I have a web form and a database. The form would let the user enter information in textbox and dropdownlist.
the data in the dropdownlist is saved in a table.
So, I am reading values from the table, when the users fill the form and choose from the dropdownlist the options they want, the data in the textbox and selected dropdownlist should be sent back to be saved in the database.
I have successfully read the value from the database and show them in the dropdownlist like in the following code:
public class state
{
public string stateID { get; set; }
public string stateName { get; set; }
}
[WebMethod]
public static List<state> PopulateDropDownList()
{
DataTable dt = new DataTable();
List<state> objDept = new List<state>();
SqlConnection con = new SqlConnection("Data Source = ****; Initial Catalog = LCF2016; Integrated Security = true");
{
using (SqlCommand cmd = new SqlCommand("SELECT STATE_ID, STATE_Name FROM state", con))
{
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
objDept.Add(new state
{
stateID = dt.Rows[i]["STATE_ID"].ToString(),
stateName = dt.Rows[i]["STATE_Name"].ToString()
});
}
}
return objDept;
}
}
}
<script src="
http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
//url is the path of our web method (Page name/functionname)
url: "Default.aspx/PopulateDropDownList",
data: "{}",
dataType: "json",
//called on jquery ajax call success
success: function (result) {
$('#ddlstate').empty();
$('#ddlstate').append("<option value='0'>-Select-</option>");
$.each(result.d, function (key, value) {
$("#ddlstate").append($("<option></option>").val(value.stateID).html(value.stateName));
});
},
//called on jquery ajax call failure
error: function ajaxError(result) {
alert(result.status + ' : ' + result.statusText);
}
});
});
</script>
<p>State</p>
<asp:DropDownList ID="ddlstate" runat="server" Width="160px" />
However, even if I am successfully calling the data to be shown into the dropdownlist, I am not able to insert the selected data along with the data in the textbox back into the database. In other word, the data is not saved into the database.
Here is my code for inserting the data "when click submit":
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack == true)
{
Label1.Text = ("**Thanks for entering your information");
}
}
protected void Button1_Click(object sender, EventArgs e)
{
using (SqlConnection vid = new SqlConnection("Data Source = ****; Initial Catalog = LCF2016; Integrated Security = true"))
{
vid.Open();
using (SqlCommand xp = new SqlCommand("insert into LCF2016 (Fname, Lname, Email, Birthdate, Phone, Address, City, STATE_ID, Zip, Country_ID, Days_Per_Month, Primary_Language, Secondary_Language, Occupation_ID, HearAbout_ID, Other_Skills) Values(#Fname, #Lname, #Email, #Birthdate, #Phone, #Address, #City, #STATE_ID, #Zip, #Country_ID, #Days_Per_Month, #Primary_Language, #Secondary_Language, #Occupation_ID, #HearAbout_ID #Other_Skills)", vid))
{
xp.Parameters.AddWithValue("#Fname", TextBox1.Text);
xp.Parameters.AddWithValue("#Lname", TextBox2.Text);
xp.Parameters.AddWithValue("#Email", TextBox3.Text);
xp.Parameters.AddWithValue("#Birthdate", TextBox4.Text);
xp.Parameters.AddWithValue("#Phone", TextBox5.Text);
xp.Parameters.AddWithValue("#Address", TextBox6.Text);
xp.Parameters.AddWithValue("#City", TextBox7.Text);
xp.Parameters.AddWithValue("#STATE_ID", ddlstate.SelectedValue);
xp.Parameters.AddWithValue("#Zip", TextBox8.Text);
xp.Parameters.AddWithValue("#country_ID", ddlcountry.SelectedValue);
xp.Parameters.AddWithValue("#Days_Per_Month", TextBox10.Text);
xp.Parameters.AddWithValue("#Primary_Language", ddllangp.SelectedValue);
xp.Parameters.AddWithValue("#Secondary_Language", ddllangs.SelectedValue);
xp.Parameters.AddWithValue("#Occupation_ID", ddloccup.SelectedValue);
xp.Parameters.AddWithValue("#HearAbout_ID", ddlhearabout.SelectedValue);
xp.Parameters.AddWithValue("#Other_Skills", TextBox15.Text);
xp.ExecuteNonQuery();
}
}
The error I get is
Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
try,
by jquery
$( "#ddlstate" ).change(function() {
$('[id*=Hiddenfield1]').attr('value', $( "#ddlstate" ).val());
});
body
<asp:HiddenField ID="Hiddenfield1" runat="server">
code
xp.Parameters.AddWithValue("#STATE_ID", Hiddenfield1.vlue);
Never having tried exactly what you are doing here, my best approximation is that the ViewState is invalid when you do your PostBack because you're using Ajax to populate the drop down list. It appears you are populating your drop down list using an Ajax call, then trying to use a full page post to send that data back to the server.You have several things going on here I don't quite understand, but what I would suggest is this.
I think you need to do a server side Request / Post, i.e. bind your drop down list and text box controls server side on the request, and then use the normal postback to send the data back to the server. OR, use AJAX both ways -receive AND send your data, but not try to mix them as you are.

Can I send a message instead of a view back as an ActionResult with ASP.NET MVC4

I have the following action in ASP.NET MVC4
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
// ?? Need some code here
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
I have the following code that calls this:
$('#article').on('submit', '#loginForm, #registerForm', function (e) {
e.preventDefault();
var $form = $(this);
var href= $form.attr('data-href');
$form.validate();
if (!$form.valid()) {
return false;
}
var data = $form.serializeArray();
$.ajax(
{
data: data,
type: 'POST',
url: href
})
.done(submitDone)
.fail(submitFail);
function submitDone(content) {
$('#article').html(content)
}
function submitFail() {
alert("Failed");
}
return false;
});
If the registration works I would like to force the whole web page to refresh. Is there
a way that I can send back a message from the actionmethod to the javascript to
tell it that the registration works and the javascript should refresh the whole
web page?
I did try return RedirectToLocal("/"); but this definitely does not work. What
this does is to return a new page and then have it populated in the #article DIV.
There is nothing that will automatically refresh the browser from the server.
To refresh the browser from the server you'll need to send something from the server to the client indicating that you want to refresh the page. You'll need to write the javascript to look for the indication to refresh the browser.
Client Code
function submitDone(content) {
var json = $.parseJson(content);
if(json.isSuccess) {
//Do something here
}
$('#article').html(json.content)
}
Server code
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
// ?? Need some code here
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return Json(new {isSuccess = true, content = model});
}
I am unsure of what you are trying to accomplish by refreshing the page, if it's to clear out the form fields. The same could be achieved by using JavaScript. By using javascript instead of a page refresh you won't lose page state, such as error messages.
well i can think of a quick javascript trick to refresh a page on success like this
function submitDone(content) {
window.location.reload();
}
this will reload the page on the success.

Categories