How to make an Ajax call to action method in different controller - asp.net

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.

Related

ajax call status is 200 but it is not successfull

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.

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
}

Pass data using http post in angularjs and Asp .Net Web Api

I am trying to use post method of Web API from angularjs code but the data that I am sending from $http is not reaching to Web API method. The planDetailsVM parameter remains null. Below is my code-
Web API Controller code-
public class RateCalculationController : ApiController
{
[HttpPost]
public RateCalcOutParmDTO GetPlanRateCalculation(PlanDetailsVM planDetailsVM)
{
//planDetailsVM remains null
RateCalcOutParmDTO rateCalcOutParmDTO = new RateCalcOutParmDTO();
// Some operation here
return rateCalcOutParmDTO;
}
}
Here planDetailsVM remains null.
AngularJs Code-
$http({
url: key_Url_GetPlanRateCalculation,
method: 'Post',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
params: $scope.PlanDetails
}).then(function (result) {
//Some operation here
});
Route mapping code-
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
}
I tried to follow one of the solution at this link AngularJs $http.post() does not send data but it's not working for me. What can I need to do so that planDetailsVM receives the posted data from AngularJS http post?
PlanDetails data-
$scope.PlanDetails = { QuoteName: null, BenefitAmountId: 0, BenefitAmountValue: null, DoD_Id: 0, DoD_Value: null, EPBD_Id: null, EPBD_Value: null, _DisplayMsg: null, _DisplayFlag: false };
I was able to solve this issue by just replacing key "params:" with "data:" in the https post request as suggested by Ben. Below is the angularJS code that did the work-
$http({
url: key_Url_GetPlanRateCalculation,
method: 'Post',
data: $scope.PlanDetails
}).then(function (result) {
//Some operation here
});

Asp.Net web-api ajax call 404 method not found

