Ajax call is not passing parameter to controller method - c#

In the Controller I added a method to perform some live data exchange into a div.
public class TextItemsController : Controller
{
//[HttpPost]
public JsonResult SpinText(string Body)
{
SpinningResult spinningResult = new SpinningResult();
spinningResult.Spintext = "This is the result text";
string jsonResult = JsonConvert.SerializeObject(spinningResult);
return Json(jsonResult);
}
}
This works in general and the result is sent back to the calling Ajax method and the div is updated with the result text as intended. So the general communication seems to work. But I never receive the input string from the Ajax call.
function doSpinning() {
//var token = $('input[name="__RequestVerificationToken"]', $('#textForm')).val();
var myData = { Body : "Hello" };
//var dataWithAntiforgeryToken = $.extend(myData, { '__RequestVerificationToken': token });
var requestData = JSON.stringify(myData);
$.ajax({
url: "/TextItems/SpinText",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: requestData,
success: function (data) {
var json = JSON.parse(data);
document.getElementById("PreviewText").innerHTML = json["Spintext"];
},
error: function () {
document.getElementById("PreviewText").innerHTML = "Error";
}
});
}
$("#spinButton").on('click', doSpinning);
data seems to have the correct value "{"Body":"Hello"}" before the post but string Body is always null.

Can you try to prefix your parameter with [FromBody] like this :
public JsonResult SpinText([FromBody] DtoBody Body)
And use a data transfer object so the JsonSerializer will know how to map the sent data
public class DtoBody
{
public string Body {get;set;}
}

You are posting an object with a Body property, and your method expects a string value. These don't match up, obviously, but you don't need to post an object when you only want to pass in a primitive:
$.ajax({
url: "/TextItems/SpinText",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: "Hello",
success: function (data) {
var json = JSON.parse(data);
document.getElementById("PreviewText").innerHTML = json["Spintext"];
},
error: function () {
document.getElementById("PreviewText").innerHTML = "Error";
}
});
Note that this is not your only problem though, as you are doing a double JSON serialization on your Action:
// serialize to JSON
string jsonResult = JsonConvert.SerializeObject(spinningResult);
//serialize the serialized object
return Json(jsonResult);
You never have to explicitly serialize to JSON, that's what the helper does for you.
Just use:
public IActionResult SpinText(string Body)
{
SpinningResult spinningResult = new SpinningResult();
spinningResult.Spintext = "This is the result text";
return Json(spinningResult);
}
And, again, you don't need to double-parse the JSON on the AJAX result:
success: function (data) {
document.getElementById("PreviewText").innerHTML = data.spintext;
},

Thanks a lot, I got it with a mix of your help.
DTO
public class SpinningInput
{
public string Title { get; set; }
public string Body { get; set; }
public string Tags { get; set; }
public string Keyword { get; set; }
}
Controller
public JsonResult SpinText([FromBody]SpinningInput spinningInput)
{
SpinningResult spinningResult = new SpinningResult();
spinningResult = Utility.Spinning.SpinText(spinningInput);
return Json(spinningResult);
}
Javascript
function doSpinning() {
const textBody = document.getElementById("Body").value;
const textTitle = document.getElementById("Title").value;
const textTags = document.getElementById("Tags").value;
const textKeyword = document.getElementById("Keyword").value;
var textData = { Title: textTitle, Body: textBody, Tags: textTags, Keyword: textKeyword };
var requestData = JSON.stringify(textData);
$.ajax({
url: "/TextItems/SpinText",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: requestData,
success: function (data) {
document.getElementById("PreviewText").innerHTML = data.spintext;
document.getElementById("WordCount").innerHTML = data.wordCount;
document.getElementById("KeywordDensity").innerHTML = data.keywordDensity + "%";
},
error: function () {
document.getElementById("PreviewText").innerHTML = "Error";
}
});
}
$("#spinButton").on('click', doSpinning);

Related

How to send data to the ASP.NET Core MVC controller in C#?

