Can I post a JSON model from html.raw to controller? - ajax

I have a model I am passing to a view and using Html.Raw to encode it into a JSON object:
var model = #Html.Raw(Json.Encode(Model));
On the page I fill various portions of the model from fields in the page:
model.ProductId = $("#txtProductId").val();
and then try to post it to the controller that way with ajax:
$.ajax({
type: 'POST',
url: '#Utl.Action("AddProducts"),
data: JSON.stringify(model),
dataType: 'json',
//etc
but it is never making it to the controller method:
[HttpPost]
public ActionResult AddProducts(ProductModel, model)
{
//do stuff with the model data
}
Can anyone help me out here and explain how I have to changs things to get the model to post?
My models, simplified:
public class OrderModel {
public ProductModel Product {get;set;}
public PersonModel Person {get;set;}
public List<ProductModel> Products {get;set;}
}
public class ProductModel {
public string Partno {get;set;}
public int Quantity {get;set;}
/// etc
}
public class PersonModel {
public string Surname {get;set;}
public string GivenName {get;set;}
public string Address {get;set;}
/// etc
}

Change you code to
$.ajax({
type: 'POST',
url: '#Url.Action("AddProducts")',
data: model, // not stringified
dataType: 'json',
....
or
$.post('#Url.Action("AddProducts")', model, function(data) {
// do stuff with returned data
});
which will post back to
[HttpPost]
public ActionResult AddProducts(ProductModel model)
{
//do stuff with the model data
}
assuming the model in your view is ProductModel
However, if your just wanting to post back the form, you can use var model = $('form').serialize(); rather than manually setting the properties of the object.

Related

In ASP.NET Core 6 MVC - passing list of object to controller with model object

I have a model class like this:
public class DataModel
{
public int CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public List<ViewModel> ViewModel { get; set; }
}
public class ViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
In ASP.NET Core 6.0 MVC, from js file posting data as shown here:
let postedModel = {
CreatedBy :null,
CreatedDate :null,
ViewModel : []
}
postedModel.CreatedBy = "some id";
postedModel.CreatedDate = "today date"
$(".form-fieldset").each(function () {
let formObject = {};
$('form').find('input').each(function (index, element) {
//In cshtml Name attribute given without form index
formObject[$(element).attr('name')] = $(element).val();
})
postedModel.ViewModel.push(formObject)
}
$.ajax({
url: '/ApiController/SaveData',
type: 'POST',
crossDomain: true,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(postedModel),
async: false
})
My api controller looks like this:
public async Task<IActionResult> SaveData([FromBody] DataModel postedModel)
{
}
but I am getting null in the api controller.
What am I doing wrong? Please help.

Web API model binding not working

Why is Web API model binding so complicated by default:
I tried a lot of combinations but none of them seem to work.
This is ajax request:
var dataString = JSON.stringify({
request: Request
});
var request = Request;
$.ajax({
type: "POST",
data: '='+dataString,
// contentType: 'application/x-www-form-urlencoded',
contentType: "application/json; charset=utf-8",
dataType: "json",
This is controller:
public AccResultObject Post(string jezik, string page, string size, string sort,AccRequestViewModel model)
This is AccRequestViewModel
public class AccRequestViewModel
{
public AccRequestObject request { get; set; }
}
and this is AccRequestObject:
public class AccRequestObject
{
public int FM { get; set; }
public int Budget { get; set; }
public string WebCatID { get; set; }
public int Distance { get; set; }
}
Whatever I do, controller gets null value.
I tried this also. It seems very logical:
var dataString = JSON.stringify({
request: Request
});
$.ajax({
type: "POST",
data: dataString, ...
and controller receives AccRequestObject:
public AccResultObject Post(string jezik, string page, string size, string sort,[FromBody] AccRequestObjectmodel)
It works great except this small problem. Values are not binded.
Make sure the properties of each object you are creating in javascript match exactly to the code model. If a property name is uppercase in the code model, it needs to be uppercase in the js. Other than that, to post a model with jquery to a Web Api controller is pretty simple:
//code model
public class MyModel{
public int MyProperty{get;set;}
}
//js
$.ajax({
contentType: "application/json",
dataType: 'json',
url: 'http://api/to/my/controller',
data: JSON.stringify({MyProperty: 1}),
type: "POST"
});
In the C#, make sure your properties are public properties, not fields.
public class MyBindingModel
{
public string myProp{ get; set; }
}

AJAX post to asp.net MVC controller method not working

I have this method in my controller:
[HttpPost]
public ActionResult Create(StatusMessage statusMessage, int foreignKey, int statusMessageType)
{
//Do something
}
This is how my StatusMessage model looks like:
public abstract class StatusMessage
{
[Key]
public int Id { get; set; }
/// <summary>
/// Message
/// </summary>
/// [Required]
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public int UseraccountId { get; set; }
public virtual Useraccount Useraccount { get; set; }
}
And I'd like to send a post via jquery ajax to my controller:
function sendForm(message, foreignKey, statusMessageType, target) {
var statusMessage = {
Description: "This is a test message"
};
$.ajax({
url: target,
type: "POST",
contentType: 'application/json',
data: JSON.stringify({
statusMessage: statusMessage,
foreignKey: foreignKey,
statusMessageType: statusMessageType
}),
success: ajaxOnSuccess,
error: function (jqXHR, exception) {
alert(exception);
}
});
}
But the POST isn't sent correctly.
Through testing I figured already out that the problem is the StatusMessage class. If I replace it by a string, everything is working fine.
Why you have defined your class as abstract, controller won't be able to create its instance
Define you class as
public class StatusMessage
for info http://www.codeproject.com/Articles/6118/All-about-abstract-classes
Your ajax post is not working because StatusMessage is an abstract class and you (or the controller) cannot create an instance of it. You should either make it a concrete class or derive another class from it.

IModelBinder not firing on MVC 3

I have this Controller:
[HttpPost]
public JsonResult Execute(PaymentModel paymentModel){...}
this is the model
public class PaymentModel
{
[Required]
[DisplayName("Full name")]
public string FullName { get; set; }
...
}
this is the binding action
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.Add(typeof(PaymentModel), new PaymentModelsBinding());
}
this is the binding inplementation
public class PaymentModelsBinding : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
//Cant get to here with the debugger
}
I dont know if that is relevant or not, but I am injecting using Ninject to the controller constructor.
Update
This is how the form is submitted:
$.ajax({
type: 'POST',
url: $("#form").attr("action"),
data: $("#form").serialize(),
success: function (json) {
...
},
dataType: "Json"
});
I want that to be restful, meaning I will to call it in every possible WEB way.
Browser Ajax, Browser Classic form submission, WebClient... and more.
Update
This is my ninject code:
kernel.Components.Add<IInjectionHeuristic, CustomInjectionHeuristic>();
kernel.Bind<IPaymentMethodFactory>().ToProvider<PaymentMethodFactoryProvider>().InSingletonScope();
kernel.Bind<IDefaultBll>().To<DefaultBll>().InSingletonScope();
kernel
.Bind<IDalSession>()
.ToProvider<HttpDalSessionProvider>()
.InRequestScope();
Thanks
Sorry, I can't see anything wrong with your code. This should work. And as a proof of concept, here's what you could try:
Create a new ASP.NET MVC 3 application using the Internet Template
Define a view model:
public class PaymentModel
{
[Required]
[DisplayName("Full name")]
public string FullName { get; set; }
}
A custom model binder:
public class PaymentModelsBinding : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return new PaymentModel();
}
}
HomeController:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new PaymentModel());
}
[HttpPost]
public ActionResult Index(PaymentModel model)
{
return Json(new { success = true });
}
}
A corresponding view (~/Views/Home/Index.cshtml):
#model PaymentModel
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "form" }))
{
#Html.EditorFor(x => x.FullName)
<button type="submit">OK</button>
}
<script type="text/javascript">
$('#form').submit(function () {
$.ajax({
type: this.method,
url: this.action,
data: $(this).serialize(),
success: function (json) {
}
});
return false;
});
</script>
And finally register the model binder in Application_Start:
ModelBinders.Binders.Add(typeof(PaymentModel), new PaymentModelsBinding());
Run the application in Debug mode, submit the form and the custom model binder gets hit.
So the question now becomes: what did you do differently?

