Calling C# method from javascript in MVC4 - c#

i'm trying to call a c# method from javascript but nothing works. What this have to do is that i call the javascript after user press enter, then i call the method in c#, the API try to find the city, then i show the temperature of the city that he typed. But i tried a lot of thing, but nothing worked.
the code:
My JavaScript:
function enterpressalert(e, textarea) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) { //Enter keycode
var tb = $('#search-bar').val();
$.ajax({
url: '#Url.Action("getWeather", "IndexController")',
type: 'GET',
dataType: 'text',
// we set cache: false because GET requests are often cached by browsers
// IE is particularly aggressive in that respect
cache: false,
data: { city: tb },
success: function () {
$('#search-bar').val() = 'funcionou';
}
});
}
}
My c# method that i'm trying to call:
[WebMethod]
public LocalWeather getWeather(string city)
{
LocalWeatherInput input = new LocalWeatherInput();
input.query = city;
input.num_of_days = "5";
input.format = "JSON";
FreeAPI api = new FreeAPI();
LocalWeather localWeather = api.GetLocalWeather(input);
return localWeather;
}
thanks.

Place a break point in getWeather() function and try this:
[HttpGet]
public LocalWeather getWeather(string city)
{
LocalWeatherInput input = new LocalWeatherInput();
input.query = city;
input.num_of_days = "5";
input.format = "JSON";
FreeAPI api = new FreeAPI();
LocalWeather localWeather = api.GetLocalWeather(input);
return localWeather;
}
and also check whether your are using url routing in global.asax

Related

I am trying to check that If email already exist in databse or not or not in database but my code throws error

This is the error I am getting in my console;
GET http://localhost:1089/api/Employee/EmailAlreadyExist?%22some#abc.com%22 404 (Not Found)
This my ajax code where I am sending the user email while creating a new user, and I want this method to let me know if the email already exist in database or not;
function CheckAvailability() {
var email = $("#officialemail").val();
$.ajax({
type: "GET",
url: 'http://localhost:1089/api/Employee/EmailAlreadyExist',
dataType: 'json',
contentType: "application/json",
data: JSON.stringify(email),
success: function (response) {
var message = $("#message");
if (response) {
//Email available.
message.css("color", "green");
message.html("Email is available");
}
else {
//Email not available.
message.css("color", "red");
message.html("Email is NOT available");
}
}
});
}
function ClearMessage() {
$("#message").html("");
};
and I am passing this entire function in another fucntion in which I am passing the email parameter in attempt of creating a new user along with all of the other parameters with their values;
$('.empOfficialDetails').click(function (ev) {
ev.preventDefault();
CheckAvailability()
var data = new Object();
data.UserName = $('#username').val();
data.UPassword = $('#userpass').val();
data.OfficialEmailAddress = $('#officialemail').val();
data.Departments = $('#departments :selected').text();
data.Designation = $('#designation :selected').text();
data.RoleID = $('#role').val();
data.Role = $('#role :selected').text();
data.ReportToID = $('#reportToID').val();
data.ReportTo = $('#reportTo :selected').text();
data.JoiningDate = $('#joindate').val();
data.IsAdmin = $('#isAdmin :selected').val() ? 1 : 0;
data.IsActive = $('#isActive :selected').val() ? 1 : 0;
data.IsPermanent = $('#isPermanent :selected').val() ? 1 : 0;
data.DateofPermanancy = $('#permanantdate').val();
data.HiredbyReference = $('#hiredbyRef :selected').val() ? 1 : 0;
data.HiredbyReferenceName = $('#refePersonName').val();
data.BasicSalary = $('#basicSalary').val();
data.CurrentPicURL = $('.picture').val();
if (data.UserName && data.UPassword && data.OfficialEmailAddress && data.Departments && data.Designation && data.Role && data.IsAdmin && data.IsPermanent) {
$.ajax({
url: 'http://localhost:1089/api/Employee/EmpOfficialDetails',
type: "POST",
dataType: 'json',
contentType: "application/json",
data: JSON.stringify(data),
beforeSend: function () {
$("#dvRoomsLoader").show();
},
complete: function () {
$("#dvRoomsLoader").hide();
},
success: function (data) {
var ID = parseInt(data);
if (ID > 0) {
//var id = data;
$(".HiddenID").val(data);
//var id = $(".HiddenID").val();
$('#official').css('display', 'block');
$('#official').html("Employees Official details added successfully...!");
$('#official').fadeOut(25000);
$("#dvRoomsLoader").show();
$('.empOfficialDetails').html("Update <i class='fa fa-angle-right rotate-icon'></i>");
}
else {
$('#official').find("alert alert-success").addClass("alert alert-danger").remove("alert alert-success");
}
},
error: function (ex) {
alert("There was an error while submitting employee data");
alert('Error' + ex.responseXML);
alert('Error' + ex.responseText);
alert('Error' + ex.responseJSON);
alert('Error' + ex.readyState);
alert('Error' + ex.statusText);
}
});
}
return false;
});
and in my controller I am using an inline query to check for similar email in my database;
[Route("api/Employee/EmailALreadyExist")]
[HttpGet]
public bool EmailAlreadyExist(string email)
{
string retval;
var con = DB.getDatabaseConnection();
Employee emp = new Employee();
string query = "IF EXISTS (SELECT 1 FROM Employee WHERE OfficialEmailAddress = #OfficialEmailAddress)";
SqlCommand com = new SqlCommand(query, con);
com.Parameters.AddWithValue("#OfficialEmailAddress", email);
email = emp.OfficialEmailAddress;
SqlDataReader rdr = com.ExecuteReader();
if (rdr.HasRows)
{
retval = "true";
}
else
{
retval = "false";
}
return Convert.ToBoolean(retval);
}
all of the help I get is highly appreciated and sugesttions for making this code better are all warmly welcomed
thank you
I can see that there is a typo in the route. The L in EmailALreadyExist is capitalized. But you are calling it with a lowercase letter.
Also, I am seeing a missing semicolon in the Ajax code, check that out too.
Your code uses a GET method that can't have a body. So it had to append an URL parameter to it. In ASP.NET it should be named. But your method has not named parameters. So it is not found. Add the parameter name to your payload (name "email"). to your JSON - replace in your JS function CheckAvailability data: JSON.stringify(email), with data: JSON.stringify({email: email}),. Then jQuery should call for api/Employee/EmailALreadyExist?email=.... that will match public bool EmailAlreadyExist(string email).
It is better to use a POST method to hide the email in the request body. Then your original code could have a C# smaller update:
public bool EmailAlreadyExist([FromBody]string email). It will map the single parameter from the body to the C# email variable.
There is a point to separate your logic from the controller. "Thin controller" could validate parameters, a service will contain your "business logic".
From your url
http://localhost:1089/api/Employee/EmailAlreadyExist?%22some#abc.com%22
it looks like you aren't passing email parameter correctly.
You can pass it like
http://localhost:1089/api/Employee/EmailAlreadyExist?email=some#abc.com
or change your route a bit to support your url
[Route("api/Employee/EmailAlreadyExist/{email}")]

