C# WebMethod - Send and receive same custom object as parameter - javascript

mycode:
object:
public class Person
{
private string _Nome;
private DateTime _Nascimento;
public string Nome { get { return _Nome; } }
public DateTime Nascimento { get { return _Nascimento; } }
public Person(string Nome, DateTime Nascimento)
{
_Nome = Nome;
_Nascimento = Nascimento;
}
}
page (WebMethods):
[WebMethod]
public static Person SendPerson()
{
return new Person("Jhon Snow", DateTime.Now);
}
[WebMethod]
public static string ReceivePerson(Person oPerson)
{
return "OK!";
}
javascript:
var Person;
GetPerson();
SendPersonBack();
function GetPerson()
{
$.ajax({
type: "POST",
url: "frmVenda.aspx/SendPerson",
data: {},
contentType: "application/json; charset=utf-8",
success: function (RequestReturn) {
Person = RequestReturn.d;
console.log(Person);
},
error: function (error) {
alert(error.statusText);
}
});
}
function SendPersonBack()
{
$.ajax({
type: "POST",
url: "frmVenda.aspx/ReceivePerson",
data: JSON.stringify({"oPerson": Person}),
contentType: "application/json; charset=utf-8",
success: function (RequestReturn) {
alert(RequestReturn.d);
},
error: function (error) {
alert(error.statusText);
}
});
}
I send the object to the clientside normally, but can not receive it back to server.
Why can not receive it back if the object is the same and their properties as well.
where is the problem?

Looking at the very link provided by you is possible to notice the problem.
Your code: data: JSON.stringify({"oPerson": Person}),
Right code: data: "{oPerson:" + JSON.stringify(Person) + "}",
It seems to me that you're sending a bad formatted Json to the server
Also, try adding dataType: 'json' to your call.

I solved the problem by creating a constructor with no parameters , setting all properties as string and adding the set method on all properties on my custom object (Person).
public class Person
{
private string _Nome;
private string _Nascimento;
public string Nome { get { return _Nome; } set { _Nome = value; } }
public string Nascimento { get { return _Nascimento; } set { _Nascimento= value; } }
public Person()
{
}
public Person(string Nome, DateTime Nascimento)
{
_Nome = Nome;
_Nascimento = Nascimento.ToString();
}
}

You are returning an object from webService, but your content type in ajax is json! You should create data in json format in both of your methods and return a string not object:
[WebMethod]
public static static SendPerson()
{
JavaScriptSerializer TheSerializer = new JavaScriptSerializer();
return TheSerializer.Serialize(new Person("Jhon Snow", DateTime.Now));
}
For second method just remove content-type from ajax or replace it by :
application/x-www-form-urlencoded; charset=UTF-8

Related

Return parameter null in controller from ajax

I don't know what happened the value sent to the controller is always null, even though in the console.log the value is there, please I need help
this is my ajax:
$('#ddlItemName').change(function () {
var ItemCode = $('#ddlItemName').text();
if (ItemCode != '') {
var RequestParam = {
search: ItemCode
}
console.log(RequestParam);
$.ajax({
url: '/Order/CustomerItemOrders',
type: 'POST',
data: JSON.stringify(RequestParam),
contentType: 'application/json; charset=utf-8',
success: function (data) {
alert(data[0].Name);
},
error: function (data) {
toastr.error(data);
}
});
}
$('#ddlItemName').text('');
});
This is my controller :
[HttpPost]
public JsonResult CustomerItemOrders([FromBody] string search)
{
var result = _order.BindCustomerOrders(search);
return Json(result.data);
}
This is my error :
enter image description here
I've tried adding '[FromBody]' but the value parameter still doesn't get sent
I recomend you add the parameter to query
If you insist on pass the value with request body
Try creat a model:
public class SomeModel
{
public string search{get;set;}
}
in your controller:
public JsonResult CustomerItemOrders([FromBody] SomeModel somemodel)
{
.......
}

What's the correct way to create class in JavaScript and pass that to MVC controller

