How to Serialize Model in View and Pass to Controller Action - json

I have a very specific need to serialize a model in the view and then pass it to a controller action at some point. I can get it to work by doing several hacks but its not pretty.
My test controller action
public ActionResult Index()
{
DefaultOptionValueRound defaultOptionValueRound = new DefaultOptionValueRound()
{
OptionId = 1835,
OptionValueId = 40343
};
TestModel testModel = new TestModel()
{
DefaultOptionValueRound = defaultOptionValueRound
};
return View(testModel);
}
The View
#using Common.Repository.Extensions
#model EngA.SandboxApplication.Controllers.TestModel
#Html.Hidden("DefaultOptionValueRound", Html.Raw(Json.Encode(Model.DefaultOptionValueRound)))
<input type="button" value="submit" onclick="SerializeModelTest.processOptionMag()"/>
<script language="javascript">
SerializeModelTest = {
processOptionMag: function () {
//Testing: This Works
//var defaultOptionValueRound = { OptionId: 1834, OptionValueId: 4034377 }
//var data = JSON.stringify({ defaultOptionValueRound: defaultOptionValueRound });
//This Does Not Work
var defaultOptionValueRound = $("#DefaultOptionValueRound").val();
var data = { defaultOptionValueRound: defaultOptionValueRound }; //Stringify Does not work either
$.ajax({
contentType: 'application/json; charset=utf-8',
type: "Post",
cache: false,
url: '#Url.Action("ProcessOptionMag", "SerializeModelTest")',
data: data,
dataType: "json",
traditional: true,
success: function(data) {
alert(data);
}
});
}
}
</script>
The problem is that the serialized model is returned in a stringify form already.
There must be an elegant way of doing this without me have to do JS string manipulation to make it work.
Thank you for your help

I found out that I can un-stringify my result using JSON.Parse and then repackage it with other parameters for sending to the controller.
var defaultOptionValueRound = $("#DefaultOptionValueRound").val();
var data = JSON.stringify({ defaultOptionValueRound: JSON.parse(defaultOptionValueRound) });
Now everything works.

Related

AJAX hiddenfield submit instead of form does not work