can't pass data to controller via ajax

I have the following model class:
[Serializable]
public class SearchHomeModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
public string Title { get; set; }
}
I have the following controller code:
public ActionResult DataTableUserList(SearchHomeModel search, UserListType type, int iDisplayStart, int iDisplayLength, string sEcho)
and the following client part:
var search = {};
search.FirstName = 'aa';
search.LastName = 'bb';
search.Company = 'kkk';
search.Title = 'aaaawww';
fnServerData: function (sSource, aoData, fnCallback) {
aoData.push({ "name": "type", "value": "All" });
aoData.push({ "name": "search", "value": search });
$.ajax({
dataType: 'json',
type: "POST",
url: sSource,
data: aoData,
but I look at debugger on server-side I see that type="All" (it's correct), but search is null. Why and how to pass data to search object from ajax?
You may or may not find this useful, but I did this so I could directly pass JSON back and forth from the controller. I had come across this approach HERE while playing around with Knockout.js.
I created this attribute
public class FromJsonAttribute : CustomModelBinderAttribute
{
private readonly static JavaScriptSerializer serializer = new JavaScriptSerializer();
public override IModelBinder GetBinder()
{
return new JsonModelBinder();
}
private class JsonModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var stringified = controllerContext.HttpContext.Request[bindingContext.ModelName];
if (string.IsNullOrEmpty(stringified))
return null;
return serializer.Deserialize(stringified, bindingContext.ModelType);
}
}
}
This is my controller code:
[HttpPost]
public ActionResult Gifts([FromJson] List<GiftModel> gifts, [FromJson] string guid)
{
}

Resources