I have a JavaScript function that uses AJAX request to send data to my controller on asp.net MVC. Look:
function verCarrinho() {
$.ajax({
type: "POST",
url: "/Produto/Carrinho",
data: { "carrinho": carrinho },
success: function (e) {
}
});
}
Where carrinho is an array with two properties. One of these properties is an ID that I need to send to my controller to use EF to make a query on my data base.
My ActioNResult on controller:
[HttpPost]
public ActionResult Carrinho(List<Carrinho> carrinho)
{
var ids = carrinho.Select(s => s.idLivro).ToList();
var resultado = db.Produtos.Where(w => ids.Contains(w.idProduto));
return PartialView("_Carrinho", resultado);
}
The problem is: my variable "resultado" stay null! The AJAX is not sending the IDs. If I put a breakpoint on resultado I can see that AJAX send the objects, but I can't see the IDs.
I have a class same type of my parameter:
public class Carrinho
{
public int idLivro;
public int qtdProduto;
}
I don't know if I could be clear, but I hope you can help.
Thank you.
you need to data: JSON.stringify({ "carrinho": carrinho }) and also add contentType: 'application/json; charset=utf-8', to ajax call.
Javascript Object Literal Syntax !== JSON.
You need to JSON.stringify() your data object in your ajax request.
I changed my code based on a friend's code and it works. It's look like this:
namespace WebAppImaginario.Models
{
public class ItemCarrinho
{
public int idLivro { get; set; }
[DisplayName("Quantidade do Produto")]
public int qtdProduto { get; set; }
[DisplayName("Nome do Produto")]
public string nomeProduto { get; set; }
[DisplayName("Descrição do Produto")]
public string descProduto { get; set; }
[DisplayName("Preço do Produto")]
public decimal precProduto { get; set; }
[DisplayName("Desconto da Promoção")]
public decimal descontoPromocao { get; set; }
[DisplayName("Imagem")]
public byte[] imagem { get; set; }
}
}
Controller:
[HttpPost]
public ActionResult Carrinho(string hidCarrinho)
{
List<ItemCarrinho> listaCarrinho = new List<ItemCarrinho>();
if (hidCarrinho != null)
{
var itens = JsonConvert.DeserializeObject<List<ItemCarrinho>>(hidCarrinho);
foreach (var item in itens)
{
var qtd = int.Parse(new string(item.qtdProduto.ToString().Where(char.IsDigit).ToArray()));
if (qtd > 0)
{
var idLivroNumerico = int.Parse(new string(item.idLivro.ToString().Where(char.IsDigit).ToArray()));
var resultado = db.Produtos.Where(m => m.idProduto == idLivroNumerico).FirstOrDefault();
ItemCarrinho prod = new ItemCarrinho();
prod.idLivro = idLivroNumerico;
prod.qtdProduto = qtd;
prod.nomeProduto = resultado.nomeProduto;
prod.descProduto = resultado.descProduto;
prod.precProduto = resultado.precProduto;
prod.descontoPromocao = resultado.descontoPromocao;
prod.imagem = resultado.imagem;
listaCarrinho.Add(prod);
}
}
}
return View(listaCarrinho);
}
JavaScript:
function setValueEnviar() {
$("#hiddenInputContainer").empty();
for (var i = 0; i < carrinho.length; i++) {
var newInput = document.createElement('input');
newInput.type = "hidden";
newInput.value = JSON.stringify(carrinho[i]);
newInput.name = 'data';
$("#hiddenInputContainer").append(newInput);
}
}
$('#formCarrinho').submit(function (e) {
e.preventDefault();
$('#hidCarrinho').val(JSON.stringify(carrinho));
document.formCarrinho.submit();
})
Those IDs are a form on my page and hidden input. I don't know if it is clear, but it works to me.
Thank you for all support.
Syntax like data: { "carrinho": carrinho } can work, $.ajax does accept a PlainObject as data (see http://api.jquery.com/jquery.ajax/).
Your problem is that your variable carrinho is not conforming to the requirements of a PlainObject.
The PlainObject type is a JavaScript object containing zero or more key-value pairs
http://api.jquery.com/Types/#PlainObject
Depending on what carrinho is, you may have success with stringify as an alternative:
function verCarrinho() {
$.ajax({
type: "POST",
url: "/Produto/Carrinho",
data: JSON.stringify({ "carrinho": carrinho }),
success: function (e) {
}
});
}
Related
I tried to pass array of objects to controller by jQuery Ajax, but result is null in ASP.NET 5.0.
My data array is what send to controller: regions.
Data constructor is defined in BoundingBoxModel class.
This is my ajax function:
$("body").on("click", "#onClick", function () {
var regions = [];
var arr = Array.prototype.slice.call(document.getElementsByClassName('ui-draggable'));
arr.forEach((tagele) => {
var region = {};
region.Height = tagele.offsetHeight;
region.Width = tagele.offsetWidth;
region.Top = tagele.offsetTop;
region.Left = tagele.offsetLeft;
regions.push(region);
});
$.ajax({
url: '/GenCode/Addregions',
type: "POST",
dataType: "json",
contentType: "application/json;charset=utf-8",
data: JSON.stringify({'regions': regions}),
success: function () {
alert("pass")
},
error: function (jqXhr, json, errorThrown) {
alert(errorThrown);
console.log(errorThrown);
}
});
});
So this is my BoundingBoxModel:
public class BoundingBoxModel
{
public int BoundingBoxId { get; set; }
public double Top { get; set; }
public double Left { get; set; }
public double Height { get; set; }
public double Width { get; set; }
}
This is my action method. It's defined in GenCodeController.
[HttpPost]
public IActionResult AddRegions(List<BoundingBoxModel> regions)
{
JsonResult result = new JsonResult(this.Json(JsonConvert.SerializeObject(regions), System.Web.Mvc.JsonRequestBehavior.AllowGet));
return result;
}
My result is null:
I don't understand why it's happened. Can you help me?
There are some issues that I can see -
I am not sure if you explicitly written this logic but your region object will always have last value of arr because you declare your variable inside loop.
If you are trying to create an array then you should declare your region variable like - var region = []; .Right now it is an object.
You are trying to pass an object and accepting a list in webservice. Either remove the list in parameter in AddRegions service or pass a Array from ajax call.
I resolved my problem by deteting contentType: "application/json;charset=utf-8", line in ajax code.
Using this line make the array of region's type change to string so when i get data in Controller problem was happened.
Array of objects after stringifying is not passed to controller action and the parameter of action (the model) is null.
I have tried many solutions given to this problem in StackOverflow but none of these solution solved my problem. I provided the links which I tried:
Pass array to mvc Action via AJAX
pass array in javascript object to mvc controller
Here is my code
JavaScript Code
$("#FormSubmit").click(function () {
var datalist = [];
$("#MarksTable tbody tr").each(function () {
var obj = {};
obj.StudentID = 1;
obj.ExamTimeTableID = 1;
obj.ClassActivity = $(this).find("td:eq(5) input").val();
obj.IsPresent = $(this).find("td:eq(7) input").val();
obj.Assignment = $(this).find("td:eq(6) input").val();
obj.MidTerm = $(this).find("td:eq(3) input").val();
obj.Final = $(this).find("td:eq(4) input").val();
datalist.push(obj);
});
$.ajax({
url: "#Url.Action("InsertData", "Examination")",
type: "POST",
cache: false,
contentType: "application/json;charset=utf-8",
dataType: "json",
data: JSON.stringify(datalist),
success: function (result) {
alert(result);
},
error: function (errormessage) {
alert(errormessage.responseText);
}
});
});
Action of Controller:
[HttpPost]
public JsonResult InsertData([FromBody] List<StudentMarksList> obj)
{
DynamicParameters param = new DynamicParameters();
.
.
.
return Json(param.Get<string>("msg"));
}
The Model:
public class StudentMarksList
{
public int StudentID { get; set; }
public int ExamTimeTableID { get; set; }
public int ClassActivity { get; set; }
public int IsPresent { get; set; }
public int Assignment { get; set; }
public int MidTerm { get; set; }
public int Final { get; set; }
}
Request Payload:
[,…]
0: {StudentID: 1, ExamTimeTableID: 1, ClassActivity: 3, IsPresent: 0, Assignment: 2, MidTerm: 5, Final: 4}
Assignment: 2
ClassActivity: 3
ExamTimeTableID: 1
Final: 4
IsPresent: 0
MidTerm: 5
StudentID: 1
Request Payload source:
[{"StudentID":1,"ExamTimeTableID":1,"ClassActivity":3,"IsPresent":0,"Assignment":2,"MidTerm":5,"Final":4}]
The obj should contains the passed objects but it is null.
Any Help???
[Edit]
Change the js as below:
function toInt(str){
var i = parseInt(str);
return i ? i : 0;
}
$("#MarksTable tbody tr").each(function () {
var obj = {};
obj.StudentID = 1;
obj.ExamTimeTableID = 1;
obj.ClassActivity = toInt( $(this).find("td:eq(5) input").val());
obj.IsPresent =toInt( $(this).find("td:eq(7) input").val());
obj.Assignment = toInt( $(this).find("td:eq(6) input").val());
obj.MidTerm =toInt( $(this).find("td:eq(3) input").val());
obj.Final = toInt( $(this).find("td:eq(4) input").val());
datalist.push(obj);
});
This will make sure the empty input to 0 instead of null.
That's because on your server side you're declaring the ClassActivity/ClassActivity/Assignment/... as int type but your js send all them as string. For example, the Payload sent to server will be something like:
[{"StudentID":1,"ExamTimeTableID":1,"ClassActivity":"3","Assignment":"aa","MidTerm":"333333333","Final":"3333"},{"StudentID":1,"ExamTimeTableID":1,"ClassActivity":"","Assignment":"s","MidTerm":"2","Final":"1"},{"StudentID":1,"ExamTimeTableID":1,"ClassActivity":"3","Assignment":"","MidTerm":"2","Final":"1"}]
Please either change the property type or convert the $(this).find("td:eq(7) input").val() result (a string) to int/bool/... type before sending them.
You can try this also.
cshtml page you need to add one form tag like eg.
<div style="display:none;">
<form id="FormPost"></form>
</div>
Jquery Code
$("#FormSubmit").click(function () {
$("#FormPost").html('');
$("#MarksTable tbody tr").each(function (index,elem) {
addHidden("StudentID["+index+"]","1");
addHidden("ExamTimeTableID["+index+"]","1");
addHidden("ClassActivity["+index+"]",$(this).find("td:eq(5) input").val());
addHidden("IsPresent["+index+"]",$(this).find("td:eq(7) input").val());
addHidden("Assignment["+index+"]",$(this).find("td:eq(6) input").val());
addHidden("MidTerm["+index+"]",$(this).find("td:eq(3) input").val());
addHidden("Final["+index+"]",$(this).find("td:eq(4) input").val());
});
$.ajax({
url: "#Url.Action("InsertData", "Examination")",
type: "POST",
cache: false,
contentType: "application/json;charset=utf-8",
dataType: "json",
data: $("#FormPost").serialize(),
success: function (result) {
alert(result);
},
error: function (errormessage) {
alert(errormessage.responseText);
}
});
});
function addHidden(key, value) {
var input = document.createElement('input');
input.type = 'hidden';
input.name = key;
input.value = value;
$("#FormPost").appendChild(input);
}
Action of Controller:
[HttpPost]
public JsonResult InsertData(List<StudentMarksList> obj)
{
DynamicParameters param = new DynamicParameters();
.
.
.
return Json(param.Get<string>("msg"));
}
That could be dynamic value of one of property in object below is not a number, it contains some alphabet characters.
var obj = {};
obj.StudentID = 1;
obj.ExamTimeTableID = 1;
obj.ClassActivity = $(this).find("td:eq(5) input").val();//this value could be not a number, ex: 'abc' text
obj.IsPresent = $(this).find("td:eq(7) input").val();
obj.Assignment = $(this).find("td:eq(6) input").val();
obj.MidTerm = $(this).find("td:eq(3) input").val();
obj.Final = $(this).find("td:eq(4) input").val();
It will be reason that Asp.Net cannot deserialize your action parameter item to object of StudentMarksList.
If above is not the root cause, you can follow this question to log out serialization errors to have further investigation.
Simply add this property to your ajax call:
traditional:true,
such that your ajax call looks like this at the end
$.ajax({
url: "#Url.Action("InsertData", "Examination")",
type: "POST",
cache: false,
traditional:true,
contentType: "application/json;charset=utf-8",
dataType: "json",
data: JSON.stringify(datalist),
success: function (result) {
alert(result);
},
error: function (errormessage) {
alert(errormessage.responseText);
}
});
Happy coding. Hope it helps someone just as it helped me.
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);
}
});
})
I'm passing multiple JSON objects from my frontend to a C# backend - how can I deserialize them into C# classes so they can be used later on in my application? Before I go any farther, I am tied to using the JS FormData object, contentType: false, and processData: false, because I also need to pass files via this AJAX call; that is completely unrelated to this question. Here's my code so far:
Frontend - function is called when a submit button is pressed
submitData: function () {
var formCollection = this.appModel.get('formCollection').models;
var formData = new FormData();
var formJson = [];
$.each(formCollection, function (index, form) {
var tempJson = {};
if (form) {
tempJson['id'] = form.get('id');
tempJson['number'] = form.get('number');
tempJson['name'] = form.get('name');
tempJson['attachments'] = form.get('attachments');
formJson.push(tempJson);
}
});
console.log(JSON.stringify(formJson));
formData.append('formJson', JSON.stringify(formJson));
$.ajax({
type: "POST",
url: '/NMISProduct/Test',
contentType: false,
processData: false,
data: formData,
success: function (result) {
console.log(result);
}
});
}
JSON.stringified data that's being passed
[{"id":1,"number":null,"name":"Investment Portfolio Statement","attachments":null},{"id":2,"number":"61-0227","name":"WMC Signature Portfolio Agreement","attachments":null},{"id":3,"number":"61-1126","name":"WMC Signature Choice Agreement","attachments":null},{"id":4,"number":"61-1162","name":"WMC Signature Annuities Agreement","attachments":null},{"id":5,"number":"61-1205","name":"WMC Signature Managed Accounts Client Agreement","attachments":null}]
C# MVC 5 Backend
[HttpPost]
public async Task<JsonResult> Test()
{
Debug.WriteLine(Request.Params["formJson"]);
var forms = JsonConvert.DeserializeObject<Form>(Request.Params["formJson"]);
Debug.WriteLine(forms);
try
{
var srNumber = GetSRNumber();
foreach (string file in Request.Files)
{
var fileContent = Request.Files[file];
Debug.WriteLine(ReadFileInputStream(fileContent));
if (fileContent != null && fileContent.ContentLength > 0)
{
// get a stream
var stream = fileContent.InputStream;
// and optionally write the file to disk
//var fileName = Path.GetFileName(file);
var fileName = fileContent.FileName;
var path = Path.Combine(Server.MapPath("~/App_Data/"), fileName);
using (var fileStream = System.IO.File.Create(path))
{
stream.CopyTo(fileStream);
}
}
}
}
catch (Exception)
{
return Json("Upload failed");
}
return Json("File uploaded successfully");
}
public class Form
{
public int id { get; set; }
public string number { get; set; }
public string name { get; set; }
public Form attachments { get; set; }
public byte[] fileAsBytes { get; set; }
}
I've done my research and found several Stackoverflow questions that show how to serialize one JSON object into one C# class - however, I need to serialize multiple JSON objects into a List<Form>. How can I do this? What am I doing wrong in the posted code?
You're trying to deserialize to a single form here:
var forms = JsonConvert.DeserializeObject<Form>(Request.Params["formJson"]);
Just change it to:
var forms = JsonConvert.DeserializeObject<List<Form>>(Request.Params["formJson"]);
You should then be able to use forms in a normal way - iterating over it, taking a count etc.
[HttpPost]
public async Task<JsonResult> Test(List<Form> forms)
{
// your code here
}
And put your JS code
formJson.push(tempJson);
inside the
if (form)
I am trying to do like this in ASP.net MVC 2.0 Application. I have a form with two fields number1 and number2.
I want add two these two numbers using an ajax request. In the controller, I am recieving two numbers ,adding them and storing result in another string. Then, I am doing like this:
[HttpPost]
public string TestAjax(FormCollection form)
{
int strnum1 = Convert.ToInt32(form["txtbox1"].ToString());
int strnum2 = Convert.ToInt32(form["txtbox2"].ToString());
string strnum3 = Convert.ToString(strnum1 + strnum2);
if (strnum3 != null)
{
return "<script>alert("some message")</script>";
}
return string.Empty;
}
Is it possible to return java script in the form of string from controller actions?
Is it possible to return java script in the form of string from controller actions
You could return a JavaScriptResult:
[HttpPost]
public ActionResult TestAjax(FormCollection form)
{
int strnum1 = Convert.ToInt32(form["txtbox1"].ToString());
int strnum2 = Convert.ToInt32(form["txtbox2"].ToString());
return JavaScript("<script>alert(\"some message\")</script>");
}
For this to work you have to configure your AJAX request to execute javascript. For example if you are using jQuery that would look like this:
$.ajax({
url: '/someaction',
type: 'POST',
data: { txtbox1: '12', txtbox2: '13' },
dataType: 'script'
});
As an alternative you could return a JsonResult which will serialize the model to a JSON string:
[HttpPost]
public ActionResult TestAjax(FormCollection form)
{
int strnum1 = Convert.ToInt32(form["txtbox1"].ToString());
int strnum2 = Convert.ToInt32(form["txtbox2"].ToString());
string strnum3 = Convert.ToString(strnum1 + strnum2);
return Json(new { sum = strnum3 });
}
and then:
$.ajax({
url: '/someaction',
type: 'POST',
data: { txtbox1: '12', txtbox2: '13' },
success: function(result) {
alert(result.sum);
}
});
As you can see here you are no longer mixing javascript with C# code in your controller. Respect the DRY principle. javascript belongs in javascript files.
As further improvement to this controller action I would recommend you introducing a view model and get rid of the terrible plumbing code of parsing stuff from the FormCollection. That's the responsibility of the default model binder.
So:
public class SumViewModel
{
public int TxtBox1 { get; set; }
public int TxtBox2 { get; set; }
}
and then:
[HttpPost]
public ActionResult TestAjax(SumViewModel model)
{
int sum = model.TxtBox1 + model.TxtBox2;
return Json(new { sum = sum });
}
Conclusion: we have put this controller action on a diet, and moved the javascript where it belongs.
Why not use your ajax success callback function?
[HttpPost]
public string TestAjax(FormCollection form)
{
int strnum1 = Convert.ToInt32(form["txtbox1"].ToString());
int strnum2 = Convert.ToInt32(form["txtbox2"].ToString());
string strnum3 = Convert.ToString(strnum1 + strnum2);
if (strnum3 != null)
{
return strnum3;
}
return string.Empty;
}
$.ajax({
url: "/Controller/TestAjax/",
type: "POST",
data: /* form data here */,
success: SuccessCallback,
error: FailureCallback
});
function SuccessCallback(data) {
alert(data);
}
Try this,
[HttpPost]
public ActionResult TestAjax(FormCollection form)
{
int strnum1 = Convert.ToInt32(form["txtbox1"].ToString());
int strnum2 = Convert.ToInt32(form["txtbox2"].ToString());
string strnum3 = Convert.ToString(strnum1 + strnum2);
if (strnum3 != null)
{
return "<script>alert("some message")</script>";
}
return JavaScript("JSFunction(paramtr);");
}
View:-
function JSFunction(paramtr)
{
}