How to call api from ASP.NET razor view - c#

Just as stated above, I am not sure how to call an API.
I have done it using fetch in the example below:
fetch("https://localhost:5001/api/patients/add", {
method: "POST",
mode: "cors",
cache: "no-cache",
headers: { "Content-Type": "application/json" },
body: postBody
});}
But it seems there is a different way of doing things in Razor view.
Below is what I have in my API:
// GET: api/Patients/5
[HttpGet("{id}")]
public async Task<ActionResult<Patient>> GetPatient(int id)
{
var patient = await _context.Patient.FindAsync(id);
if (patient == null)
{
return NotFound();
}
return patient;
}
It's just the GET made when creating an API in Visual Studio.

The following ajax call, within a script tag inside the razor page - although this is not best practice - would work as follows:
$.ajax({
type: "GET",
url: "#Url.Action("GetPatient", "Patients")",
data: { id : 1234 },
success: function(result){
//do something with result here
alert(result);
}
});
The second parameter of Url.Action is the Controller Name. This may need to be adapted for yourself.

This is what I ended up doing that worked. Thanks for the help guys!
$(document).ready(function () {
var options = {};
options.url = "https://localhost:44381/api/States";
options.type = "GET";
options.dataType = "json";
options.success = function (states) {
states.forEach(function (state) {
$("#state").append("<option>" + state.stateName + "</option>"
)
});
};
options.error = function () {
$("#msg").html("Error while calling the Web API!");
};
$.ajax(options);
});

Related

C# & ASP.NET MVC : call a view with ajax call

I want to call a view with an ajax call on my current view. The following is my Ajax call that calls a function of my controller.
$.ajax({
type: 'POST',
url: '#Url.Action("EditCertificateObservation", "Frühwarnsystem")',
data: {
serverName: '#Model[0].ServerName',
name: event.data.name,
thumbprint: event.data.thumbprint,
expiringDateStr: event.data.expiringDate,
isChecked: document.getElementById(store + event.data.index).checked,
model: data,
},
});
This code is my controller function that returns a view to load.
[HttpPost]
public ActionResult EditCertificateObservation(string serverName, string name, string thumbprint, string expiringDateStr, bool isChecked, string model)
{
var newModel = JsonConvert.DeserializeObject<List<Store>>(model);
var cert = new Certificate(serverName, name, thumbprint, expiringDateStr);
var server = new Server(serverName);
server.FetchIdByServerName();
if (isChecked)
{
cert.AddToObservation(server.Id);
}
else
{
cert.DeleteFromObservation();
}
return View("Index");
}
To know for you: I call the ajax call with a checkbox on my view, which is dynamically generated. If I debug the controller function get called and runs but the browser doesn't load the view I return.
If you need more information, just ask here.
Thank you for your help
If you want to open a view with after Ajax request than you just have to wait for the response of your controller then you can use success, but you can also use failure or error depend on your need, so your Ajax will be like this:
$.ajax({
type: 'POST',
url: '#Url.Action("EditCertificateObservation", "Frühwarnsystem")',
data: {
serverName: '#Model[0].ServerName',
name: event.data.name,
thumbprint: event.data.thumbprint,
expiringDateStr: event.data.expiringDate,
isChecked: document.getElementById(store + event.data.index).checked,
model: data,
},
success: function (response) {
alert(response.message);
window.location.href = "/Frühwarnsystem/Index";
// or with some parameter
window.location.href ="/Frühwarnsystem/Index?id=" + response.counter;
// or if you prefer with helper ...
window.location.href = '#Url.Action("Frühwarnsystem","Index")';
},
failure: function (response) { alert("failure"); },
error: function (response) { alert("error"); }
});
And to be a little more useful, your controller can send a Json response with some parameter for example, as follow:
[HttpPost]
public JsonResult EditCertificateObservation(string serverName, string name, string thumbprint, string expiringDateStr, bool isChecked, string model)
{
var newModel = JsonConvert.DeserializeObject<List<Store>>(model);
var cert = new Certificate(serverName, name, thumbprint, expiringDateStr);
var server = new Server(serverName);
server.FetchIdByServerName();
if (isChecked)
{
cert.AddToObservation(server.Id);
}
else
{
cert.DeleteFromObservation();
}
// Do some condition here to send an answer ...
string message = "";
int counter = 0;
var response = new { counter, message };
return Json(response);
}
You are calling an ajax POST HTTP request. It means you can download the result of the call and assign it into a javascript variable. This result will not be displayed in the browser as a page. Take a look at examples of $.post here.