I have a complex form with different tabs, so my ask is to save the entire form data to database on final save. I have the models as per my database as follows, posting sample class
public class VesselDetail
{
public string VesselName { get; set; }
}
public class MainModel
{
public VesselDetail VesselDetail { get; set; }
}
I have created JavaScript models as follows
class VesselDetail {
constructor() {
}
VesselName;
}
class MainModel {
constructor() {
this.VesselDetail = [];
}
}
On my save I am framing the data as follows
let data = new MainModel();
let vesselDetail = new VesselDetail();
vesselDetail.VesselName = "XYZ";
data.VesselDetail.push(vesselDetail);
$.ajax({
url: '/Controller/SaveFormData',
type: 'POST',
data: '{mainModel: ' + JSON.stringify(data) + '}',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
hideSpinner();
},
error: function (request) {
hideSpinner();
}
});
My controller is as follows
[HttpPost]
public JsonResult PostUserData(MainModel mainModel)
{
return new JsonResult { Data = "OK" };
}
Somehow I am unable to see the vessel name that was given. I would like to know are my JavaScript models are correct or should I do any changes? Any better idea to make these models in JavaScript.
Don't hand-construct JSON, it's really easy to get it wrong. In this case, you haven't put the necessary " around mainModel in the JSON you're sending the server, which makes it invalid. As a result, the server won't be able to parse the JSON it receives.
$.ajax({
url: '/Controller/SaveFormData',
type: 'POST',
data: '{mainModel: ' + JSON.stringify(data) + '}',
// ^−−−−−−−−^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− missing quotes
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
hideSpinner();
},
error: function (request) {
hideSpinner();
}
});
Instead, let JSON.stringify do it for you:
$.ajax({
url: '/Controller/SaveFormData',
type: 'POST',
data: JSON.stringify({mainModel: data}),
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
hideSpinner();
},
error: function (request) {
hideSpinner();
}
});
Also, unless your server is returning JSON you're not using, you don't need dataType. (Even if it is, it should be returning the correct Content-Type header in which case dataType is redundant anyway.)
I also suggest either consistently using property declaration syntax (which is fairly new) or consistently not using it:
Not using it:
class VesselDetail {
}
class MainModel {
constructor() {
this.VesselDetail = [];
}
}
Using it:
class VesselDetail {
VesselName;
}
class MainModel {
VesselDetail = [];
}
Here's an example of the JSON that will be produced by your code with the changes above (I've used property declaration syntax — the second set of classes above — but they'll both produce the same thing):
class VesselDetail {
VesselName;
}
class MainModel {
VesselDetail = [];
}
let data = new MainModel();
let vesselDetail = new VesselDetail();
vesselDetail.VesselName = "XYZ";
data.VesselDetail.push(vesselDetail);
const json = JSON.stringify({mainModel: data});
console.log(json);
As you can see, VesselName is not blank.
try this, it was tested in VS2019 and working properly
var mainModel= { VesselDetail : { VesselName :"XYZ"} };
$.ajax({
url: '/Controller/PostUserData',
type: 'POST',
data: { mainModel: mainModel),
success: function (result) {
hideSpinner();
alert(JSON.stringify(result));
},
error: function (request) {
hideSpinner();
}
});
and fix VesselDetail class by adding setter and getter
public class VesselDetail
{
public string VesselName { get; set;}
}
And I see a bug in your action. What is a Data?
return new JsonResult { Data = "OK" };
try this
return new JsonResult(mainModel.VesselDetail.VesselName);
but if you like it a hard way you can try this
class VesselDetail {
VesselName;
}
class MainModel {
VesselDetail = {};
}
let mainModel= new MainModel();
data.VesselDetail.VesselName="XYZ";
UPDATE
Sometimes this working better, depending on net version or if you are using API controller
var mainModel= { VesselDetail : { VesselName :"XYZ"} };
$.ajax({
url: '/Controller/PostUserData',
type: 'POST',
data: JSON.stringify(mainModel),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
hideSpinner();
alert(JSON.stringify(result));
},
error: function (request) {
hideSpinner();
}
});
but you have to add [FromBody] to action
[HttpPost]
public JsonResult PostUserData([FromBody] MainModel mainModel)
{
return new JsonResult(mainModel.VesselDetail.VesselName);
}
you put the VesselName out of the builder
should be like this
class VesselDetail {
constructor() {
this.VesselName;
}
}
class MainModel {
constructor() {
this.VesselDetail = [];
}
}

Failed to load resource: the server responded with a status of 405