Cannot pass data from JSONResult back to handler using ajax

I would like to have the following workflow:
Ajax call to page model handler to trigger database and creation of some viewmodels and return the result as JSONResult
Pass back the result of step 1 to another handler in order to reload a partial view
Between step 1 and 2 there is some data handling using JS. But this is out of scope, since the data is only read and not changed.
Step 1 is working fine. But step 2 does not. Here is a short code example:
Step 1:
Ajax:
var searchArea = parseFloat(document.getElementById('txtSearchArea').value);
var latitude = parseFloat(document.getElementById('hiddenLat').value);
var longitude = parseFloat(document.getElementById('hiddenLong').value);
var requestData = JSON.stringify({'latitude': latitude, 'longitude': longitude, 'searchArea': searchArea});
$.ajax({
type: "POST",
url: '#Request.Scheme://#Request.Host#Request.Path?handler=GetCompaniesWithinSearchArea',
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
contentType: "application/json; charset=utf-8",
dataType: "json",
data: requestData
}).fail(function (x) {
alert('Error fetching companies in search area.');
}).done(function (result) {
reloadSearchResultPartialView(result);
});
C#:
public async Task<JsonResult> OnPostGetCompaniesWithinSearchAreaAsync([FromBody] LatitudeLongitudeSearchArea latitudeLongitudeSearchArea)
{
var latitude = latitudeLongitudeSearchArea.Latitude;
var longitude = latitudeLongitudeSearchArea.Longitude;
var searchArea = latitudeLongitudeSearchArea.SearchArea;
var idsOfcompaniesInArea = await _companiesService.GetIdsOfCompaniesWithinSearchAreaAsync(latitude, longitude, searchArea));
var companyInSearchAreaVMs = await _companiesInSearchAreaViewModelFactory.Create(idsOfcompaniesInArea);
return new JsonResult(companyInSearchAreaVMs);
}
with _companiesInSearchAreaViewModelFactory.Create returning List<CompanyInSearchAreaViewModel>.
Step 2:
Normally I use the javascript load(...) method to invoke reloading of a partial view.
So I was trying to use this approach again.
JS:
function reloadSearchResultPartialView(searchResult) {
$('#divSearchResult').load('#Request.Scheme://#Request.Host#Request.Path?handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels=' + searchResult);
}
where searchResult is the response result of step 1. Data have not been changed between step 1 and 2.
C# - this is the handler for reloading the partial view.
public PartialViewResult OnGetReloadCompaniesInAreaList(List<CompanyInSearchAreaViewModel> companyInSearchAreaViewModels)
{
var result = new PartialViewResult
{
ViewName = "_CompaniesInAreaList",
ViewData = new ViewDataDictionary<IList<CompanyInSearchAreaViewModel>>(ViewData, companyInSearchAreaViewModels)
};
return result;
}
The handler for reloading the partial view is called, but the list of viewmodels is always an empty list.
Hopefully someone can point me in the right direction.
Thanks in advance!
Change this:
function reloadSearchResultPartialView(searchResult) {
$('#divSearchResult').load('#Request.Scheme://#Request.Host#Request.Path?handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels=' + searchResult);
}
to
function reloadSearchResultPartialView(searchResult) {
var arrStr = encodeURIComponent(JSON.stringify(searchResult));
$('#divSearchResult').load('#Request.Scheme://#Request.Host#Request.Path?handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels='+arrStr);
}
And in PageModel
public PartialViewResult OnGetReloadCompaniesInAreaList(List<CompanyInSearchAreaViewModel> companyInSearchAreaViewModels)
{
var result = new PartialViewResult
{
ViewName = "_CompaniesInAreaList",
ViewData = new ViewDataDictionary<IList<CompanyInSearchAreaViewModel>>(ViewData, companyInSearchAreaViewModels)
};
return result;
}
to
public PartialViewResult OnGetReloadCompaniesInAreaList(string companyInSearchAreaViewModels)
{
List<CompanyInSearchAreaViewModel> data = JsonConvert.DeserializeObject<List<CompanyInSearchAreaViewModel>>(companyInSearchAreaViewModels);
var result = new PartialViewResult
{
ViewName = "_CompaniesInAreaList",
ViewData = new ViewDataDictionary<IList<CompanyInSearchAreaViewModel>>(ViewData, data)
};
return result;
}
Why it happens
but the list of viewmodels is always an empty list.
That's because your server expects a querystring like this:
handler=ReloadCompaniesInAreaList
&[0].prop1= 11
&[0].prop2=12
...
&[1].prop1=21
&[1].prop2=22
...
However, by using
$('#divSearchResult').load('#Request.Scheme://#Request.Host#Request.Path?handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels=' + searchResult);
You're sending the querystring like:
handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels=[object
How to Fix
There're several ways to fix that problem.
The easiest way is to change the json array to a form-urlencoded string, for example, change your reloadSearchResultPartialView()function as below:
function reloadSearchResultPartialView(searchResult) {
//$('#divSearchResult').load('#Request.Scheme://#Request.Host#Request.Path?handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels=' + searchResult);
$('#divSearchResult').load('#Request.Path?handler=ReloadCompaniesInAreaList', $.param(createFormUrlEncodedPayload("",searchResult)));
}
// my helper function that recursively convert a plain js obj to a form-urlencoded string
function createFormUrlEncodedPayload(name,o){
var payload = {};
function _objectNotNull(value){ return value !== null && typeof value === "object"; }
function _create(prefix,obj) {
for(var prop in obj) {
if (obj.hasOwnProperty(prop)) {
var key =prefix?
(isNaN(prop)? key = prefix + "." + prop : key = prefix + ".[" + prop + "]") :
(isNaN(prop)? key = prop : key = "[" + prop + "]");
var value = obj[prop];
if(_objectNotNull(value))
_create(key, value);
else
payload[key]=value;
}
}
};
_create(name,o);
return payload;
}
Or as an alternative, you can make your server to receive HTTP POST request instead GET,
public PartialViewResult OnPostReloadCompaniesInAreaList([FormBody]List<CompanyInSearchAreaViewModel> companyInSearchAreaViewModels)
{
...
}
and then replace the $.load() to :
$.ajax({
url: '#Request.Path?handler=ReloadCompaniesInAreaList',
method:'POST',
contentType:"application/json",
data: searchResult,
success: function(resp){
$('#divSearchResult').html(resp)
},
});

Not able to consume my second web method in same web service

In continuation to my previous question Not able to consume my web service through jQuery / AJAX i'm facing the problem again. I have now two [WebMethod] in my web service file. First one is FormSubmit() which works fine now and second one is LoginOnClick This is my code:
[WebMethod]
public void LoginOnClick(agentLoginInfo agentLoginObject)
{
string agentID = "";
string agentPassword = "";
try
{
if (agentLoginObject != null)
{
agentID = agentLoginObject.agentID;
agentPassword = agentLoginObject.agentPassword;
}
else
{
Console.Write("No Data");
}
}
catch (Exception e)
{
Console.Write("Error :" + e.Message);
}
RequestBLObject.AgentID = agentLoginObject.agentID.Trim();
RequestBLObject.AgentPassword = agentLoginObject.agentPassword.Trim();
DataTable UserDetails = new DataTable();
UserDetails = BehaviourBLObject.ValidateUsernamePasswordBL(RequestBLObject);
}
This is the AJAX:
function Login() {
var agentLoginObject = {};
var ID = $("#AgentID").val();
var Password = $("#Password").val();
agentLoginObject.AgentID = ID;
agentLoginObject.AgentPassword = Password;
$.ajax({
method: 'POST',
url: 'http://arohar.com/Service.asmx/LoginOnClick',
data: "{agentLoginObject:" + JSON.stringify(agentLoginObject) + "}",
processData: false,
dataType: 'JSON',
success: function() {
alert("success");
},
error: function() {
alert("error");
}
});
}
Keeping in mind what mistakes i did last time, i tried my best but i ran into same problem again. Can anyone point out where i went wrong again this time?
UPDATE: I saw on my networks tab and this is what I get every time
System.InvalidOperationException: LoginOnClick Web Service method name is not valid.
at System.Web.Services.Protocols.HttpServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

Return a value from a WebMethod based on conditions provided in the WebMethod

I have a jQuery Ajax WebMethod call as shown below:
<script type="text/javascript">
$(document).ready(function () {
$("#btnsubmit").click(function () {
var arr = new Array();
arr.push($("#control1").val()); arr.push($("#control2").val()); arr.push($("#control13 option:selected").val()); arr.push($("#control4 option:selected").val()); arr.push($("#control15 option:selected").val());
var requestedData = JSON.stringify(arr);
requestedData = "{'details':'" + requestedData + "'}";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "EmployeeDemotion.aspx/Save",
data: requestedData,
dataType: "json",
success: function (result) {
//check the value returned from the WebMethod and provide alerts accordingly
},
error: function (result) {
alert("Error");
}
});
});
});
</script>
and, the WebMethod is as below:
[WebMethod(EnableSession = true)]
public static InsertDetails[] Save(string details)
{
DataTable dt = new DataTable(); DataTable dts = new DataTable();
List<InsertDetails> data = new List<InsertDetails>();
JavaScriptSerializer js = new JavaScriptSerializer();
string[] Tags = js.Deserialize<string[]>(details);
object[] obj = new object[8];
obj[0] = Tags[0].ToString(); obj[1] = Tags[1].ToString(); obj[2] = Tags[2].ToString(); obj[3] = Tags[3].ToString();
obj[4] = Tags[4].ToString();
int a = //say condition 1
int b = //say condition 2
if (a< b)
{
//insert into database and set a value which says the insertion has succeeded
}
else
{
//alert that data cannot be inserted
}
return data.ToArray();
}
Now I require a value of any possible type (boolean,array,string,integer or other) to be returned to the ajax method so that the success function in the ajax method alerts the status of insertion (as commented in te snippet) i.e; a value should be returned along with the last statement "return data.ToArray();" to the ajax method.
I do not require the element 'data' to be returned, the value which validates the insertion should be returned either along with 'data' or in any other form.
not sure what you want. Whether you want both the data and the flag to be returned to the client function or simply the flag.
Case 1 : all that you want is to return a message about the action that took place inside save
just change your save method like this
[WebMethod(EnableSession = true)]
public static string Save(string details)
{
string message =string.Empty;
/// rest of the usual code of yours
///
if (a< b)
{
//rest of the code
message = "Insertion Successful";
}
else
{
//rest of the code
message = "Error Occured";
}
}
and in your client side inside the ajax success, simple do this:
success: function (result) {
alert(result.d);
}
Case 2: you want to send data also in case insertion is successful
make a wrapper and append the data and the flag both to it. Serialize it and
then send it to the client side function. i.e
//wrapper class
public class ServiceResponse
{
public bool IsSuccess {get;set;}
public string Message {get;set;}
}
now inside your save do this:
[WebMethod(EnableSession = true)]
public static string Save(string details)
{
ServiceResponse serviceResponse =new ServiceResponse();
/// rest of the usual code of yours
///
if (a< b)
{
//rest of the code
serviceResponse.IsSuccess= true;
serviceResponse.Message = String.Join(",",data.ToArray());
}
else
{
//rest of the code
serviceResponse.IsSuccess = false;
}
return new JavaScriptSerializer().Serialize(serviceResponse);
}
and use it inside your client method like :
success: function (result) {
var jsonData = $.parseJSON(result.d);
if(jsonData.IsSuccess){
alert('success');
grid.data(jsonData.Message);
}
else{
alert('failure');
}
}