Posting AJAX string to MVC Controller

I am trying to post a string (the name of the href the user clicked on) using AJAX to my MVC controller (which it will then use to filter my table results according to the string).
Whilst I have managed to get it to post (at-least according to the alerts) on the AJAX side, it doesn't seem to arrive properly on the controller side and is seen as null in my quick error capture (the if statement).
Please excuse the useless naming conventions for the moment. I've been going through countless methods to try and fix this, so will name properly when I've got a proper solution :).
I've been at work for this for a long while now and can't seem to solve the conundrum so any help is appreciated please! I'm very new to AJAX and MVC in general so I'm hoping it's a minor mistake. :) (FYI I have tried both post and get and both seem to yield the same result?)
Controller:
[Authorize]
[HttpGet]
public ActionResult GetSafeItems(string yarp)
{
using (CBREntities2 dc = new CBREntities2())
{
if (yarp == null)
{
ViewBag.safeselected = yarp;
}
var safeItem = dc.Items.Where(a => a.Safe_ID == yarp).Select(s => new {
Serial_Number = s.Serial_Number,
Safe_ID = s.Safe_ID,
Date_of_Entry = s.Date_of_Entry,
Title_subject = s.Title_subject,
Document_Type = s.Document_Type,
Sender_of_Originator = s.Sender_of_Originator,
Reference_Number = s.Reference_Number,
Protective_Marking = s.Protective_Marking,
Number_recieved_produced = s.Number_recieved_produced,
copy_number = s.copy_number,
Status = s.Status,
Same_day_Loan = s.Same_day_Loan
}).ToList();
// var safeItems = dc.Items.Where(a => a.Safe_ID).Select(s => new { Safe_ID = s.Safe_ID, Department_ID = s.Department_ID, User_ID = s.User_ID }).ToList();
return Json(new { data = safeItem }, JsonRequestBehavior.AllowGet);
}
}
AJAX function (on View page):
$('.tablecontainer').on('click', 'a.safeLink', function (e) {
e.preventDefault();
var yarp = $(this).attr('safesel');
var selectedSafeZZ = JSON.stringify("SEC-1000");
$.ajax({
url: '/Home/GetSafeItems',
data: { 'yarp': JSON.stringify(yarp) },
type: "GET",
success: function (data) {
alert(yarp);
console.log("We WIN " + data)
},
error: function (xhr) {
alert("Boohooo");
}
});
})
** The Alert reveals the correct type: "SEC-1000"
But the console Log shows: WE WIN [Object object]??
I have tried something basic in a new mvc dummy project :
View page basic textbox and a button :
<input type="text" id="txt_test" value="test"/>
<button type="button" class="btn" onclick="test()">Test</button>
<script type="text/javascript">
function test()
{
var text = $("#txt_test")[0].value;
$.ajax({
url: '#Url.RouteUrl(new{ action="GetSafeItems", controller="Home"})',
// edit
// data: {yarp: JSON.stringify(text)},
data: {yarp: text},
type: 'GET',
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function(data) {
// edit
// alert(JSON.stringify(data));
alert(data.data);
}});
}
</script>
Controller :
[HttpGet]
public ActionResult GetSafeItems(string yarp)
{
return Json(new {data = string.Format("Back end return : {0}",yarp)}
, JsonRequestBehavior.AllowGet);
}
Alert result => {"data":"Back end return : \"test\""}
It's a simple ajax call to a web method. You don't return a view, so I don't understand the use of
if (yarp == null)
{
ViewBag.safeselected = yarp;
}
Also I see an [Authorize] attribute, you perhaps use some authentication and I don't see any authentication header on your ajax call
Try this:
$.each(data, function (i) { console.log("We WIN " + data[i].Serial_Number )});

