How to call local MVC 4 function inside ajax call - asp.net-mvc

In my SPA website i need to send antiforrgery token over to server by ajax. I use this article method:
http://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-%28csrf%29-attacks
So in my layout.cshtml i have local function :
<script>
#functions{
public string TokenHeaderValue()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}
</script>
and i have separate js file named register.js where i call this function inside ajax:
$.ajax({
url: 'User/JsonRegister',
type: "POST",
data: d,
headers: {
'RequestVerificationToken': '#TokenHeaderValue()'
},
success: function (result) {
},
error: function (result) {
}
});
the problem is that i never #TokenHeaderValue() is never called and i m keep getting this error:
The required anti-forgery form field "__RequestVerificationToken" is not present.
How do i solve this problem?

The problem is using server side helper function in the separate js file. If you need to have ajax call in the separate js file, set #TokenHeaderValue() value to a hidden field and read the value of hidden field in the js file.

i add token to my data this way: which solves problem
AddAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
return data;
};

Pass data in JSON format
$.ajax({
type:"POST",
datatype:"JSON",
data:{d:d}, // Remaining code is same
});
And use [HttpPost] before method signature in controller because it a Post request.

Related

Ajax Request issue with ASP.NET MVC 4 Area

Today i discovered something weird, i have regular asp.net mvc 4 project with no such ajax (just post, get). so today i need ajax request, i did an ajax action with jquery in controller and it didn't work out. Here is my code
Areas/Admin/Controllers/BannersController
public JsonResult SaveOrder(string model)
{
bool result = false;
if (!string.IsNullOrEmpty(model))
{
var list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<int>>(model);
result = repository.SaveOrder(list);
}
return Json(result, JsonRequestBehavior.AllowGet);
}
View side (Its in area too)
$(document).ready(function () {
$("#saveOrder").click(function () {
var data = JSON.stringify($("#list_banners").nestable('serialize'));
$.ajax({
url: '#Url.Action("SaveOrder", "Banners", new { area = "Admin" })',
data: { model: data },
success: function (result) {
if (result) {
toastr.success('Kaydedildi.');
}
else {
toastr.error('kaydedilemedi.');
}
},
error: function (e) {
console.log(e);
}
});
});
});
i've already tried everything i know, which is $.post, $.get, ajax options, trying request from out of area etc.. just request can't reach action
and here is the errors ,
http://prntscr.com/297nye
error object
http://prntscr.com/297o3x
Try by specifying the data format (json) you wand to post to server like and Also change the way you pass data object in JSON like this :
var data = $("#list_banners").nestable('serialize');
$.ajax({
url: '#Url.Action("SaveOrder", "Banners", new { area = "Admin" })',
data: JSON.stringify({ model: data }),
dataType: 'json',
contentType: "application/json",
...
I had same issue, but after spending too much time, got solution for that. If your request is going to your specified controller, then check your response. There must be some problem in your response. In my case, response was not properly converted to JSON, then i tried with passing some values of response object from controller using select function, and got what i needed.

mvc json request life cycle

I'm pretty new to asp.net and MVC.
I was trying to use json request and populate some text boxes.
but I noticed when I'm using json, I can not access values of the other text boxes in my view.
for example
string s2 = Request.Form["selectedTestCategory"];
would generate s2 = null, when I debug.
but if I put a submit button on the page, the value is not null. (And so far I know I can only pass one parameter to my JSON method in controller)
My question is what happens when I start a json request? and why I can not get a value from Request.Form[...]
Thanks,
Update:
This is my json
<script>
$(document).ready(function() {
$('select#testStationUniqueId').change(function() {
var testStation = $(this).val();
$.ajaxSetup({ cache: false });
$.ajax({
url: "TestInput/getTestStationInformation/" + testStation,
type: 'post',
success: function(data) {
$('#driveDetailDiv').empty();
for (var i = 0; i < data.length; i++) {
$.post('TestInput/Details/', { id: data[i] }, function(data2) {
$('#driveDetailDiv').append(data2);
});
}
}
});
});
});
And this is in my controller
public PartialViewResult Details(string id)
{
//DriveDetails t = new DriveDetails(id);
//return PartialView("DriveDetailsPartial", t);
test_instance_input_model ti = new test_instance_input_model();
string s2 = Request.Form["selectedTestCategory"];
repository.setTestInstanceAttributes(ti, id);
return PartialView("TestInstancePartial", ti);
}
the s2 is null in Details, but if I use a submit button, it will have the correct value.
so I'm trying to figure out why it is null when I send a json request.
In your JavaScript your not including any data in the jQuery ajax request (see jQuery ajax). Therefore jQuery isn't adding any request parameters. You need to include a data object which jQuery will turn into parameters i.e. the more properties in the data object the more parameters in the request.
$.ajax({
url: '',
data: { selectedTestCategory: 'category' },
dataType: 'post',
success: function() {}
});
Also, in your controller you can shortcut to the request parameter.
string s2 = Request["selectedTestCategory"];

asp.net mvc 3 json values not recieving at controller

the problem is that i am not able to recieve any value in the controller . what could be wrong? the code is here.
$('#save').click(function () {
var UserLoginViewModel = { UserName: $('vcr_UserName').val(),
Password: $('vcr_Password').val()
};
$.ajax({
url: "/User/Login",
data: JSON.stringify(UserLoginViewModel),
contenttype: "application/json; charset=utf-8",
success: function (mydata) {
$("#message").html("Login");
},
error: function () {
$("#message").html("error");
},
type: "POST",
datatype: "json"
});
return false;
});
});
[HttpPost]
public ActionResult Login(UserLoginViewModel UserLoginViewModel)
{
}
As you're using MVC3 - you should be able to take advantage of the built in JSON model binding.
Your code example has a couple of typos: contentType and dataType are lowercase...(they should have an uppercase "T")
jQuery ajax docs
After you POST up the correct contentType/dataType, MVC should automatically bind your object to the posted JSON.
You're going to need an action filter or similar to intercept the json from the post body.
Here's a starter
Provider Factory
but here is the article that sorted this for me On Haacked
It is good if you know the type you are deserialising into up front, but if you need polymorphism you'll end up using these ideas in an action filter.