I am trying to send data from my Javascript to my post method controller. I have knockout as my method to bind from Javascript to my view.
This is my controller, and this is wher convocationData is null
public async Task<ActionResult> CreateConvocation(string convocationData)
{
string baseUrl = "http://localhost:8080";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(baseUrl);
This is how I try to call the method using jQuery:
var tmpSession = self.addSession();
var tmpDescription = self.addDesc();
var convocationData = {
sessionCode: tmpSession,
description: tmpDescription
};
$.ajax({
url: '/Convocations/CreateConvocation',
type: 'POST',
dataType: 'json',
data: JSON.stringify(convocationData),
contentType: 'application/json',
success: function (data) {
self.Convocations.push(new Convocation(self.addSession(), self.addDesc()));
self.addDesc("");
self.addSession("");
},
error: function (err) {
alert(err.status + " : " + err.statusText);
}
});
Add [FromBody] attribute like this
[HttpPost]
public async Task<ActionResult> CreateConvocation([FromBody]string convocationData)
{
return text;
}
You can read more here Accepting Raw Request Body Content with ASP.NET Web API
Update:
Also, read zgood's comments to your post. Instead of using JSON.stringify you should create a corresponding model as he is describing in his comment.
Update 2:
JS model class
class Convocation {
constructor(sessionCode, description) {
this.sessionCode = sessionCode;
this.description = description;
}
}
C# DTO class
public class Convocation
{
public string SessionCode{ get; set; }
public string Description { get; set; }
}
Then you can update your action method to this
[HttpPost]
public async Task<ActionResult> CreateConvocation([FromBody]Convocation convocation)
{
return text;
}
and ajax post to this:
$.ajax({
url: '/Convocations/CreateConvocation',
type: 'POST',
dataType: 'json',
data: new Convocation(tmpSession, tmpDescription),
contentType: 'application/json',
success: function(data) {
self.Convocations.push(new Convocation(self.addSession(), self.addDesc()));
self.addDesc("");
self.addSession("");
},
error: function(err) {
alert(err.status + " : " + err.statusText);
}
});
I didn't test the code but it should work.

How to map Mvc View model and ajax post data which have list property?

I have a MVC controller action with inputModel parameter which have list type property and , I ,m using $('form').serialize() to serialize the form content and append some of my custom data to serialized string, but inside the action method input model object the list property is empty,
Can any one help me , below is the code samples
My controller
[HttpPost]
public ActionResult Edit(ALDS.Web.Areas.Direct2M3.Models.ItemInputModel collection)
{ }
ItemInputModel class
public class ItemInputModel
{
//......Some property here..
public List<FabricCompositionInputModel> FabricCompositions { get; set; }
}
FabricCompositionInputModel class
public class FabricCompositionInputModel
{
public int ItemID { get; set; }
public string CompositionCode { get; set; }
public decimal Value { get; set; }
}
Ajax call
function save() {
var compositionData = generateCompositionForSave(); //Returns array
var data = $('form').serialize();
var d2 = JSON.stringify(compositionData);
var data2 = data + '&FabricCompositions=' + d2;
$.ajax({
type: 'POST',
dataType: 'json' ,
cache: false,
url: '/ItemMaster/Edit',
data: data2,
success: function (data, textStatus, jqXHR) {
sucess(data);
},
error: function (jqXHR, textStatus, errorThrown) {
failed(jqXHR);
}
});
}
Array generating function
function generateCompositionForSave() {
var arr = [];
var delClassList = $('#compositionContainer').find('.btnRemoveCompositions');
for (var c = 0; c < delClassList.length; c++) {
var row = $(delClassList[c]).closest('.row');
var code = row.find('.compositionCode').val();
var value = parseInt(row.find('.compositionValue').val());
arr.push({ItemID:0, CompositionCode:code, Value:value});
}
return arr;
}
Your not building the data correctly, and it needs to be
var compositionData = generateCompositionForSave();
var data = $('form').serializeObject(); // see function below
data['FabricCompositions'] = compositionData; // add the array to the serialized data
var data2 = JSON.stringify({ collection: data }), // stringify it
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8", // add contentType
dataType: 'json' ,
cache: false,
url: '#Url.Action("Edit", "ItemMaster")', // don't hard code your url's
data: data2,
success: function (data, textStatus, jqXHR) {
....
And add the following function (warning: this will not work correctly for a <select multiple> element)
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] === undefined) {
o[this.name] = this.value || '';
}
});
return o;
};
Note that if you generate your form controls correctly using a for loop or custom EditorTemplate for typeof FabricCompositionInputModel (refer Post an HTML Table to ADO.NET DataTable), for example
for(int i = 0; i < Model.FabricCompositions.Count; i++)
{
#Html.TextBoxFor(m => m.FabricCompositions[i].CompositionCode)
#Html.TextBoxFor(m => m.FabricCompositions[i].Value)
}
then all that is required is
var data = $('form').serialize();
$.ajax({
type: 'POST',
dataType: 'json' ,
cache: false,
url: '#Url.Action("Edit", "ItemMaster")',
data: data,
success: function (data, textStatus, jqXHR) {

jQuery cannot deserialize json object

i have this return come from here
public string Get(int id)
{
return "{\"longPachage\":{\"Id\":0}}";
}
and i Receive this return by ajax with this code
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: "http://localhost:3148/api/values/5",
success: function (data) {
alert(data);
alert(" Success ");
},
error: function (data) {
alert(" Error ");
}
})
what i can to deserialize json object and print the Id value only ?
You can use this code. It may be help to you.
You are not parse the data to get JSON in string format. So you can now use this code to get JSON data in string format.
var obj = JSON.parse(data);
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: "http://localhost:3148/api/values/5",
success: function (data) {
var obj = JSON.parse(data);
alert(obj.Id);
alert(" Success ");
},
error: function (data) {
alert(" Error ");
}
})
yes, Stephen is right.
you have to send a json result from controller.
for exa.
public JsonResult Get(int id)
{
return Json(new
{
longPachage = new { ID = 0 }
}, JsonRequestBehavior.AllowGet);
}
and in your ajax success, just retrieve that object or dataID.
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: "http://localhost:3148/api/values/5",
success: function (data) {
var dataID = data.longPachage.Id;
// Do with Your ID.
},
error: function (data) {
//Do anything for error here.
}
})
Change your method like this:
public ActionResult Get(int? id)
{
return Content("{\"longPachage\":{\"Id\":0}}");
}
And then in your jQuery:
$.getJSON("http://localhost:3148/api/values", {id:5}, function(data) {
var id = data.longPachage.Id;
alert(id)
});
Try to use JsonResult in MVC to return Json instead of building a string. JsonResult is just an abstact class of ActionResult. Modify your code in the controller as follows
Method 1:
public JsonResult GetTest(int id)
{
return this.Json(new { ID = 0 }, JsonRequestBehavior.AllowGet);
}
OR
Method 2:
Try to create a model class as LongPachage
public class LongPachage()
{
public int ID {get;set;}
}
and try to invoke into the controller method as follows
public JsonResult Get(int id)
{
LongPachage model = new LongPachage();
model.ID = 0;
return this.Json(model, JsonRequestBehavior.AllowGet);
}
OR
Method 3
Create Model class say TestModel and try to add LongPachage class as propery of this class.
public class TestModel()
{
public LongPachage LongPachage {get;set;}
}
and try to invoke into the controller method as follows
public JsonResult Get(int id)
{
TestModel model = new TestModel();
model.LongPachage .ID = 0;
return this.Json(model, JsonRequestBehavior.AllowGet);
}
and then in the view using AJAX GET wrapper try to implement as follows
$.get('#Url.Action("Get","ControllerName")', { id: "5" })
.done(function (data) {
// If you are using Method 1 or Method 2 alert will be as follows
alert(data.ID);
// If you are using method 3
alert(data.LongPachage.ID)
});

