How to call API in c# using angularjs - c#

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;
}
});

Related

How to call api from ASP.NET razor view

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);
});

Jquery .post method is sending a null value. How to pass actual value to controller?

I have a controller that applies to an edit view in asp.net MVC. I have an actionlink that sends the row Id to the controller which then brings back the correct row to see in the associated view.
I then have a partial view below that. That also requires a parameter in order to bring associated data from another table.
I have a Jquery .post call that runs after the page is loaded. I can alert out and show the exact value I want to send to the controller.
$(document).ready(function () {
var url = "/Home/MmsAndNotes";
var Uc = $("#Id").serialize();
alert(Uc);
$.post(url, {Id: Uc}, function (data) {
alert("what is Uc now? " + uc); //just for testing
});
})
I have also used it this way.
$(document).ready(function () {
var url = "/Home/MmsAndNotes";
var Uc = $("#Id").val();
alert(Uc);
$.post(url, Uc, function (data) {
});
})
the alerts come up and show the value I want. However, when the .post call runs, it sends a null value. Here is my controller.
public ActionResult MmsAndNotes(string Id)
{
//Declare LogisticsVM for individual policy info
LogisticsMMS_NotesVM model;
if(uc == null)
{
return Content("uc is empty.");
}
int val = Convert.ToInt32(uc);
using (Db db = new Db())
{
LogisticsMMS_NotesDTO dto = db.LogisticsMMS.Find(val);
//confirm policy exists
if (dto == null)
{
return Content("This policy cannot be found." + val);
}
model = new LogisticsMMS_NotesVM(dto);
}
return PartialView(model);
}
It always returns as uc is empty. I repeat, when the alerts come up. I get the correct value to send to the controller. But once it sends, something happens and it converts to null. HELPPPPP.. please .. I'm losing my mind over this one.
I don't know why, but changing my $.post() call to an $.ajax({}) call solved the issue. As you can see above, I had the $.post call. Using this instead,
$.ajax({
type: "POST",
url: "/Home/MmsAndNotes",
dataType: 'text',
data: { Id: Uc }
});
Solved it. I thought Jquery's shortened calls worked the same way. They certainly might, but doing it this way was the only way it worked for me.
P.S. Thanks Tyler (above) for your comments.
this solution should be work :
$(document).ready(function () {
$.ajax({
url: '/Home/MmsAndNotes',
type: 'GET',
dataType: "html",
data: { uc : $("#Id").val() },
success: function (result) {
code here
}
});
})
You need to verify if $("#Id").val() is not empty

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 )});

Kendo UI TreeListDataSource Read() only works when running locally

I have a Kendo TreeList with its datasource defined as
var ds = new kendo.data.TreeListDataSource({
transport: {
read: {
url: "/Home/Read/",
type: "POST",
dataType: "json"
}},
schema:...
}
My controller's read method is:
[HttpPost]
public string Read()
{
log.Info("Start read()");
var vm = vmHelper.GetClientOrgListViewModel();
var json = new JavaScriptSerializer().Serialize(vm.FacilityList);
log.DebugFormat("json read returned: {0}", json);
return json;
}
Everything works great as long as I run locally through VS but once I deploy to our staging server, the Read() transport code never gets executed. I get a 500 error. Pressing F-12 to view the requests in IE shows a 500 error
Any ideas or suggestions on why it works locally but not on the server and how to resolve this issue?
Try building your URL using #Url.Action("Read", "Home")
var ds = new kendo.data.TreeListDataSource({
transport: {
read: {
url: '#Url.Action("Read", "Home")',
type: "POST",
dataType: "json"
}},
schema:...
}
If your javascript code is in a javascript file you won't be able to use the razor helpers. What I do in that case is add it to a list of URL's I keep in my layout file. Like this:
<script type="text/javascript">
var Configuration;
(function (Configuration) {
var urls = {
Read: '#Url.Action("Read", "Home")'
}
Configuration.url = urls;
})(Configuration || (Configuration = {}));
</script>
Then just use it as:
transport: {
read: {
url: Configuration.url.Read
}
}

Web Api 2 - How to send attribute from $http call to controller (attribute routing)

I have this $http call :
$http({
method: 'GET',
url: '/api/PhotoSubmit/GetCategories',
accept: 'application/json'
})
.success(function (result) {
$scope.categories = result;
});
... which needs to send the parameter to this HTTPGET method :
[Route("api/PhotoSubmit/GetCategories/{id}")]
[HttpGet]
public object GetCategories(int id)
{
return FileServices.GetCategoriesForUser().Select(c => new { Id = c.Id, Name = c.Name });
}
Th routing works, i'm just not sure how to access it by angular/javascript to send it to the controller (OR... how the route-call should look like in the $http call
This is the URL :
http://localhost:63203/Index.html#/photosubmit/1
I'm sure $http is similar, but I'm using $resource in a factory to hit my web api endpoint.
In services.js, I have:
var app = angular.module('app.service', ['ngResource']);
app.factory('api', ['$resource', function ($resource) {
'use strict';
return {
Categories: $resource('/api/PhotoSubmit/GetCategories/:id', {id: '#id'})
};
}]);
Then in my controller, I call it with
$scope.categories = api.Categories.get({id:"1"});
If you really want to start having fun, you can wait and use the data after the results come back using a $promise.
api.Categories.get({id:"1"})
.$promise
.then(function (results){
$scope.categories = results;
});
Update:
To get the variable into $routeParams, I'm doing the following (bear in mind, this was my first angular app, so there are better ways to code this.)
In my app.config, I have the following code to create an id parameter:
$routeProvider
...
.when('photosubmit/:id', {
templateUrl: "photo.html",
controller: "PhotoController"
})
.otherwise({ redirectTo: '/' });
Then, I get the param in the controller $scope.$routeParams = $routeParams;
I had to do this at the top so it doesn't get lost or undefined.
Next, you can access the variable you created in the route by using $scope.$routeParams.id
Id can be passed through url itself.
url: '/api/PhotoSubmit/GetCategories/1',
or you can pass this in params too.
$http({
url: '/api/PhotoSubmit/GetCategories',
method: "GET",
params: {id: 1}
});

Categories