I am using Asp.net mvc4 web-api.
I got an error 404 method not found, i am calling DelteMenu Method using jquery ajax. I am pssing argument Using data : of Jquery ajax. if i am passing Model parameter it is working fine but for other parameters like Guid, String throwing exception : 404 method nod found.please let me know if you have any idea why it is throwing 404 error.
//api method
public HttpResponseMessage DeleteMenu(Guid MenuId)
{
try
{
MenuDA.DeleteMenu(objMenuModel.MenuId);
return this.Request.CreateResponse(
HttpStatusCode.OK,
new
{
Success = true
});
}
catch (Exception ex)
{
ErrorLogDA.LogException(ex);
throw ex;
}
}
//Jquery ajax function
function performdeletemenu(MenuId)
{
if (confirm('Are you sure you want to delete this menu?'))
{
$.ajax({
type: 'DELETE',
url: '/api/MenuWebApi/DeleteMenu/',
data: "MenuId=" + MenuId,
success: function (data)
{
if (data.Success == true)
{
GetMenuList();
}
},
error: function (xhr, textStatus, errorThrown)
{
//window.location = JsErrorAction;
},
dataType: "json",
headers:
{
'RequestVerificationToken': JsTokenHeaderValue
}
});
}
return false;
}
Regards
The data setting does not work when sending a HTTP DELETE through jQuery's ajax function. You will have to pass the Guid in the url itself: url: '/api/MenuWebApi/DeleteMenu?MenuId=' + MenuId.
What I do find strange is that a 404 is returned, instead of a 400 Bad Request.
Add this line in RouteConfig.cs as below
routes.IgnoreRoute("{*x}", new { x = #".*\.asmx(/.*)?" });
I tool reference from https://stackoverflow.com/a/17058251/2318354
It will work definately in case of 404 Error Method not found.

How to get jQuery.Ajax to perform a normal POST with a redirect using ASP.NET MVC

I currently have a JSON object on my page which gets built up as users add items to it. This is all done in JavaScript/jQuery.
When the user is done adding items, I want to POST this object to a controller action and have the action return a strongly typed view using this data.
Currently, I have the jQuery.ajax POST sending this JSON object to an Action Method which then binds this object to my strongly typed Model. Problem is, I actually want this jQuery.ajax POST to redirect as if the JSON object were in a FORM and simply being submitted.
I also can't use the jQuery.post() method, which would redirect as required, as I need to be able to set the contentType to "application/json" so my binding works correctly. Unfortunately, the jQuery.post() method doesn't allow you to set this parameter.
I've read that the jQuery.post() method basically uses the jQuery.ajax() method, so I've been battling to get the jQuery.ajax() method to redirect.
I've also read that I can set the default contentType for all jQuery.ajax() methods which would then allow me to use the jQuery.post() method but want to try avoid this if possible.
Thanks
Edit: Updated with Saedeas suggestion:
My JavaScript on the 'Index' View:
<script language="javascript" type="text/javascript">
// Initialize the Shopping Cart object
var m_ShoppingCart = {
UserId: 10,
DeliveryInstructions: "Leave at front desk",
CartItems: []
};
$(document).ready(function () {
$.extend({
postJSON: function (url, data, callback) {
return $.ajax({
type: "POST",
url: url,
data: JSON.stringify(data),
success: callback,
dataType: "json",
contentType: "application/json",
processData: false
});
}
});
});
function PostDataWithRedirect() {
var url = '#Url.Action("ConfirmOrder", "Store")';
$.postJSON(url, m_ShoppingCart, function () { });
}
function AddToCart(id, itemName, price, quantity) {
// Add the item to the shopping cart object
m_ShoppingCart.CartItems.push({
"Id": id,
"ItemName": itemName,
"Price": price.toFixed(2), // Issue here if you don't specify the decimal place
"Quantity": quantity
});
// Render the shopping cart object
RenderShoppingCart();
}
function RenderShoppingCart() {
$("#CartItemList").html("");
var totalAmount = 0;
$.each(m_ShoppingCart.CartItems, function (index, cartItem) {
var itemTotal = Number(cartItem.Price) * Number(cartItem.Quantity);
totalAmount += itemTotal;
$("#CartItemList").append("<li>" + cartItem.ItemName + " - $" + itemTotal.toFixed(2) + "</li>");
});
$("#TotalAmount").html("$" + totalAmount.toFixed(2));
}
</script>
And then the Controller Action 'ConfirmOrder'
[HttpPost]
public ActionResult ConfirmOrder(ShoppingCartModel model)
{
return View(model);
}
So when the PostDataWithRedirect() JavaScript method is called it must hit the ConfirmOrder Controller Action and be redirected to the ConfirmOrder View. The Shopping Cart object on my Index view is built up entirely in JavaScript and the user then clicks a 'Proceed to Checkout' button and is redirected etc.
PS: My full working example can be found in an the article [ How to POST a JSON object in MVC ], I just need to update this code so that it can do the post and redirect as explained above
In the success method, do a location.href = "TARGET LOCATION" to cause the page to go to TARGET LOCATION.
$.ajax({
url: myurl,data,
data: myData,
// processData: false, // you may need this option depending on service setup
success: function(){
location.href = "TARGET LOCATION";
},
type: "POST",
contentType: "application/json"
});
Return a view that redirects:
controller
return View("redirectionView");
view
RedirectionView.cshtml
#{
Layout = null;
}
<script type="text/javascript">
alert("Success! Redirecting...");
window.location = "./";
</script>
EDIT
To accommodate data retention use tempdata.
controller
TempData["collectedUserData"] = collectedData;
return View("redirectionView");
RedirectionView.cshtml
#{
Layout = null;
}
<script type="text/javascript">
alert("Success! Redirecting...");
window.location = "./Rebuilder/ActionMethod";
</script>
Controller Rebuilder
public ActionResult ActionMethod()
{
if( TempData.ContainsKey("collectedUserData") )
{
var collectedData = TempData["collectedUserData"];
}
//todo: use else clause to catch data not present
use collectedData to build new view
return View();
}
Maybe I'm not following the question, but why does the classic post, redirect, get pattern not work?
[HttpGet]
public ActionResult WhateverActionName()
{
YourViewModel yvm = new YourViewModel();
//Initalize viewmodel here
Return view(yvm);
}
[HttpPost]
public ActionResult WhateverActionName(YourViewModel yvm)
{
if (ModelState.IsValid) {
RedirectToAction("OtherAction", "OtherController")
}
return View(yvm);
}
Do you mean you want to do a post, have it bind to the viewmodel for validation purposes in one controller, and then have that controller post to another controller that verifies everything? If so, I suggest taking a look at this code to post in c# http://geekswithblogs.net/rakker/archive/2006/04/21/76044.aspx.
Edit: Or you could just place the data in a tempdata object if the other controller action doesn't truly require a post.
Edit 2: Wait, is the question how to do the post with jquery? If so,
$("#YourForm").submit(function () {
$.post('#Url.Action("WhateverActionName", "YourController")';
});
});
Note: may be small syntax errors, but close to that. The #Url.Action is the important part.
Edit 3: This should finally work.
jQuery.extend({
postJSON: function(url, data, callback) {
return jQuery.ajax({
type: "POST",
url: url,
data: JSON.stringify(data),
success: callback,
dataType: "json",
contentType: "application/json",
processData: false
});
}
});
Call it in your view as
$.postJSON('#URL.Action("Action", "Controller")', yourJson, callback)
And then redirect inside the controller.

Resources