ajax call status is 200 but it is not successfull - asp.net

I working on mvc asp.net project. I call my controller function with ajax, the call status is 200 but it is not successful, and goes to error section.
service:
public async Task<IEnumerable<TeamDto>> GetAllTeamsList()
{
var teams = await _teamRepository.GetAll().Include(u => u.Users).ThenInclude(m => m.User).ToListAsync();
return ObjectMapper.Map<IEnumerable<TeamDto>>(teams);
}
Controller:
public async Task<IEnumerable<TeamDto>> GetTeams()
{
var teams = await _teamAppService.GetAllTeamsList();
return teams;
}
js file:
$.ajax(
{
type: "GET",
url: "/App/Team/GetTeams",
success: function (data) {
///
},
error: function (data) { console.log("it went bad " + JSON.stringify(data)); }
});
Error:
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
this is what I get when copy the url in the browser:
{"result":[{"tenantId":1,"name":"admin
team","users":[{"tenantId":1,"userId":2,"teamId":58,"user":{"profilePictureId":null,"shouldChangePasswordOnNextLogin":false,"signInTokenExpireTimeUtc":null,"signInToken":null,"googleAuthenticatorKey":null,"pin":"1234","hourlyRate":0.00,"payrollId":"","warehouseId":1,"tandaUser":null,"normalizedUserName":"ADMIN","normalizedEmailAddress":"ADMIN#DEFAULTTENANT.COM","concurrencyStamp":"bd7ee91e-587b-4ae2-bc97-be2ce7d7789b","tokens":null,"deleterUser":null,"creatorUser":null,"lastModifierUser":null,"authenticationSource":null,"userName":"admin","tenantId":1,"emailAddress":"admin#defaulttenant.com","name":"admin","surname":"admin","fullName":"admin
admin","password":"AQAAAAEAACcQAAAAENfcSE+zBppFKVxKUynGBiy4WZgDU3C3gbbWnQUdEyBb5J/S0uLkcqk+2MwM0DXxjw==","emailConfirmationCode":null,"passwordResetCode":null,"lockoutEndDateUtc":null,"accessFailedCount":1,"isLockoutEnabled":true,"phoneNumber":"","isPhoneNumberConfirmed":false,"securityStamp":"07a4d582-7233-3fbc-f3f7-39f015ee388b","isTwoFactorEnabled":false,"logins":null,"roles":null,"claims":null,"permissions":null,"settings":null,"isEmailConfirmed":true,"isActive":true,"isDeleted":false,"deleterUserId":null,"deletionTime":null,"lastModificationTime":"2020-09-30T02:54:34.402372Z","lastModifierUserId":null,"creationTime":"2019-09-05T23:27:47.8514365Z","creatorUserId":null,"id":2},"team":{"tenantId":1,"name":"admin
team","users":[

Open up the developer tools and look at the URL it is trying to request. Normally in the context of the application, you don't have the /App defined. In fact, you can use ASP.NET MVC Url helper to get the action method, to make sure the path is correct:
$.ajax({
type: "GET",
url: "#Url.Action("GetTeams", "Team")",
Also, normally you would return data via JSON from the controller like:
public async Task<IEnumerable<TeamDto>> GetTeams()
{
var teams = await _teamAppService.GetAllTeamsList();
return Json(teams, JsonRequestBehavior.AllowGet);
}
And maybe that would make a difference, using Json() from the asp.net mvc controller. Note AllowGet ensures that GET requests on an action returning JSON works, otherwise it will be blocked and return an error.

Related

How do I fill a Javascript var with Json data from a Controller in Asp.net Core

I have a controller that returns a JsonResult
[HttpGet]
public JsonResult ShopMarkers()
{
var shops = repository.Shops;
return Json(shops);
}
In my view I'd like to fill a var with the data from that method. In an older MVC project I remember I'd write an ajax call to fill the var. Something like this:
var markers;
$.ajax({
type: 'POST',
url: '/Map/ShopMarkers',
dataType: 'json',
contentType: dataType,
data: data,
success: function (result) {
markers = result;
}
});
Or I could return a string to a view and Json.Parse it there inside a script tag.
Neither of these seem right. Is there a better way to fill my var in .Net Core?
Your client code is currently making the ajax call with POST type request. But your action method is decorated with HttpGet. So you should be getting a 404 error (If you inspect your browser dev tools, you should be able to see the status of the network (ajax) call)
[HttpPost]
public JsonResult ShopMarkers()
{
var shops = repository.Shops;
return Json(shops);
}
This should work assuming your code inside ShopMarkers method is not crashing ! (throwing any exceptions or so)
In your client side code you are trying to send an object. If you are sending a complex object, you should specify the contentType as "application/json" and send the data using JSON.stringify method.
var dataType = "application/json";
var data = { userId: 12, Password: 'ss' };
$.ajax({
type: 'POST',
url: '/Home/ShopMarkers',
dataType: 'json', // not really needed in your case
contentType: dataType,
data: JSON.stringify(data),
success: function (result) {
var markers = result;
console.log(result);
//Use result only here. Not outside
}
});
Since the ajax call is sending data in the request body, you should decorate the method parameter with [FromBody] attribute so that model binder will be able to map the posted data (from the request body) to your parameter.
[HttpPost]
public JsonResult ShopMarkers([FromBody] YourUserViewModel model)
{
//to do : Return some JSON
}

CORS Issue same controller, one method is ok, other one is not

Very strange error I'm experiencing.
I have two methods in controller which are called by angular js http get event.
First one works fine, second one is throwing CORS error, not sure how is that possible since both of them are in same controller.
This is the error I'm getting:
These are the calls I'm doing in angularjs:
$http({
url: 'http://localhost:52876/api/Admin/GetLoanInfo',
method: "GET",
params: { loanID: querystringParam }
}).success(function (data, status) {
console.log(data);
$scope.LoanDetailsVM.LoanStatus = data.LoanStatus;
}).error(function (data, status) {
console.log(data);
});
$http({
url: 'http://localhost:52876/api/Admin/GetLoanCovenants',
method: "GET",
params: { loanID: querystringParam }
}).success(function (data, status) {
console.log(data);
}).error(function (data, status) {
console.log(data);
});
And the controller methods:
[HttpGet]
[Route("api/Admin/GetLoanInfo")]
public async Task<IHttpActionResult> GetLoanInfo(int loanID)
{
LoanApplication newApplication = null;
newApplication = db.LoanApplications.FirstOrDefault(s => s.LoanId == loanID);
return Ok(newApplication);
}
[HttpGet]
[Route("api/Admin/GetLoanCovenants")]
public async Task<IHttpActionResult> GetLoanCovenants(int loanID)
{
LoanCovenant newCovenant = null;
newCovenant = db.LoanCovenants.FirstOrDefault(s => s.LoanID == loanID);
return Ok(newCovenant);
}
I'm able to hit both methods, I have breakpoints in both of the methods, but not sure why is complaining about CORS on the first one.
Calling methods using CORS from a Web browser makes Web API being called first with an OPTIONS request (example at the end of this article).
This way, the browser knows if it can call the requested API.
In your case, the call to your endpoint seems to be crashing, which means the HTTP 500 error does not contain any CORS headers.
This explains why the web browser complaning about CORS HTTP Header missing: Reason: CORS Header 'Access-Control-Allow-Origin' missing.
If you fix your method, then HTTP OPTIONS should be ok, and the CORS erros would go away.

How to make an Ajax call to action method in different controller

I have following scenario.
Route Config:
routes.MapRoute(
name: "SellerRegistration",
url: "Registration/{action}/{id}",
defaults: new { controller = "SellerRegistration", action = "Seller", id = UrlParameter.Optional, area = "" },
namespaces: new[] { "MyCompany.Controllers" }
);
So when the url is www.example.com/Registration/Seller, the above route will match and displaying the view without any issues.
class SellerRegistration
{
public ActionResult Seller()
{
return View("Seller");
}
[AjaxOnly]
public bool ValidateUserEmail(string email)
{
return _userService.ValidateUserEmail(email);
}
}
Inside my view Seller.cshtml, I'm trying to make an ajax call to the method ValidateUserEmail().
I'm making ajax call as below:
$.ajax({
type: "POST",
url: rootUrl + "/SellerRegistration/ValidateUserEmail",
cache: false,
async: false,
data: { email: $("#Email").val() },
success: function (data) {
if (data === 'True') {
//redirect to login page
window.location.href = newUrl;
} else {
$("#otherDetails").show();
$("#emailValidation").hide();
$("#submitCompleteFormDiv").show();
}
},
error: function (data, jqXhr) {
console.log(jqXhr.status);
}
});
I have also tried generating url as below in the above ajax method.
url: '#Url.Action("SellerRegistration", "ValidateUserEmail")'
But I'm getting
401 - Unauthorised error.
I'm guessing that I'm not able to make ajax call because of the routing I configured. But, that routing is required to meet other scenarios in the application.
When ajax call is made, the url format is like www.example.com/Registration/Seller
So browser initiates an ajax call to the ValidateUserEmail method inside the controller SellerRegistration from www.example.com/Registration/Seller.
Because there is no real controller named Registration, when the ajax call is made to ValidateUserEmail() inside SellerRegistration controller, I'm getting 401 Unauthorized error.
Can someone please suggest if there is any technique or workaround to make it possible.
Thank you.

How to send data from URL to Post Request Method?

i'm developing an MVC4 application and using Web API for my web services to send data for android application and i need some testing on the results so when i use GET Request Method i put in the browser this URL
http://localhost:2100/api/Accounts/LogIn?UserName=Fadi&PassWord=123456
this is my method
[HttpGet]
public ConfrmationMessage LogIn(string UserName, string PassWord)
{
ConfrmationMessage flag = new ConfrmationMessage();
if (WebSecurity.Login(UserName, PassWord))
{
flag.status = "LogedIn";
return flag;
}
else
{
flag.status = "The user name or password provided is incorrect.";
return flag;
}
}
and every thing work fine but when i'm using an [HttpPost] and use this URL again
http://localhost:2100/api/Accounts/LogIn?UserName=Fadi&PassWord=123456
it give me this error
{"Message":"The requested resource does not support http method 'GET'."}
so i did do some search and find that the post method use anther way to put data from URL link but still can not understand how to write the correct URL for the post method so any help and thanks in advance.
you submit a post request via a form element like so (there are more attributes you can add but you can look these up easily.
<form action="~/api/Accounts/LogIn" method="POST">
<!--input elements here -->
</form>
or through an ajax call (requires jquery)
$.ajax({
url: "~/api/Accounts/LogIn",
type: "POST",
data: { UserName: "Fadi", PassWord: "123456" }
success: function(result) {
//do something when response is successful (result is the response)
},
error: function(jqXHR, textStatus, errorThrown) {
//will return exception info from server
//jqXHR is the request in xml format
//textStatus is the description of the exception (if there is one)
//errorThrown is the excception object thrown (if there is one)
}
});

AngularJS - Unknown provider configuring $httpProvider

In the following code example:
myApp.config(['$httpProvider', function($httpProvider, $cookieStore) {
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.headers.get['Authorization'] = 'Basic '+ $cookieStore.get('myToken');
return JSON.stringify(data);
}]);
I get an angularjs error like 'Unknown provider $cookieStore'.
'myApp' has dependenciy and 'ngCookies' and angular-cookies.min.js is laoded, so what's wrong with that code ?
Is that fact that i'm doing this in .config ?
Because it's only possible to pass providers when configuring, i have finally done the overwrite of my http parameter not with a request transformer but by creating a service as factory to do requests.
Here is a code example of the service (not tested, just for information):
angular.module('myapp-http-request', []);
angular.module('myapp-http-request')
.factory('MyRequests', function($http, $cookieStore){
return {
request: function(method, url, data, okCallback, koCallback){
$http({
method: method,
url: url,
data: data
}).success(okCallback).error(koCallback);
},
authentifiedRequest: function(method, url, data, okCallback, koCallback){
$http({
method: method,
url: url,
data: data,
headers: {'Authorization': $cookieStore.get('token')}
}).success(okCallback).error(koCallback);
}
}
});
And example of usage (not tested, just for information):
angular.module('sharewebapp', ['myapp-http-request'])
.controller('MyController', ['MyRequests', function(MyRequests){
MyRequests.authentifiedRequest('DELETE', '/logout', '', function(){alert('logged-out');}, function(){alert('error');})
}]);
You probably need to add the cookieStore
myApp.config(['$httpProvider', '$cookieStore', function($httpProvider, $cookieStore)
I had ran into this same problem so i'll post how I got around it. I essentially used the $injector module to manual grab an instance of the service I needed. Note this also works for user defined services.
angular.module('app').
config(config);
config.$inject = ['$httpProvider'];
function config($httpProvider) {
//Inject using the $injector
$httpProvider.interceptors.push(['$injector', function($injector){
return {
request: function(config) {
//Get access by injecting an instance of the desired module/service
let $cookieStore = $injector.get('$cookieStore');
let token = $cookieStore.get('your-cookie-name');
if (token) {
config.headers['x-access-token'] = token;
}
return config;
}
}
}])
}
Using the Module.run() seems to be a cleaner way to set headers that are always needed. See my answer here: AngularJS pass requestVerificationToken to a service

Resources