sending data to MVC from an angular post - asp.net-mvc

We are using angularjs to post a form to an MVC controller to process
$scope.resultsFilter = function () {
$scope.data = [];
$scope.data = {
startdate: $scope.$$childHead.resultfilter.startdate,
enddate: $scope.$$childHead.resultfilter.enddate,
frequency: $scope.resultfilter.frequency,
direction: $scope.resultfilter.direction
};
var url = '/user/GetResults/';
$http.post(url, $scope.data).success(function (data, status, headers, config) {
if (data.msg != '') {
$scope.msgs.push(data.msg);
}
else {
$scope.errors.push(data.error);
}
}).error(function (data, status) { // called asynchronously if an error occurs
// or server returns response with an error status.
$scope.errors.push(status);
});
};
});
and the MVC controller is :-
[HttpPost]
public ActionResult GetResults()
{
}
how do we access the data that has been posted by the form?

If you have POCO equivalent of that data, something like:
public class MyData{
public DateTime startdate{get;set;}
public DateTime enddate{get;set;}
....
}
You can try:
[HttpPost]
public ActionResult GetResults(MyData myData)
{
}
With the following HTTP Post:
$http({
url: '/controllerName/GetResults/',
method: "POST",
data:$scope.data,
})
.success(function (data, status, headers, config) {
}).error(function (data, status, headers, config) {
});

you can get MVC model using model object and pass to function as json
data
click=someFunc('#Json.Encode(Model)');

Related

How to call async Task from ajax aspnet core

I am using asp.net core and I am calling async task ActionResult method from ajax. Its is running fine on local host but after hosting on IIS it throw 500 status code error.
But it is not calling this method is ajax code
This is ajax method:
$('.Savebtn').click(function () {
$.ajax({
url: '#Url.Action("Testing", "Home")',
data: "Test data",
type: 'POST', //POST if you want to save, GET if you want to fetch data from server
success: function (obj) {
// here comes your response after calling the server
alert('Suceeded');
},
error: function (obj) {
alert('Something happened');
}
});
});
This is Controller method:
[HttpPost]
public async Task<IActionResult> Testing()
{
if (ModelState.IsValid)
{
try
{
return NotFound();
}
catch (Exception ex)
{
return NotFound();
}
}
return View();
}
Error Screen Shot
In Startup.cs file add service like this:
services.AddAntiforgery(options => options.HeaderName = "RequestVerificationToken");
In your cshtml file add:
#Html.AntiForgeryToken()
$.ajax({
type: 'GET',
url: '/home/Demo1',
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (result) {
alert(result);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError);
}
});
And your method in Controller looks like this:
[HttpGet]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Demo1()
{
//your code
return new JsonResult(null);
}
If you don't want [ValidateAntiForgeryToken] remove it and it will work. If you want it, then you have to pass the auto generated cookie value to validate as mentioned below, check this.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Testing()
{
if (ModelState.IsValid)
{
try
{
await Task.Delay(100);
return Ok();
}
catch (Exception ex)
{
return NotFound();
}
}
return View();
}
View:
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
#Html.AntiForgeryToken()
}
<button class="Savebtn btn btn-success">Save</button>
Script:
$(document).ready(function () {
$('.Savebtn').click(function () {
var form = $('#__AjaxAntiForgeryForm');
var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
url: '#Url.Action("Testing", "Home")',
data: {
__RequestVerificationToken: token,
data: "Test data"
},
type: 'POST', //POST if you want to save, GET if you want to fetch data from server
success: function (obj) {
// here comes your response after calling the server
alert('Suceeded');
},
error: function (obj) {
alert('Something happened');
}
});
});
})
</script>
Reference
First change the URL to like 'Testing/Home' and Make sure you're passing data because if you don't it might throw 500 status code error.
In my case I wasn't passing any data I mean I was sending an empty form that was why. I thought it might help someone.

call api controller method in asp.net mvc from angularjs

Hello i have a server side controller method:
public class CustomerController : ApiController
{
public void Delete(IList customers)
{
// handle delete action here....
}
}
I am using Angularjs , my question is how can i call my delete method from angularjs at client side.
Thanks
You could use an AJAX request with $http:
var customers = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Smith' }
];
$http({
method: 'DELETE',
url: '/customer',
data: customers
}).success(function(data, status, headers, config) {
alert('success');
}).error(function(data, status, headers, config) {
alert('error');
});
You should probably use $http in angularjs rather than normal http.
function Delete(customer) {
var promise = $http.post(
'/customer',
{ customer: customer}
).success(function (data, status, headers, config) {
return data;
}).error(function (data) {
return data;
});
return promise;
}