I have trouble sending AJAX post request to controller. The following code works:
var path = $(this).prop("value");
var token = $('[name=__RequestVerificationToken]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;
var ids = $("#ids").val();
var formData = new FormData();
formData.append('ids', ids);
$.ajax({
url: path,
type: "POST",
cache: false,
headers: headers,
data: formData,
async: false,
processData: false,
contentType: false,
success: function (result) {
document.write(result);
document.close();
console.log("YES");
},
error: function () {
alert("Error.");
}
});
Here is the Controller Method:
[AjaxOnly]
[HttpPost]
[ValidateAntiForgeryToken]
[OutputCache(NoStore = true, Location = OutputCacheLocation.None)]
public ActionResult MyMethod(string aString)
The call to the Controller works fine, but as expected aString in Controller-Function parameter is null.
What I actually want to do is not to POST the formData ($("#myForm").serialize();) in the data field of the AJAX post, but an hiddenField:
var aString = $("#ids").val();
So when I put the aString variable in the data field of Ajax call instead of formData the call to my function does not work anymore and I get 500 error.
Anyone can help how to POST this hiddenfield value instead of formData?
MyForm:
#{
ViewBag.Title = "MyForm";
#model MyFormModel
}
#using (Html.BeginForm("MyForm", "MyController", FormMethod.Post, new { id = "MyForm" }))
{
<div class="tab-content" id="tabContent">
content
</div>
#Html.Partial("_MyFormPopup")
Partial:
#using (Html.BeginForm("MyMethod", "MyController", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="modal fade">
content
</div>
#Html.Hidden("ids")
Controller Code:
[AjaxOnly]
[HttpPost]
[ValidateAntiForgeryToken]
[OutputCache(NoStore = true, Location = OutputCacheLocation.None)]
public ActionResult MyMethod(string ids)
{
string[] IdsFunktions = ids.Split(new string[] { ";" },
....
return RedirectToAction("MyForm");
}
So in order for your code to work you need to correctly name your formData variables, here are the two variants:
If you want to have a aString variable on your Controller then your AJAX post code should post like this:
var formData = new FormData();
formData.append('aString', $("#ids").val());
$.ajax({
url: path,
type: "POST",
cache: false,
headers: headers,
data: formData,
async: false,
success: function (result) {
document.write(result);
document.close();
},
error: function () {
alert("Error.");
}
});
Another solution would be in the case you want to post all form fields data by using data: $("#myForm").serialize() you must change the Controller reference variable names and reference each field by its form name, e.g if you have only one hidden field then:
[AjaxOnly]
[HttpPost]
[ValidateAntiForgeryToken]
[OutputCache(NoStore = true, Location = OutputCacheLocation.None)]
public ActionResult MyMethod(string ids, string fieldNameOne, string fieldNameTwo, etc...)

IformFile in the action controller takes the value as null, value is pass to the action controller using ajax request

I am trying to get the value passed from the ajax request into one of the method in the controller but IFormFile files is null every time.
Here is my ajax request :
uploadFile: function (field, value)
{
var me = this;
var view = me.getView();
var fileuploadControl = me.lookupReference('ImportFile');
var file = fileuploadControl.fileInputEl.el.dom.files[0];
var param = new FormData();
param.append('files', file);
var ajax = Ext.Ajax.request(
{
url: './../XYController/ImportCSVFile',
data: param,
method: 'POST',
contentType: "application/json; charset=utf-8",
dataType: "json",
headers: { 'accept': '*/*' },
processData: true,
success: function (response, options) {
var result = JSON.parse(response.responseText);
if (mask) {
mask.destroy();
}
Ext.Msg.alert("File Upload Successful");
}
});
},
And this is my Action Controller :
[HttpPost]
[Route("XYController/ImportCSVFile")]
public IActionResult ImportCSVFile(IFormFile files)
{
if(files!=null)
{
//do something
}
}
For file upload , The contenttype needs to be set to false along with the processData option. Otherwise jQuery will not see this as a file upload :
processData: false,
contentType: false,
See code samples from here , that should be same no matter use ExtJS or other Jquery wrapper library .

Populate textboxes based on id searched

Okay, so i am new to ajax and mvc. i have a form which requires me to enter an id in the field and after clicking the search button it retrieves and populates data from the database and displays it in the textfields.
Controller Code
public ActionResult LoadVendorInfo(string vendornumber)
{
var query = from c in db.Vendors
where c.VendorNumber == vendornumber
select c;
return Json(query.FirstOrDefault());
}
Ajax
<script type="text/javascript">
$(document).ready(function () {
$("#searchvendor").click(function () {
var vendornumber = $('#vendornumber').val();
$.ajax({
cache: 'false',
type: "POST",
data: { "vendornumber": vendornumber },
url: '#Url.Action("LoadVendorInfo", "Vendors")',
datatype: 'json',
"success": function (data) {
if (data != null) {
var vdata = data;
$("#companyname").val(vdata[0].companyname);
$("#regnum").val(vdata[0].regnum);
$("#email").val(vdata[0].email);
$("#contactnum").val(vdata[0].contactnum);
$("#refnum").val(vdata[0].refnum);
}
}
})
})
})

Handling a model returned as json data from a controller in ASP.NET

I have a controller which return a model as json object:
[HttpGet("{id}")]
[Route("GetById")]
public async Task <JsonResult> GetById([FromQuery]string id)
{
var myfoo = new {foo="bar", baz="Blech"};
return Json(myfoo);
}
How can handle the returned json object in jQuery?
<script type="text/javascript">
$('#id').change(function () {
var id = $('#id').val();
if (id.length = 17) {
$.ajax(
{
url: '/Home/GetById?id=' + id,
type: 'GET',
jsondata: "",
contentType: 'application/json; charset=utf-8',
success: function (jsondata) {
alert("foo is: " + jsondata ); <---?
},
error: function () {
//alert("error");
}
});
}
});
</script>
I need to get foo value and assigned to an html control
Thanks in advance
all the time I was using capital letter
jsondata.foo // not .Foo

cannot pass json object to mvc action

I am trying to call an mvc 3 action method with jquery ajax. please let me note that I am generating a partial view in ajax, and in the generated partial view, I am calling ajax again (it is something like nested ajax calls). here is my code:
the partial view:
#model MYWeb.UI.Models.ClientDetailsViewModel
The javascript in the view:
<script type="text/javascript">
$(document).ready(function () {
$("#savedetails#(i)").click(function () {
var clientNumber = $('#ClientNumber#(i)').val();
var clientName = $('#ClientName#(i)').val();
var client =
{
ClientNumber: clientNumber,
ClientName: clientName
};
alert(JSON.stringify(client));
$.ajax({
url: '/Home/ClientUpdate',
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(client),
beforeSend: function () {
$("#loader#(i)_details").fadeIn('fast');
},
complete: function () {
$("#loader#(i)_details").fadeOut('fast');
},
success: function () {
$("#loader#(i)_details").fadeOut('fast');
if ($("#ModelFirstError").val())
showModelMessageError;
else
showUpdateMessageSuccess();
},
error: function () {
$("#loader#(i)_details").fadeOut('fast');
showUpdateMessageError();
},
async: true,
processData: false
});
});
});
the Model object:
public class ClientDetailsViewModel
{
[Display(ResourceType = typeof(adm), Name = "ClientNumber")]
public int ClientNumber { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessageResourceName = "RequiredClientName", ErrorMessageResourceType = typeof(adm))]
[Display(ResourceType = typeof(adm), Name = "ClientName")]
public string ClientName { get; set; }
more fields...
}
the action method:
[Authorize]
[HttpPost]
public ActionResult ClientUpdate(ClientDetailsViewModel client)
{}
this attempt to update always returns the ajax error. what am I doing wrong?
Edit:
I noticed that when I remove the parameter to the action method, it does get called.
But how can I pass the model this way?
[Authorize]
[HttpPost]
public ActionResult ClientUpdate()
{}