When invoked with a jQuery $.ajax, what to return from the Action Method if things go ok?

Here's my code:
[HttpPost]
public ActionResult VoteChampionStrongAgainst(string championStrong, string againstChampion)
{
int champStrongId = int.Parse(championStrong);
int againstChampId = int.Parse(againstChampion);
string ip = System.Web.HttpContext.Current.Request.UserHostAddress;
using (EfCounterPickRepository counterPickRepository = new EfCounterPickRepository())
{
var existingCounterPick = counterPickRepository.FindAll()
.SingleOrDefault(x => x.ChampionStrong == champStrongId && x.AgainstChampion == againstChampId);
//Does this counterpick combination already exist?
if (existingCounterPick != null)
{
//Has this user already voted?
var existingVote = counterPickRepository.FindVoteForUser(ip, existingCounterPick.CounterPickVoteId);
//He hasn't voted, add his vote history.
if (existingVote == null)
{
StrongCounterHistory history = new StrongCounterHistory();
history.IPAddress = ip;
history.VoteType = true;
history.StrongCounterPickVoteId = existingCounterPick.CounterPickVoteId;
counterPickRepository.AddStrongPickHistory(history);
counterPickRepository.SaveChanges();
//Add a total vote the pick.
existingCounterPick.TotalVotes++;
counterPickRepository.SaveChanges();
}
else
{
//Will use this to display an error message.
//How to return an "error" that jquery understands?
}
}
else //This combination doesn't exist. Create it.
{
//Create it....
StrongCounterPickVote newCounterPick = new StrongCounterPickVote();
newCounterPick.ChampionStrong = champStrongId;
newCounterPick.AgainstChampion = againstChampId;
newCounterPick.TotalVotes = 1;
counterPickRepository.CreateNewCounterPick(newCounterPick);
counterPickRepository.SaveChanges();
//Assign a vote history for that user.
StrongCounterHistory history = new StrongCounterHistory();
history.IPAddress = ip;
history.VoteType = true;
history.StrongCounterPickVoteId = newCounterPick.CounterPickVoteId;
counterPickRepository.AddStrongPickHistory(history);
counterPickRepository.SaveChanges();
}
return View();
}
}
Here's my jQuery code:
$(".pick .data .actions .btn-success").click(function () {
var champStrongId = $(this).data("champstrongid");
var againstChampId = $(this).data("againstchampid");
$.ajax({
type: 'POST',
url: "/Counterpicks/VoteChampionStrongAgainst",
data: { championStrong: champStrongId, againstChampion: againstChampId },
success: function () {
alert("Great success!");
},
error: function (e) {
alert("Something bad happened!");
console.log(e);
}
});
});
What do I need to return from my ActionMethod so the code execution enters success: if things went OK, or error: if things go wrong (for example, he already voted on this particular counter pick?
Servlet should answer a "200 OK" HTTP response.
Don't know about your 'View' api, but HttpServletResponse.setStatus(200) would do on the Java side. Don't forget, you can request the AJAX url manually in your browser to see what it is returning..
Here's some things I'd do...
public JsonResult VoteChampionStrongAgainst(string championStrong, string againstChampion) {
var success = true;
// Do all of your data stuff
return Json(new { success = success, error = 'Some error message'});
}
The JsonResult is a special ActionResult for returning Json. It automatically sets the correct headers for the browser. The Json() will use ASP.NET's built in serializer to serialize an anonymous object to return to the client.
Then with your jQuery code...
$.ajax({
type: 'POST',
url: "/Counterpicks/VoteChampionStrongAgainst",
data: { championStrong: champStrongId, againstChampion: againstChampId },
success: function (json) {
if (json.success) {
alert("Great success!");
}
else if(json.error && json.error.length) {
alert(json.error);
}
},
// This error is only for responses with codes other than a
// 200 back from the server.
error: function (e) {
alert("Something bad happened!");
console.log(e);
}
});
In order to have the error fire you'd have to return a different response code with Response.StatusCode = (int)HttpStatusCode.BadRequest;
You can return 500 internal server error if there are any errors on your server something like
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
Response.ContentType = "text/plain";
return Json(new { "internal error message"});

Categories