observableArray sent as parameter to a contoller function is null

I want to pass the data in the FeatureList (observableArray) to the SaveMappings function in the TreeController. I have binded a button to the sendItems function. I put a breakpoint at the var data=p2fData line to see what I received. p2fData is null.
I changed the controller to public JsonResult SaveMappings(List p2fData). In this case p2f data shows that there is 1 element, but then its null too.
var Feature = function (featId) {
var self = this;
self.featId = featId;
self.parameters = ko.observableArray();
}
var ParameterToFeatureListViewModel = function () {
var self = this;
var newFeature = new Feature("Feature XYZ");
newFeature.parameters.push("1");
newFeature.parameters.push("2");
self.FeatureList = ko.observableArray([newFeature]);
self.sendItems = function() {
$.ajax({
type: "POST",
url: '/Tree/SaveMappings',
data: ko.toJSON(self.FeatureList),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response);
},
error: function (request, status, error) {
alert(request.statusText);
}
});
}
}
var vm = new ParameterToFeatureListViewModel()
ko.applyBindings(vm);
public class TreeController:Controller
{
public ActionResult Index(){...}
[HttpPost]
public JsonResult SaveMappings(string p2fData)
{
var data = p2fData;
return Json(data);
}
}
Please have a look # how to pass knockoutjs view model into a mvc controller
... May be it helps..

how to pass knockoutjs view model into a mvc controller

I have the following function in a MVC controller
public class XyzController:Controller
{
public ActionResult Index(){...}
[HttpPost]
public bool Save(string jsondata)
{
//parse json data to insert into the database
}
}
I want to pass this view model into the Save function
var myObj = function (id) {
var self = this;
self.myId = id;
self.parameters = ko.observableArray();
}
var ViewModel = function () {
var self = this;
self.myObjList = ko.observableArray();
self.sendItems = function() {
$.ajax({
type: "POST",
url: '/Xyz/Save',
data: ko.toJSON(self),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response);
},
error: function (request, status, error) {
alert(request.statusText);
}
});
}
}
var vm = new ViewModel()
ko.applyBindings(vm);
I do get the data if I pass the data as JSON.stringify({jsondata:ko.toJSON(self)}), but how do I then convert it into a object so that I can iterate over the myObjList and the parameters?
First of all try changing your Model to something like this :-
[JsonObject(MemberSerialization.OptIn)]
public class Test
{
[JsonProperty("myId")]
public string Id { get; set; }
[JsonProperty("parameters")]
public List<string> Parameters { get; set; }//List<string> or whatever it takes int of string
}
if it doesn't work, the please post your Ajax request data... Else....
I follow approach like this:-
MODEL:-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;
namespace MvcApplication4.Models
{
[JsonObject(MemberSerialization.OptIn)]
public class Test
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}
}
CONTROLLER
//
// POST: /Testing/
[HttpPost]
public void Post(MvcApplication4.Models.Test request)
{
try
{
//DO YOUR STUFF
}
catch (Exception ex)
{
throw (ex);
}
}
AJAX Call:-
var json = {};
json = data.id;
json = data.name;
$.ajax({
type: "POST",
url: ""//Your URL,
dataType: "json",
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(json)
}).done(function (data) {
}).fail(function (request, error) {
});
OR make your AJAX call like
$.ajax({
type: "POST",
url: ""//Your URL,
dataType: "json",
contentType: 'application/json; charset=utf-8',
data: ko.toJSON({ id: value1, name: value2 }),//Get value1 and value2 from you ko varables
}).done(function (data) {
}).fail(function (request, error) {
});

ASP.NET MVC Ajax Error handling