jQuery Datatables webforms call

I am trying to use Datatables within my webforms application.
unfortunatly I get the whole html page instead of json data :'(
this is my code.
<script type="text/javascript">
$(document).ready(function () {
$('#grid').dataTable({
"dataType": 'JSON',
"bServerSide": true,
"sAjaxSource": 'GategoriesManagement.aspx/GetPersonList',
"bProcessing": true,
"aoColumns": [
{ "sName": "d.name" },
]
});
});
</script>
my webmethod
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string GetPersonList()
{
List<personne> personeList = new List<personne>();
personne person = new personne();
person.name = "test1";
personeList.Add(person);
person = new personne();
person.name = "test2";
person = new personne();
person.name = "test3";
personeList.Add(person);
FormatedList list = new FormatedList();
list.iTotalDisplayRecords = 10;
list.iTotalRecords = 200;
list.aaData = personeList;
var javaScriptSerializer = new JavaScriptSerializer();
string jsonString = javaScriptSerializer.Serialize(list);
return jsonString;
}
and this is the alert that I get in the browser
DataTables warning: table id={id} - Ajax error
it appear that my webmethod is not accessible
what should I do ???
The magic piece of code which makes this work as of 1.10.12 is the ajax parameter. ASP.NET wraps JSON results in the .d property, so you need to execute the callback on that object.
$('#tableId').dataTable(
{
"processing": true,
"serverSide": true,
"stateSave": false,
"lengthMenu": [[10, 30, 100, -1], [10, 30, 100, "All"]], // 1st = page length values, 2nd = displayed options
ajax: function (data, callback, settings) {
$.ajax({
url: "/UserService.asmx/GetUsers",
type: 'POST',
contentType: 'application/json',
dataType: "json",
data: JSON.stringify(data),
success: function (data) {
$spinner.hide();
callback(data.d); // execute the callback function on the wrapped data
}
});
},
I really liked #Echilon answer, but I'd like to add that it's possible to send the Ajax request as GET too.
Having said that, and although OP's example didn't include a parameter in the GetPersonList() method, I'd like to show how parameters would need to be sent on an Ajax request depending if it's a GET or POST** request:
POST request
It doesn't matter if the value is of type int, string, boolean or an object, the way to send data is the same that #Echilon showed. Although here's a little variation:
data: function (data) {
data.parameterName = value;
return JSON.stringify(data);
}
And here's a brief example. Let's suppose that this is your original method:
[WebMethod]
//The parameter could be a int, string or bool
public static string GetPersonList(int|string|bool value)
{
//do something here...
}
And in your Ajax call:
$('#tableId').dataTable(
{
//your DataTable options here
$.ajax({
url: "/UserService.asmx/GetUsers",
type: 'POST',
contentType: 'application/json; charset=utf-8',
//dataType: "json", only include this if you're expecting the result in json format
data: function (data) {
data.value = 10|"Test"|false; //Send the appropriate data according to the parameter type in your method
return JSON.stringify(data);
},
dataSrc: "d.data" //DON'T forget to include this or your table won't load the data
},
// your columns settings here
});
In case you need to send an object here's a brief example. Let's suppose that this is your original method:
class Person
{
public int Id { get; set; }
public string UserName { get; set; }
}
[WebMethod]
public static string GetPersonList(Person person)
{
//do something here...
}
Then in your Ajax call:
var $person = {};
$person.Id = 9;
$person.UserName = "jsmith";
$('#tableId').dataTable(
{
//your DataTable options here
$.ajax({
url: "/UserService.asmx/GetUsers",
type: 'POST',
contentType: 'application/json; charset=utf-8',
//dataType: "json", only include this if you're expecting the result in json format
data: function (data) {
data.person = $person;
return JSON.stringify(data);
},
dataSrc: "d.data" //DON'T forget to include this or your table won't load the data
},
// your columns settings here
});
GET request
If you prefer to use a GET request, then the way to send the data varies a little. If the value is of type int or boolean, you can send it like this:
data: function (data) {
data.parameterName = value;
return data;
}
But if you want to send a string or an object, then you can send it like this:
data: function (data) {
data.parameterName = JSON.stringify(value);
return data;
}
Let's see a brief example. Let's suppose that this is your original method:
[WebMethod]
[ScriptMethod(UseHttpGet = true)] // I didn't include the ResponseFormat parameter because its default value is json
//The parameter could be a int or bool
public static string GetPersonList(int|bool value)
{
//do something here...
}
And in your Ajax call:
$('#tableId').dataTable(
{
//your DataTable options here
$.ajax({
url: "/UserService.asmx/GetUsers",
type: 'GET',
contentType: 'application/json; charset=utf-8',
//dataType: "json", only include this if you're expecting the result in json format
data: function (data) {
data.value = 10|false; //Send the appropriate data according to the parameter type in your method
return data;
},
dataSrc: "d.data" //DON'T forget to include this or your table won't load the data
},
// your columns settings here
});
In case you need to send a string or an object here's a brief example. Let's suppose that this is your original method:
class Person
{
public int Id { get; set; }
public string UserName { get; set; }
}
[WebMethod]
[ScriptMethod(UseHttpGet = true)] // I didn't include the ResponseFormat parameter because its default value is json
//The parameter could be an object or a string
public static string GetPersonList(Person person) // or (string value)
{
//do something here...
}
Then in your Ajax call:
var $person = {};
$person.Id = 9;
$person.UserName = "jsmith";
$('#tableId').dataTable(
{
//your DataTable options here
$.ajax({
url: "/UserService.asmx/GetUsers",
type: 'GET',
contentType: 'application/json; charset=utf-8',
//dataType: "json", only include this if you're expecting the result in json format
data: function (data) {
data.person = JSON.stringify($country);
//data.value = JSON.stringify("Test"); Or this one, depending the parameter of your method
return data;
},
dataSrc: "d.data" //DON'T forget to include this or your table won't load the data
},
// your columns settings here
});

Send FormData using Jquery-Ajax to C# Web-Api

I have the following function:
public class UserRequest
{
public string RequestMessage { get; set; }
public HttpPostedFileBase Photo { get; set; }
}
public void CreateRequest(UserRequest userRequest)
{
}
When I post to this function with the following script the posted image is always null:
var requestMessage = document.getElementById("txtReqMessage").value;
var inputFile = document.getElementById("reqphoto");
var imageFile = inputFile.files[0];
$.ajax({
type: "POST",
url: "/UserRequest/CreateRequest/",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
"RequestMessage": requestMessage,
"Photo": imageFile
}),
success: function () {
alert("Success");
}
I read about posting complex data so I changed the script to:
var requestMessage = document.getElementById("txtReqMessage").value;
var inputFile = document.getElementById("reqphoto");
var imageFile = inputFile.files[0];
var formData = new FormData();
formData.append("RequestMessage", requestMessage);
formData.append("Photo", imageFile);
$.ajax({
type: "POST",
url: "/UserRequest/CreateRequest/",
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: function () {
alert("Success");
}
});
But now something is wrong I get Error 500.
I changed it to this:
public void CreateRequest()
{
var httpRequest = HttpContext.Current.Request;
var userRequest = new UserRequest
{
RequestMessage = httpRequest.Form["RequestMessage"],
Photo = httpRequest.Files["RequestPhoto"],
};
}
var formData = new FormData();
formData.append("RequestMessage", requestMessage);
formData.append("RequestPhoto", imageFile);
$.ajax({
type: "POST",
url: "/UserRequest/CreateRequest",
data: formData,
processData: false,
success: function () {
alert("OK");
},
error: function () {
alert("Error");
}
});
define the method as web method
[WebMethod]
public void CreateRequest(UserRequest userRequest)
{
}
you should read data in a FormDataCollection
public void CreateRequest(FormDataCollection form)
{
}
try changing contentType ajax property to
contentType: 'multipart/form-data'
you are using false value that should be used only when you are sending files

Categories

Resources