Posting/Binding multiple forms on backend ASP.NET MVC (MEF) - javascript

We are trying to send multiple forms with one Ajax (jQuery) Call to an ASP application.
We use the following jQuery code:
var formContainer = {
Form1 : form1.serialize(),
Form2 : form2.serialize()
}
$.ajax({
type: "POST",
url: '#Url.Action("CreateModel", "Controller")',
data: formContainer,
success: function (result) { }
});
On the server we receive the following in the Request.Form property:
Key : Value
Form1 : All serialized form elements for Form1
Form2 : All serialized form elements for Form2
Normally we use the following method so ASP is automaticly creating the object with the right property value:
public ActionResult CreateModel(ClassForForm1 obj)
But because the two forms are send together the modelbinder cannot bind and build the class.
So for this action we want the modelbuilder to use the values in Request.Form["Form1"].
We can't use a custom modelbinder, because we use an extern library (DevExpress ,they wrote an own implementation above this).
We are using the MEF framework to add functionalities (these functionalities are added as forms on the view). For this reason we do not know what too expect on the backend. So writing a wrapper ViewModel is not acceptable.
The functionality for proccessing the other forms data will be handeled inside other modules.
Any solutions are welcome!
Thanks in advance.

This is typically done using a combined view model. Otherwise, you would need to manually parse the request parameters. Here is a fiddle showing how to combine the data from multiple forms.
$(function() {
$('button').click(function(e) {
var form1 = $('#form1');
var form2 = $('#form2');
$.ajax({
type: "POST",
url: '/echo/html/',
data: form1.serialize()+"&"+form2.serialize(),
success: function (result) {
alert(result);
}
});
});
});
On the server, your view model would require:
public class IndexViewModel {
// properties from form1
public string first { get; set; }
// properties from form2
public string last { get; set; }
}
public class First {
public string first { get; set; }
}
public class Last {
public string last { get; set; }
}
And your action signature:
[HttpPost]
public ActionResult Index(IndexViewModel model) {
var firstModel = (new First()).CloneMatching(model);
var lastModel = (new Last()).CloneMatching(model);
return RedirectToAction("Thanks");
}
See Best way to clone properties of disparate objects for the CloneMatching extension method.

If you create you javascript object like this:
var formContainer = { obj : {
Form1 : form1.serialize(),
Form2 : form2.serialize()
}
}
The controller should match it up with the name 'obj' you created in the javascript with the 'obj' in your method....
public ActionResult CreateModel(ClassForForm1 obj)