How would you pass objects with MVC and jQuery AJAX?

I am finally experimenting and trying to learn MVC after years of asp.net.
I am used to using asp.net AJAX PageMethods where you can pass an object that automagically gets parsed to whatever type the parameter is in that method.
Javascript:
PageMethods.AddPerson({First:"John",Last:"Doe"});
Code-Behind:
[WebMethod]
public static Result AddPerson(Person objPerson)
{
return Person.Save();
}
How would do this using MVC and jQuery?
Did just have to send strings and parse the json to object?
That depends on how complex your form data is going to be. Let's use a jQuery example:
$.ajax({
url: '\Persons\AddPerson', // PersonsController, AddPerson Action
data: { First: "John", Last: "Doe" },
type: 'POST',
success: function(data, status)
{
alert('Method called successfully!');
}
});
So we post two pieces of data. If the Person class has two properties called 'First' and 'Last', then the default ASP.NET MVC Model Binder should have no problems putting this form data into those properties (everything else will be defaulted).
Of course, you could always make a custom model binder for the Person type, and then you can take whatever form values you want and put them into any property at all, or call some other kind of logic.
I have a post that covers AJAX calls to ASP.NET MVC action methods. It covers the following combinations:
HTTP GET, POST
jQuery methods $.get, $.getJSON, $.post
Sending parameters to the action methods
Returning parameters (strings and JSON) from the action methods
Posting form data
Loading a MVC partial view via AJAX
AJAX calls to ASP.NET MVC action methods using jQuery
When you POST a form via ajax to an action method on your controller, the ModelBinder architecture kicks in to parse the posted form values into business objects for you. You can leverage modelbinding in a few different ways.
public ActionResult MyAction(MyObject obj)
{
}
In the above example, the modelbinder implicitly tries to create a MyObject from the information it received in the request.
public ActionResult MyAction(FormCollection stuff)
{
MyObject obj = new MyObject();
TryUpdateModel(obj);
}
Here we are explicitly trying to bind the posted form data to an object that we created. The ModelBinder will try to match the posted values to the properties of the object.
In either of these cases, you can query the ModelState object to see if there were any errors that occurred during translation of the posted values to the object.
For an introduction to model binding, see here.
For advanced modelbinding to lists and dictionaries, see Phil Haack's post.
You could do something like this:
var person = {};
person["First"] = $("#FirstName").val();
person["Last"] = $("#LastName").val();
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/Admin/AddPerson",
data: JSON.stringify(person),
dataType: "json",
success: function(result) {
},
error: function(result) {
}
});
and then on your admin controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddRelease(Person p)
{
// Code to add person
}
The JSON.stringify method is available from here. You could also use a model rather than the Person object as a parameter that way you could handle all of your validation.
I guess I am a cheater and do the following:
$("#ProgressDialog").dialog({
autoOpen: false,
draggable: false,
modal: true,
resizable: false,
title: "Loading",
closeOnEscape: false//,
// open: function () { $(".ui-dialog-titlebar-close").hide(); } // Hide close button
});
$("form").live("submit", function (event) {
event.preventDefault();
var form = $(this);
$("#ProgressDialog").dialog("open");
$.ajax({
url: form.attr('action'),
type: "POST",
data: form.serialize(),//USE THIS to autoserialize!
success: function (data) {
$("#dialog").dialog({height:0});
},
error: function (jqXhr, textStatus, errorThrown) {
alert("Error '" + jqXhr.status + "' (textStatus: '" + textStatus + "', errorThrown: '" + errorThrown + "')");
},
complete: function () {
$("#ProgressDialog").dialog("close");
}
});
});
});
<div id="ProgressDialog" style="text-align: center; padding: 50px;">
<img src="#Url.Content("~/Content/ajax-loader.gif")" width="128" height="15" alt="Loading" />
</div>

How to send a model in jQuery $.ajax() post request to MVC controller method