When trying to call an ASP.NET method from the client using $.ajax it gives the following error "Failed to load resource: the server responded with a status of 405 ()" knowing that the client and the API are both running on the same domain "localhost:4500", I followed the procedure I found in this Microsoft docs "https://learn.microsoft.com/en-us/aspnet/core/tutorials/web-api-javascript?view=aspnetcore-5.0 " and added the wwwroot folder to avoid the CORS issue but still can't call the API methods through the $.ajax method in javascript.
I tested the backend code through swagger and it was working just fine.
this my backend controller code:
[ApiController]
[Route("api/[Controller]")]
public class RunAnalysisController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok();
}
[HttpPost("LoadFramesData")]
public IActionResult LoadFrameData([FromBody]RootObject ModelData)
{
try
{
ManageModel.CreateModel(ModelData);
return Ok(ModelData); //returning same object for testing purpose
}
catch
{
return BadRequest("Error");
}
}
}
and this my ajax function in the client side:
$.ajax({
type: "POST",
url: "api/RunAnalysis/LoadFramesData", ///// URL must be specified
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(new RootData()), //this class returns a json object
cache: false,
success: function (result) {
console.log(result);
},
error: function (ex) {
WriteToConsole(ex.responseText);
}
});
As mentioned in the comments, the issue relates the request url, change the url as below: url: "/api/RunAnalysis/LoadFramesData.
More detail information, you could refer the following sample:
Model:
public class RootObject
{
public int ID { get; set; }
public string Name { get; set; }
}
MVC View Page:
<input type="button" id="btnsubmit" value="Click Me" />
#section Scripts{
<script>
$(function () {
// LoadChart();
class RootData {
constructor(id, name) {
this.ID = id;
this.Name = name;
}
}
$("#btnsubmit").click(function () {
//var data = {};
//data.ID = "1001";
//data.Name = "Tom";
$.ajax({
type: "POST",
url: "/api/todo/LoadFramesData", ///// URL must be specified
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(new RootData(1001, "Tom")), //this class returns a json object
cache: false,
success: function (result) {
alert(result.name);
},
error: function (ex) {
alert(ex.responseText);
}
});
});
});
</script>
}
API upload method:
[Route("api/[controller]")]
[ApiController]
public class TodoController : ControllerBase
{
[HttpPost("LoadFramesData")]
public IActionResult LoadFrameData([FromBody] RootObject ModelData)
{
try
{
return Ok(ModelData);
}
catch
{
return BadRequest("Error");
}
}
The result as below:

ASP.NET: Ajax doesn't send string

I have this method to send some data with ajax:
function SendData(foodID, basketID) {
var data = { FoodID: foodID, BasketID: basketID };
$.ajax({
url: '/Order/Post',
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json;utf-8',
datatype: 'json'
}).done(function (data) {
console.log(data);
}).fail(function (data) {
console.log("Error: " + data);
});
}
In C#, my Post Method in my Order controller gets triggered, but the string I want to hand over is null:
public bool Post(string s)
{
//When this gets executed, s is null
return true;
}
I tested this by executing SendData(1,1) directly on a button click. What is the mistake I'm doing and how can I get the string in my Post-Method?
you are post the object. not string.
you can try generate to object and load this object. or add new one parameter to action (foodId and basketId but you must post like that if you check this option data:{foodId,basketId})
//model
public class SomeObject{
public string FoodId {get;set;}
public string BasketId {get;set;}
}
//code
public bool Post(SomeObject data)
{
return true;
}
It seems for me your data structure to the Post action doesn't match action parameter names. Try this:
[HttpPost]
public bool Post(string foodID, string baskedID)
{
return true;
}
I believe you have to name your data that's being passed like so:
data: { 's': JSON.stringify(data) }

Ajax POST and Stringify Confusion

I am learning about POST with Ajax and I've noticed a lot of examples using stringify on static arrays.
In my example I am building array via jQuery objects extracted from <input> values.
Jquery
function PostEdit(vData){
var content = JSON.stringify(vData); //content = "[{"Id":"1","Date":"7/12/2017 12:00:00 AM"}]"
$.ajax({
url: '#Url.Action("Index", "PostViewData")',
type: "POST",
data: JSON.stringify({ ViewData : vData }),
contentType: "application/json",
success: function (result) {
alert("success" + result);
},
error: function (result) {
alert("failure" + result);
}
});
return;
}
Controller
[HttpPost]
public ActionResult Index(List<DataViewModel> ViewData )
{
if(ViewData != null)
{
var json = new { success = true };
return Json(json);
}
return Json(false);
}
ViewModel
public class DataViewModel
{
public DataViewModel(string id, string date)
{
Id = id;
Date = date;
}
public string Id { get; set; }
public string Date { get; set; }
}
Where DataViewModel is a class that consists of two values, Id, and Date which correspond to my JS object.
Since vData enters the function as value vData = [Object], When I call .stringify(vData) it returns content = "[{"Id":"1","Date":"7/12/2017 12:00:00 AM"}]"
The value of content above is how I see most examples structured before stringify such as the example here.
Once in this format, this is when most responses, examples call stringify anyway.
Now when I call .stringify(ViewData : vData) I dont even make it to the controller. Ajax fails to post. On the contrary when I call .stringify(ViewData : content), I make it to the controller, but with a null value. What am I missing / misunderstanding?
I'm looking for a better explanation of Ajax Post and Stringify, and how it interacts with the controller parameter.
Just add parameterless constructor to your model. With that change, your code will work as it is. ASP is unable to parse your json as DataViewModel since it's trying to call default constructor that doesn't exists.
public class DataViewModel
{
public DataViewModel()
{
}
//...other methods and members here
}
Please try the solution below.
There's another way of doing this
function PostEdit(vId, vDate){
$.ajax({
url: '/PostViewData/Index' // it should be '/controller/method'
type: "POST",
data: JSON.stringify({ Id: vId, Date: vDate}),
contentType: "application/json",
success: function (result) {
alert("success" + result);
},
error: function (result) {
alert("failure" + result);
}
});
return;
}
[HttpPost]
public ActionResult Index(string Id, string Date )
{
if(Id != null)
{
var json = new { success = true };
return Json(json);
}
return Json(false);
}
Update: In the controller method, it should be string id, string date
Update: The constructor should be parameterless. From the answer mentioned below
public DataViewModel()
{
}

Categories

Resources