ajax request to razor page using handler

I am trying to get data from Active.cshtml.cs file using ajax call.
Here is the jquery code:
var turl = '/Active?handler=Clients/' + id;
$.ajax({
type: "GET",
url: turl,
dataType: "json",
success: function (result) {
alert(JSON.stringify(result));
});
Here is Active.cshtml.cs method
public JsonResult OnGetClients()
{
return new JsonResult("new result");
}
The status is 200 Ok, but it shows the entire webpage in response. Ideally it should return "new result" in Network tab of developer tools. Is it that I have Active.cshtml and Active.cshtml.cs in Pages that creates the confusion? How can I resolve it?
Thanks
For razor pages, you should be passing the parameter value(s) for your handler method in querystring.
This should work.
yourSiteBaseUrl/Index?handler=Clients&53
Assuming your OnGetClients has an id parameter.
public JsonResult OnGetClients(int id)
{
return new JsonResult("new result:"+id);
}
So your ajax code should look something like this
var id = 53;
var turl = '/Index?handler=Clients&id=' + id;
$.ajax({
type: "GET",
url: turl,
success: function (result) {
console.log(result);
}
});

How can I update the Database on a checkbox change in MVC

I am trying to update my database when a checkbox is checked or unchecked. I want it to update when the checkbox is clicked. This is what I have so far, but my controller is never being hit. what can I do to fix it? Ideally I want to pass in the new value of customer.IsDone and customer.Id to my controller but I don't know how to do this.
Checkbox in my view
<td>#Html.CheckBoxFor(m => customer.IsDone, new { onclick = "UpdateCustomer(IsDone)" })</td>
The function in my view
function UpdateCustomer(isDone) {
$.ajax({
type: 'POST',
url: #Url.Action("UpdateCustomer", "Home"),
data: { check: isDone },
success: success,
dataType: 'json'
});
}
this is my controller method
[HttpPost]
public ActionResult UpdateCustomer(bool check)
{
//code will be here to update the db
var customers = new CustomerGetAll();
var list = customers.Execute();
return View("Customers", list);
}
I see few issues in your code.
First of all, you are passing IsDone variable when calling the UpdateCustomer method. But where is isDone defined ?
Second, this line,
url: #Url.Action("UpdateCustomer", "Home"),
The Url.Action helper will output a string and your code will be like this when rendered in the browser
url: /Home/UpdateCustomer,
Now the browser's javascript framework usually thinks the second part after : as a js variable and if you have not defined it,it will throw a syntax error about using a not defined variable! But since we have \, you will get another "Invalid regular expression flags" syntax error!
You should wrap the result in quotes to avoid this problem.
The below code should work
#Html.CheckBoxFor(m =>customer.IsDone, new { onclick = "UpdateCustomer(this)" })
and the script
function UpdateCustomer(elem) {
var isDone = $(elem).is(':checked');
$.ajax({
type: 'POST',
url: "#Url.Action("UpdateCustomer", "Home")",
data: { check: isDone },
success: function(res) {
console.log(res);
},
dataType: 'json'
});
}
Also, If you want to update a specific customer record, you probably want to pass the customer Id as well when making the ajax call. You may keep that in html 5 data attribute on the checkbox markup and read that and use that as needed.
#Html.CheckBoxFor(m =>customer.IsDone, new { onclick = "UpdateCustomer(this)",
data_customerid = customer.Id })
This will render the checkbox with html5 data attribute for "data-customerid". All you have to now do is, read this value and send it via ajax
function UpdateCustomer(elem) {
var isDone = $(elem).is(':checked');
var cid = $(elem).data('customerid');
$.ajax({
type: 'POST',
url: '#Url.Action("UpdateCustomer", "Home")',
data: { check: isDone,customerId:cid },
success: function(res) {
console.log(res);
}
});
}
Make sure your server action method has a new parameter to accept the customer id we are sending from client side code
[HttpPost]
public ActionResult UpdateCustomer(bool check,int customerId)
{
// to do : Save and return something
}
I have something similar, and I think you can solve your problem...
My HTML
<td>
#{
bool avalia1 = false;
#Html.CheckBox("avalia1", avalia1, new { autocomplete = "off", data_on_text = "Sim", data_off_text = "Não" })
}
</td>
JS
var avalia1 = $("#avalia1").is(":checked");
var url = "/Telefonia/GravarAvaliacao";
$.ajax({
url: url,
datatype: "json",
data: { 'avalia1': avalia1,'idgravacao': idgravacao },
type: "POST",
success: function (data) {
}
});
}
ON CONTROLLER
public JsonResult GravarAvaliacao(bool avalia1, string idgravacao)
{
string _userId = User.Identity.GetUserId();
var avaliaData = new OperadorAvaliacaoData();
avaliaData.GravaAvaliacao(avalia1, idgravacao);
return Json(true, JsonRequestBehavior.AllowGet);
}
The only diference is your model checkbox, and the action trigger.