My previous sample worked just because my class has name and value props. I'm realy sorry for that. But now you can see working DEMO
JS
function mapForm(form)
{
var result = {};
$.map($(form).serializeArray(),
function(el){
mapFormProperty(result, el);
});
return result;
}
function mapFormProperty(form, property)
{
form[property.name] = property.value;
}
$('.submit').click(function(){
var form1 = mapForm($('#form1'));
var form2 = mapForm($('#form2'));
var formContainer = {
'Form1': form1,
'Form2': form2};
$.ajax({
type: "POST",
url: '#Url.Action("CreateModel", "Controller")',
data: JSON.stringify(formContainer),
success: function (result) { }
});
Operations with forms and form container should give you next json string
"{"Form1":{"Prop1":"Value1","Prop2":"Value2"},"Form2":{"Prop1":"Value1","Prop2":"Value2"}}"
And your model binder will be able solve this, if you change your action signature
Action
public ActionResult CreateModel(ClassForForm1 Form1) //argument name must be equal to data property
//but not equal to class name
And it should work. it works in my test sample

Related

Ajax call in Razor View sends null data in controller method?

I'm trying to make a simple post call in a controller method using an ajax call from a razor view.The ajax call does call the controller method but it does not send the object from that I'm trying to send.I tried multiple solutions from Stackoverflow without success including using Json.stringify() method and using the [HttpPost] attribute in controller method.I also have the name of the object from View the same as the name of the controller method parameter.This is the script where I make the Ajax call:
<script>
$(document).ready(function () {
$('.send-all').on('click', function() {
var data = $('#verticalScroll tr').map(function () {
var $row = $(this);
return {
id: $row.find('.id').text().trim(),
companyName: $row.find('.companyname').text().trim(),
price: $row.find('.price').text().trim(),
quantity: $row.find('.quantity').text().trim(),
}
}).get();
var BID = [];
for (var i = 0; i < data.length; i++) {
if (data[i].id != null && data[i].id != "") {
BID.push(data[i]);
}
}
$.ajax(
{
type: "POST",
url: "/User/UpdateBID",
data: BID,
cache: false,
async: true,
dataType: "json",
success: function (data) {
alert(data);
},
});
});
});
</script>
and this is the method from the controller :
public ActionResult UpdateBID(object BID)
{
string c = JsonConvert.SerializeObject(BID);
//Context.UpdateBID(b);
return RedirectToAction("SesionIndividual", TempData["LoginModel"]);
}
The controller method is called,but the object is null.I also made sure the JavaScript object is not null.I also tried to send other objects just to test it,and I have the same result,the parameter in the controller method is null.
I have the name of the object from View the same as the name of the controller method parameter.
The name of the object is irrelevant, as it's just a variable name. This gets converted to the name data anyway - ie data:BID = data=BID so the "variable name" passed via ajax is "data". The properties in that variable need to match.
The short answer is you your "data" variable needs a property that matches the action parameter name, ie:
data: { BID: BID },
The long(er) answer is that the MVC model binder will attempt to match property names with your parameter names. In this case you've made it difficult on yourself by using object BID instead of an actual model, so there are no properties to match so it can only match on the parameter itself.
If you created a model that matched the data being passed:
public class BIDModel {
public string companyName { get;set; }
public string price { get;set; }
public string quantity { get;set; }
}
and used that in your action
public ActionResult UpdateBID(BIDModel BID)
then passing data: BID would work as the properties of data would be matched with the properties of BIDModel - you could still use data: { BID: BID } and the MVC model binder would match the data.BID property to your parameter name directly (and the properties within each would then be mapped).
To cover:
[HttpPost] attribute in controller method.
the [HttpPost] attribute does not make it a post method - instead of restricts the http verb to POST. You generally don't need this. It's useful where you have two methods with the same name but different overloads and one for the GET with an equivalent POST (where the GET parameter is just an id but the POST is the full model). It can also be used as additional security.
In your case, you are getting inside the action (just with a null parameter) so that part is clearly working fine.
MVC will try to bind from model properties so there should be a property called BID
data: { BID: BID }
For anyone interested I realize what the problem was.I was trying to send an JavaScript array of objects to a method which theoretically accepted an array of those objects.Well,apparently this did not work.What I did was to create a new object in C# with a property which had a type of UpdateOrder[],something like that:
public class UpdateOrder
{
public int id { get; set; }
public string companyName { get; set; }
public string price { get; set; }
public int quantity { get; set; }
}
public class Term
{
public UpdateOrder[] Terminal { get; set; }
}
I created a similar Term object in Javascript and send it through AJAX in controller method and it worked.So,instead of sending directly an array,I created an object with a property which holds that array.

ASP.NET MVC Passing a BeginCollectionItem List's Object through AJAX with Javascript Serialize to Controller is passing null

This has been giving me some trouble for the past few days. I'm going to try to be as detailed as possible with what I want and the issue I'm having. I tried to simplify my controllers, models, etc as much as I can for the sake of the question.
Here's the flow of sequences I'm trying to get to work.
Give user a view with inputs for List<MyObject> in the main ViewModel
User can hit a button to add another row to add another object to that List of objects to post later
Hitting the button POSTs the object (in same container) through AJAX from the currently displayed list in order to repeat most of the inputs for the new row (MyObject)
Controller takes passed MyObject and maps some of the prior values to the new object
Controller passes back new MyObject and ajax appends the result html to my table
The Problem
The Ajax is passing the on-page MyObject as null (or C# doesn't know how to interpret) to my controller (step 4 above). I can't seem to get the object passed to the controller through the Ajax call.
What I've got
Models:
public class MyViewModel
{
// irrelevant properties
public List<MyObject> MyObjects { get; set; } = new List<MyObject>();
}
public class MyObject
{
public int Id { get; set; }
public string Name { get; set; }
public string AnotherProperty { get; set; }
public decimal AdditionalProperty { get; set; }
public List<MySubObject> MySubObjects { get; set; } = new List<MySubObject>();
}
public class MySubObject
{
public bool IsChecked { get; set; }
public bool Name { get; set; }
}
Controller GET:
public ActionResult Edit(int? id)
{
var viewModel = new MyViewModel();
// for list of checkboxes
var subObjects = new List<MySubObject>();
// get subobjects from db
subObjects.Add(new MySubObject {
Name = "SubObj1", IsChecked = false
});
subObjects.Add(new MySubObject {
Name = "SubObj12",
IsChecked = false
});
// populate viewModel with a blank MyObject
viewModel.MyObjects.Add(new MyObject
{
MySubObjects = subObjects
});
return (viewModel);
}
View (and AJAX call):
<table id="myObjectInputs">
#foreach (var obj in Model.MyObjects)
{
#Html.Partial("~/Areas/Admin/Views/Shared/EditorTemplates/MyObject.cshtml", obj)
}
</table>
<script>
$(document).ready(function () {
$("#myObjectInputs").on("focus", ".make-new-row", function () {
var plusButton = $(this);
var currentArea = plusButton.closest(".myobject-container");
var serializedData = currentArea.find(":input").serialize();
// add new row
$.ajax({
url: this.href,
cache: false,
type: "POST",
data: { "myObject": serializedData },
success: function (html) { $("#myObjectInputs").append(html); }
});
return false;
});
});
</script>
EditorTemplates/MyObject.cshtml:
#using HtmlHelpers.BeginCollectionItem
#model LD.Areas.Admin.Models.MyObject
<tbody class="myobject-container" style="border:solid 1px red;">
#using (Html.BeginCollectionItem("MyObjects"))
{
<tr>
<td>#Html.HiddenFor(x => x.Id)</td>
<td>#Html.EditorFor(x => x.Name)</td>
<td>#Html.EditorFor(x => x.AnotherProperty)</td>
<td>#Html.EditorFor(x => x.AdditionalProperty)</td>
<td>
#foreach (var subObj in Model.MySubObjects)
{
#Html.Partial("~/Areas/Admin/Views/Shared/EditorTemplates/MySubObject.cshtml", subObj)
}
</td>
<td>
<!-- the button that calls the function / AJAX -->
#Html.ActionLink("+", "NewMyObjectSection", null, new { #class = "make-new-row" })
</td>
</tr>
}
</tbody>
EditorTemplates/MySubObject.cshtml
#using HtmlHelpers.BeginCollectionItem
#model LD.Areas.Admin.Models.MySubObject
#using (Html.BeginCollectionItem("MySubObjects"))
{
<label>
#Html.HiddenFor(x => x.Id)
#Html.HiddenFor(x => x.Name)
#Html.EditorFor(x => x.IsChecked)#Html.LabelFor(x => x.IsChecked, Model.Name)
<text> </text>
</label>
}
ActionResult called by AJAX: (this is I'm getting null for MyObject)
public ActionResult NewMyObjectSection(MyObject myObject)
{
// take passed object values and create a new object based on myObject
var newObject = new MyObject();
return PartialView("~/Areas/Admin/Views/Shared/EditorTemplates/MyObject.cshtml", myObject);
}
What I've Tried
Some main things that stick out to me are that BeginCollectionItem attaches a GUID to make the collection items unique, for ex, when my <tablebody class="myobject-container"> is serialized, it looks like this (this is the result from my real object, Rates == MyObjects):
"Rates.index=b589808e-3e99-40f2-827c-58feaa9bebc3&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.OrganismNid=0&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.OrganismName=&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.OrganismUpdateType=New&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.IsPest=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.IsPreEmergent=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.IsPostEmergent=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.IsSafeOn=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.HasControl=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.HasSuppression=false&ControlTypes.index=bd9d1180-9768-4ca4-8316-fc5cbf62ca97&ControlTypes%5Bbd9d1180-9768-4ca4-8316-fc5cbf62ca97%5D.ControlTypeNid=1&ControlTypes%5Bbd9d1180-9768-4ca4-8316-fc5cbf62ca97%5D.Name=Annual&ControlTypes%5Bbd9d1180-9768-4ca4-8316-fc5cbf62ca97%5D.IsChecked=false&ControlTypes.index=0264b842-5cac-4b1a-8b79-8f9a13a26428&ControlTypes%5B0264b842-5cac-4b1a-8b79-8f9a13a26428%5D.ControlTypeNid=2&ControlTypes%5B0264b842-5cac-4b1a-8b79-8f9a13a26428%5D.Name=Biennial&ControlTypes%5B0264b842-5cac-4b1a-8b79-8f9a13a26428%5D.IsChecked=false&ControlTypes.index=6a344551-add6-4e9b-96e2-59a6fc857327&ControlTypes%5B6a344551-add6-4e9b-96e2-59a6fc857327%5D.ControlTypeNid=3&ControlTypes%5B6a344551-add6-4e9b-96e2-59a6fc857327%5D.Name=Winter%20Annual&ControlTypes%5B6a344551-add6-4e9b-96e2-59a6fc857327%5D.IsChecked=false&ControlTypes.index=91f5c6ff-402e-48ae-8f9c-1131511699a8&ControlTypes%5B91f5c6ff-402e-48ae-8f9c-1131511699a8%5D.ControlTypeNid=4&ControlTypes%5B91f5c6ff-402e-48ae-8f9c-1131511699a8%5D.Name=Perennial&ControlTypes%5B91f5c6ff-402e-48ae-8f9c-1131511699a8%5D.IsChecked=false&ControlTypes.index=3248ec07-09a8-4bf0-b99f-a518807d9636&ControlTypes%5B3248ec07-09a8-4bf0-b99f-a518807d9636%5D.ControlTypeNid=5&ControlTypes%5B3248ec07-09a8-4bf0-b99f-a518807d9636%5D.Name=Top%20Growth%20Control%20Only&ControlTypes%5B3248ec07-09a8-4bf0-b99f-a518807d9636%5D.IsChecked=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.BroadcastMin=&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.BroadcastMax=&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.BroadcastChemUnitTypeNid=1&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.BroadcastAreaUnitTypeNid=9&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.SpotMin=&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.SpotMax=&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.SpotChemUnitTypeNid=1&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.SpotFinalSolutionUnitTypeNid=1"
I'm not sure if my controller understands to bind that to my object.
I've tried other methods of passing it, such as stripping out GUIDs and extra junk from the string, passing it as a string and deserializing in C#, and others:
var serializedArray = currentArea.find(":input").serializeArray();
//https://www.regextester.com/94410
var regex = new RegExp("(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}");
var stripped = serializedData.replace(/(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}/g, '');
stripped = stripped.replace(/%5B/g, '[').replace(/%5D/g, ']');
var strung = JSON.stringify({ "modelData": serializedData });
At this point I'm at a loss. This is for a personal passion project and my lack of AJAX / JSON knowledge is really holding me back. I'm not sure what else to try. Any pointing in the right direction would be appreciated.
public ActionResult NewMyObjectSection([FromBody] MyObject myObject)
{
//myObject should be correctly populated from the request
return PartialView("~/Areas/Admin/Views/Shared/EditorTemplates/MyObject.cshtml", myObject);
}
Id Expect the item to come as a Json Object correctly passed in your request to that your myObject is populated automatically
for the request part:
var dat = {
Id:3,
Name:7,
AnotherProperty:"",
AdditionalProperty:"",
MySubObjects:[
//Create sub objects here
]
};
$.ajax({
type: "POST",
url: "youraction",
data: JSON.stringify(dat),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){alert(data);},
failure: function(errMsg) {
alert(errMsg);
}
});
})

.load jQuery method with data parameter for Partial Razor page

I'm working with Razor pages and can't get my dto object in javascript map to a class in the model using the jquery .load function.
So, a user clicks on a button in the UI and the following javascript runs:
$('#btnGoToResults').click(function (e) {
var dto = {
ID: 1,
CODE: 5
};
$('#divPerformanceResults').load('/PerformanceSearch?handler=ResultsPartial', dto); // Gives error 400
}
I've tried the following as well without getting it to work:
$('#divPerformanceResults').load('/PerformanceSearch?handler=ResultsPartial', JSON.stringify(dto)); // "works" since the code behind is hit but the dto values are 0
Also tried rewriting with ajax:
// Gives error 400
$.ajax({
url: '/PerformanceSearch?handler=ResultsPartial',
data: JSON.stringify(dto),
dataType: 'json',
contentType: 'application/json',
type: 'POST',
success: function (data) {
$('#divPerformanceResults').html(data);
}
});
This is the model I'm trying to map it to:
public class RequestResultModel
{
public int ID { get; set; }
public int CODE { get; set; }
}
It is the in-parameter for the method creating and returning the partial view which will contain all logic for filtering:
public PartialViewResult OnGetResultsPartial(RequestResultModel dto)
{
Results = new List<PerformanceResultModel>()
{
...
};
return new PartialViewResult
{
ViewName = "_PerformanceResults",
ViewData = new ViewDataDictionary<List<PerformanceResultModel>>(ViewData, Results)
};
}
The method works and the partial is rendered so all of that is good. It's just the dto I need to get working so I can filter the result list. I did get the following to work by switching the method parameter to an int but it's only one parameter, I'm going to need several inputs later.
$('#divPerformanceResults').load('/PerformanceSearch?handler=ResultsPartial', 'ID=15'); // This works. Only one param though
Attached the chrome log as well if that gives anything:
It feels like I'm just missing something easy here but I can't find any answers online.
Thanks!
Ok. After some more testing and research I ended up at:
https://www.learnrazorpages.com/security/request-verification
Where I found out that there are tokens added to razor pages preventing posts without it.
SO you can either ignore the token validation on global level or by class level, example:
[IgnoreAntiforgeryToken(Order = 1001)]
public class IndexModel : PageModel
{
public void OnPost()
{
}
}
Or you can do as I did in the following:
First of all, rename the method to OnPost instead of OnGet:
public PartialViewResult OnPostResultsPartial(RequestResultModel dto)
Then in the javascript call include the token like the following:
$('#btnGoToResults').click(function (e) {
var dto = {
ID: 1,
CODE: 5
};
$('#divPerformanceResults').load('/PerformanceSearch?handler=ResultsPartial',
{ dto: dto, __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val() });
}
And that is it! It now maps the javascript object correctly with the class in the pagemodel :) Hope this will help others out there!
your first version of .load() was good, jquery load() method will do http post if it detects dto param as object:
$('#divPerformanceResults').load('/PerformanceSearch?handler=ResultsPartial', dto);
and then you can add [HttpPost] attribute to your Action to accept post methods
[HttpPost]
public PartialViewResult OnGetResultsPartial(WebApplication1.Models.RequestResultModel dto)
{

Post knockout.js viewmodel to .Net Core (2.0) MVC Controller

Overview:
Currently, I try to create an ASP.NET Core MVC website which gets data from the server on page load. After that, the page uses knockout.js to maintain a viewmodel to update the data sent from the server (in the first step). Finally, there is a button which sends the edited data back to the server (through an AJAX request). But the corresponding value in my server method is always empty.
Current Approach:
First, there is my model class.
public class Order
{
public string Name { get; set; }
public int TemplateId { get; set; }
public decimal Price { get; set; }
public int Contingent { get; set; }
public int MaximumOrder { get; set; }
public int UserOrderCount { get; set; }
public Order() { }
public Order(SnackOffer offer)
{
Name = offer.Template.Name;
TemplateId = offer.Template.SnackTemplateId;
Price = offer.Price;
}
}
In my view I use the model class as a List (List) and load the data like this:
var model = new viewModel();
#(Json.Serialize(Model.Offers)).forEach(function (item, index) {
model.offers.push({
name: item.name,
templateId: item.templateId,
contingent: ko.observable(item.contingent),
userOrderCount: ko.observable(item.userOrderCount),
price: item.price,
maximumOrder: item.maximumOrder
});
})
The viewModel is defined like this (shortend for readability):
function viewModel() {
var self = this;
self.offers = ko.observableArray();
}
Now after someone hits the mentioned update button I call this javascript function:
self.ConfirmOrder = function () {
var data = ko.toJSON(self.offers);
$('#overlay').css('display', 'block');
$.ajax({
type: 'post',
url: '/Snack/ConfirmOrder',
data: data,
contentType: 'application/json; charset=utf-8',
success: function (result) {
$('#overlay').css('display', 'none');
},
error: function (result) {
console.log(result);
$('#overlay').css('display', 'none');
}
});
}
Here you can see that I use the ko.toJSON method to convert the observableArray to a JSON String and use this string as the data argument for the ajax post.
The ConfirmOrder method in the MVC Controller looks like this currently:
[HttpPost]
public void ConfirmOrder(List<OrderSnackViewModel.Order> offers)
{
foreach (var item in offers)
{
_logger.LogInformation(item.Name);
}
}
There is no logic yet cause the offers list is created (so not null) but the count of list items is always 0.
In a concret example this is the JSON string I receive from the server while load the view:
[{"name":"Test","templateId":1,"price":1.94,"contingent":4,"maximumOrder":7,"userOrderCount":0},{"name":"Test 1","templateId":2,"price":1.50,"contingent":30,"maximumOrder":7,"userOrderCount":0}]
And this is the string i produce with the ajax call:
[{"name":"Test","templateId":1,"contingent":4,"userOrderCount":0,"price":1.94,"maximumOrder":7},{"name":"Test 1","templateId":2,"contingent":30,"userOrderCount":0,"price":1.5,"maximumOrder":7}]
What have I tried already:
I have tried to use FromBody in my MVC Controller
I have tried to prefix the JSON output with the name offer so my controller method can map the JSON string items to the object. (e.g. data = '{ "offers":' + data + '}'; )
I have tried to rename the Properties of my model to match exactly the JSON names. So I renamed Name to name and Contingent to contingent and so on.
I have tried to use an array instead of the List in the MVC controller action
Is there a master somewhere which can help me with this problem?
(If you need some more information please do not hesitate to ask)
Thanks to the input of #adiga I have found the solutions for (my) error.
[HttpPost]
public JsonResult ConfirmOrder([FromBody]List<Order> offers)
{
_logger.LogInformation("COUNT -> " + offers.Count());
foreach (var item in offers)
{
_logger.LogInformation(item.Name);
}
}
This is the working solution. I thought I already have tried it but maybe I have forgoten the content-type for the ajax post.
var data = ko.toJSON(self.offers);
$('#overlay').css('display', 'block');
$.ajax({
type: 'post',
url: '/Snack/ConfirmOrder',
data: data,
contentType: 'application/json; charset=utf-8',
success: function (result) {
//location.reload();
$('#overlay').css('display', 'none');
},
error: function (result) {
console.log(result);
$('#overlay').css('display', 'none');
}
});
Thanks again for all responses!

send multiple objects via ajax (using angular)

I have a list of user inputs in an object 'data'. (for e.g data.username, data.password, data.age)
i am passing the data object to backend like this using angular.
var submits = "=" + JSON.stringify(data);
$.ajax({
type: "POST",
url: serviceURL,
data: submits
});
I am passing two more objects. selections and grid. how can i pass all these three together in one ajax call ? or do i have to transfer it independently. will it affect the performance if i transfer these details separately.
can i do something like this to send the object together in one ajax call?
var data = {};
data[0] = data1;
data[1] = data2;
How can i retrieve it separately at the server side using c# if at all they are passed together.
Heres the 3 objects that i need to pass
data -->> ["Raul","New York","31"]
selections-->> ["dy.txt","my.txt","yy.txt"]
grid--> ["sesion","id"]
Assuming you have a view model like this in your server side
public class CreateUserViewModel
{
public string UserName{set;get;}
public string Location {set;get;}
public int Age {set;get;}
}
public class RegisterViewModel
{
public CreateUserViewModel User {set;get;}
public List<string> Selections {set;get;}
public List<string> Grid {set;get;}
}
and an MVC action method like this
public ActionResult Create(RegisterViewModel model)
{
// read model and save and return some JSON response
}
You can simply build the javascript object which matches the structure of the view model and post it using angualr's $http service. No need to worrry about setting content-Type or Json stringifying it. Angualr will take care of it.
var model={ User : {} ,Selections :[], Grid=[] };
model.User.Age =23;
model.User.UserName ="test";
model.User.Location="New York";
model.Selections.push("dy.txt");
model.Selections.push("some.txt");
model.Grid.push("session");
model.Grid.push("id");
var url="replcaeUrltoYourActionMethodHere";
$http.post(url, model)
.then(function(response)
{
// do something with the response
// var result= response.data
});
You can send multiple objects / variables in ajax with:
var submits = "=" + JSON.stringify(data);
$.ajax({
type: "POST",
url: serviceURL,
data: {submits : submits, data1:data1, data2:data2}
});
In your C# you can access data1 and 2 in the same way as you handle submits now.
Depending of what is in data1 and data2 you might need to stringify it first.
second option:
You can also if you want to (but it is more ugly) use the stringify on everything at once and only pass the string:
data = {};
data["data1"] = data1;
data["data2"] = data2;
var submits = "=" + JSON.stringify(data);
Are you using WebApi or MVC on the server? If so, the simplest approach would be to create a class which holds the 3 entities you need to send and leverage the built-in model-binding
So in your example you list what looks to be a user form, selections and grids. I'm not really sure what the last two are but an example Model might look something like this:
public class UserSubmissionViewModel
{
public UserSubmissionViewModel() { }
public UserFormModel User {get;set;}
public SelectionsModel Selections { get; set; }
public GridModel Grids { get; set; }
}
Then on your web api controller or your MVC controller you'd have a method such as this:
public async Task<IHttpActionResult> Submit(UserSubmissionViewModel model)
And your javascript would resemble something roughly like this:
var toSend = {"UserFormModel":data, "SelectionsModel":selections, "GridModel":grids};
$.ajax({
type:"POST",
data:toSend, //<--- you might need to JSON.stringify this, cant test this code at the moment
url:serviceURL //<-- Calls your Submit method on the controller
});

Categories