In doing an auto-refresh using the following code, I assumed that when I do a post, the model will automatically sent to the controller:
$.ajax({
url: '<%=Url.Action("ModelPage")%>',
type: "POST",
//data: ??????
success: function(result) {
$("div#updatePane").html(result);
},
complete: function() {
$('form').onsubmit({ preventDefault: function() { } });
}
});
Every time there is a post, I need to increment the value attribute in the model:
public ActionResult Modelpage(MyModel model)
{
model.value = model.value + 1;
return PartialView("ModelPartialView", this.ViewData);
}
But the model is not passed to the controller when the page is posted with jQuery AJAX request. How can I send the model in the AJAX request?
The simple answer (in MVC 3 onwards, maybe even 2) is you don't have to do anything special.
As long as your JSON parameters match the model, MVC is smart enough to construct a new object from the parameters you give it. The parameters that aren't there are just defaulted.
For example, the Javascript:
var values =
{
"Name": "Chris",
"Color": "Green"
}
$.post("#Url.Action("Update")",values,function(data)
{
// do stuff;
});
The model:
public class UserModel
{
public string Name { get;set; }
public string Color { get;set; }
public IEnumerable<string> Contacts { get;set; }
}
The controller:
public ActionResult Update(UserModel model)
{
// do something with the model
return Json(new { success = true });
}
If you need to send the FULL model to the controller, you first need the model to be available to your javascript code.
In our app, we do this with an extension method:
public static class JsonExtensions
{
public static string ToJson(this Object obj)
{
return new JavaScriptSerializer().Serialize(obj);
}
}
On the view, we use it to render the model:
<script type="javascript">
var model = <%= Model.ToJson() %>
</script>
You can then pass the model variable into your $.ajax call.
I have an MVC page that submits JSON of selected values from a group of radio buttons.
I use:
var dataArray = $.makeArray($("input[type=radio]").serializeArray());
To make an array of their names and values. Then I convert it to JSON with:
var json = $.toJSON(dataArray)
and then post it with jQuery's ajax() to the MVC controller
$.ajax({
url: "/Rounding.aspx/Round/" + $("#OfferId").val(),
type: 'POST',
dataType: 'html',
data: json,
contentType: 'application/json; charset=utf-8',
beforeSend: doSubmitBeforeSend,
complete: doSubmitComplete,
success: doSubmitSuccess});
Which sends the data across as native JSON data.
You can then capture the response stream and de-serialize it into the native C#/VB.net object and manipulate it in your controller.
To automate this process in a lovely, low maintenance way, I advise reading this entry that spells out most of native, automatic JSON de-serialization quite well.
Match your JSON object to match your model and the linked process below should automatically deserialize the data into your controller. It's works wonderfully for me.
Article on MVC JSON deserialization
This can be done by building a javascript object to match your mvc model. The names of the javascript properties have to match exactly to the mvc model or else the autobind won't happen on the post. Once you have your model on the server side you can then manipulate it and store the data to the database.
I am achieving this either by a double click event on a grid row or click event on a button of some sort.
#model TestProject.Models.TestModel
<script>
function testButton_Click(){
var javaModel ={
ModelId: '#Model.TestId',
CreatedDate: '#Model.CreatedDate.ToShortDateString()',
TestDescription: '#Model.TestDescription',
//Here I am using a Kendo editor and I want to bind the text value to my javascript
//object. This may be different for you depending on what controls you use.
TestStatus: ($('#StatusTextBox'))[0].value,
TestType: '#Model.TestType'
}
//Now I did for some reason have some trouble passing the ENUM id of a Kendo ComboBox
//selected value. This puzzled me due to the conversion to Json object in the Ajax call.
//By parsing the Type to an int this worked.
javaModel.TestType = parseInt(javaModel.TestType);
$.ajax({
//This is where you want to post to.
url:'#Url.Action("TestModelUpdate","TestController")',
async:true,
type:"POST",
contentType: 'application/json',
dataType:"json",
data: JSON.stringify(javaModel)
});
}
</script>
//This is your controller action on the server, and it will autobind your values
//to the newTestModel on post.
[HttpPost]
public ActionResult TestModelUpdate(TestModel newTestModel)
{
TestModel.UpdateTestModel(newTestModel);
return //do some return action;
}
I think you need to explicitly pass the data attribute. One way to do this is to use the
data = $('#your-form-id').serialize();
This post may be helpful.
Post with jquery and ajax
Have a look at the doc here..
Ajax serialize
you can create a variable and send to ajax.
var m = { "Value": #Model.Value }
$.ajax({
url: '<%=Url.Action("ModelPage")%>',
type: "POST",
data: m,
success: function(result) {
$("div#updatePane").html(result);
},
complete: function() {
$('form').onsubmit({ preventDefault: function() { } });
}
});
All of model's field must bo ceated in m.
In ajax call mention-
data:MakeModel(),
use the below function to bind data to model
function MakeModel() {
var MyModel = {};
MyModel.value = $('#input element id').val() or your value;
return JSON.stringify(MyModel);
}
Attach [HttpPost] attribute to your controller action
on POST this data will get available

Resources