How to call API in c# using angularjs

Hi I am calling my API using below code
$http.get('/api/controller/method?param=value').
then(function (response) {
if (response.status == 200) {
console.log(response.data);
}
});
It is working fine in my local machine (http://localhost/api/controller/method?param=value).
But when I deployed it in server with application name app, it is not able to call the API(http://server-ip/app/api/controller/method?param=value).
Obviously, it won't, as URL are different. So what is the correct way to call an API in c# so that it will work in any server.
What I have tried:
1. URL.Action : It is not working in this case.
2. I don't want to Use #HTML.hidden
3. Call starting with or without slash (/)
I usually solve this by using a factory like this -
First in the .cshtml page I load all the angular js required.
Then create a factory for the baseURL like this -
function(angular){
var module = angular.module('NameOfMyModule'); //gt the module
module.factory('BaseUrl', function(){
return '#Url.Action("Action", "Controller")';
});
}(window.angular);
Then inject that BaseURL inside the controller -
....
module.controller('SomeController', [...., 'BaseUrl', function(...., BaseUrl){
$scope.baseUrl = BaseUrl;
}]);
....`
Finally prepend it in the url
$http.get($scope.baseUrl + /...../).then(....);
I'm not sure if I undestood your question correctly, but I'm using angular constant to set server url
angular.constant("CONSTS", {
"DEV_URL": "http://localhost:12345",
"LIVE_URL": "http://server-ip/app"
})
and then in $http call
$http.get(CONSTS.DEV_URL + '/api/controller/method?param=value').
then(function (response) {
if (response.status == 200) {
console.log(response.data);
}
});
I'm sure there is a way to automate this (gulp, grunt), but I didn't get there yet.
When deploying the app I would just manually change the constant.
If I'll find outomatic way to it I'll update the answer.
Hope this helps a bit...
I don't know your build process etc. but usually you can store application path in some constant value in Angular and use it when calling your API as a prefix.
If you have some kind of automated build, it is easy to prepare deployment packages with changed values(by using Gulp/Grunt/TeamCity/Octopus, whatever you like).
//controller
app.controller("sampleController", function($scope, commonService) {
//post
$scope.postData = function() {
var command = {}
commonService.postSample(command);
}
//get
commonService.getSample().then(function(data) {
$scope.permissionList = data;
});
});
//service
app.service('commonService', function($http, $q) {
this.postSample = function(command) {
var deferred = $q.defer();
$http({
method: 'POST',
data: command,
url: '/Attendance/CreatePersonDailyLeave'
})
.success(function(data) {
deferred.resolve(data);
})
.error(function(data) {
deferred.reject(data);
});
return deferred.promise;
}
this.getSample = function(id) {
var deferred = $q.defer();
$http({
method: 'GET',
async: true,
url: '/Attendance/GetRoles?id=' + id
})
.success(function(data) {
deferred.resolve(data);
})
.error(function(data) {
deferred.reject(data);
});
return deferred.promise;
}
});

Categories