How do I handle exceptions thrown in a controller when jquery ajax calls an action?
For example, I would like a global javascript code that gets executed on any kind of server exception during an ajax call which displays the exception message if in debug mode or just a normal error message.
On the client side, I will call a function on the ajax error.
On the server side, Do I need to write a custom actionfilter?
If the server sends some status code different than 200, the error callback is executed:
$.ajax({
url: '/foo',
success: function(result) {
alert('yeap');
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('oops, something bad happened');
}
});
and to register a global error handler you could use the $.ajaxSetup() method:
$.ajaxSetup({
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('oops, something bad happened');
}
});
Another way is to use JSON. So you could write a custom action filter on the server which catches exception and transforms them into JSON response:
public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
filterContext.Result = new JsonResult
{
Data = new { success = false, error = filterContext.Exception.ToString() },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
and then decorate your controller action with this attribute:
[MyErrorHandler]
public ActionResult Foo(string id)
{
if (string.IsNullOrEmpty(id))
{
throw new Exception("oh no");
}
return Json(new { success = true });
}
and finally invoke it:
$.getJSON('/home/foo', { id: null }, function (result) {
if (!result.success) {
alert(result.error);
} else {
// handle the success
}
});
After googling I write a simple Exception handing based on MVC Action Filter:
public class HandleExceptionAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
filterContext.Exception.Message,
filterContext.Exception.StackTrace
}
};
filterContext.ExceptionHandled = true;
}
else
{
base.OnException(filterContext);
}
}
}
and write in global.ascx:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleExceptionAttribute());
}
and then write this script on the layout or Master page:
<script type="text/javascript">
$(document).ajaxError(function (e, jqxhr, settings, exception) {
e.stopPropagation();
if (jqxhr != null)
alert(jqxhr.responseText);
});
</script>
Finally you should turn on custom error.
and then enjoy it :)
Unfortunately, neither of answers are good for me. Surprisingly the solution is much simpler. Return from controller:
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);
And handle it as standard HTTP error on client as you like.
I did a quick solution because I was short of time and it worked ok. Although I think the better option is use an Exception Filter, maybe my solution can help in the case that a simple solution is needed.
I did the following. In the controller method I returned a JsonResult with a property "Success" inside the Data:
[HttpPut]
public JsonResult UpdateEmployeeConfig(EmployeConfig employeToSave)
{
if (!ModelState.IsValid)
{
return new JsonResult
{
Data = new { ErrorMessage = "Model is not valid", Success = false },
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.DenyGet
};
}
try
{
MyDbContext db = new MyDbContext();
db.Entry(employeToSave).State = EntityState.Modified;
db.SaveChanges();
DTO.EmployeConfig user = (DTO.EmployeConfig)Session["EmployeLoggin"];
if (employeToSave.Id == user.Id)
{
user.Company = employeToSave.Company;
user.Language = employeToSave.Language;
user.Money = employeToSave.Money;
user.CostCenter = employeToSave.CostCenter;
Session["EmployeLoggin"] = user;
}
}
catch (Exception ex)
{
return new JsonResult
{
Data = new { ErrorMessage = ex.Message, Success = false },
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.DenyGet
};
}
return new JsonResult() { Data = new { Success = true }, };
}
Later in the ajax call I just asked for this property to know if I had an exception:
$.ajax({
url: 'UpdateEmployeeConfig',
type: 'PUT',
data: JSON.stringify(EmployeConfig),
contentType: "application/json;charset=utf-8",
success: function (data) {
if (data.Success) {
//This is for the example. Please do something prettier for the user, :)
alert('All was really ok');
}
else {
alert('Oups.. we had errors: ' + data.ErrorMessage);
}
},
error: function (request, status, error) {
alert('oh, errors here. The call to the server is not working.')
}
});
Hope this helps. Happy code! :P
In agreement with aleho's response here's a complete example. It works like a charm and is super simple.
Controller code
[HttpGet]
public async Task<ActionResult> ChildItems()
{
var client = TranslationDataHttpClient.GetClient();
HttpResponseMessage response = await client.GetAsync("childItems);
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
List<WorkflowItem> parameters = JsonConvert.DeserializeObject<List<WorkflowItem>>(content);
return Json(content, JsonRequestBehavior.AllowGet);
}
else
{
return new HttpStatusCodeResult(response.StatusCode, response.ReasonPhrase);
}
}
}
Javascript code in the view
var url = '#Html.Raw(#Url.Action("ChildItems", "WorkflowItemModal")';
$.ajax({
type: "GET",
dataType: "json",
url: url,
contentType: "application/json; charset=utf-8",
success: function (data) {
// Do something with the returned data
},
error: function (xhr, status, error) {
// Handle the error.
}
});
Hope this helps someone else!
For handling errors from ajax calls on the client side, you assign a function to the error option of the ajax call.
To set a default globally, you can use the function described here:
http://api.jquery.com/jQuery.ajaxSetup.

Resources