Passing knockout.js observablearray object to MVC Controller Action? - javascript

Im using knockout with MVC. Im trying to pass an observable array of objects from knockout back to my MVC controller action for saving to the database. If I pass the Array from knockout over to my controller action via ko.toJSON(viewModel.ArrayName) it comes back as null in my controller parameter. If I try to pass it to MVC via ko.toJS(viewModel.ArrayName) it has the correct number of items but the data is null for some reason. Any help on how to do this would be greeatly appreciated. Thanks!
My JQuery Data Retrieval Method:
var dataService = {};
var viewModel;
$(document).ready(function () {
dataService.getAccessLevelList();
})
dataService.getAccessLevelList = function () {
$.post('/DataService/GetAccessLevelList', null, function (data) {
viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
});
}
This is the problem method:
updateAccessLevels = function () {
$.post('/DataService/UpdateAccessLevels', { accessLevels: ko.toJSON(viewModel.AccessLevels) }, function (status) {
alert(status);
});
}
My MVC Controller Data Retrieval action:
[HttpPost]
public ActionResult GetAccessLevelList()
{
FacilityAccessViewModel viewModel = new FacilityAccessViewModel();
viewModel.AccessLevels = unitOfWork.AccessLevelRepository.Get().ToList();
return Json(viewModel);
}
The parameter is coming back NULL or with NULL data when trying to pass it in from Knockout on this controller method.
[HttpPost]
public ActionResult UpdateAccessLevels(List<AccessLevel> accessLevels)
{
try
{
foreach (AccessLevel record in accessLevels)
{
unitOfWork.AccessLevelRepository.Update(record);
}
unitOfWork.Save();
return Json("SUCCESS");
}
catch (Exception ex)
{
return Json(ex.ToString());
}
}
Below is the JSON data shown via fiddler thats being posted to my MVC controller action when i pass in { accessLevels: ko.toJSON(viewModel.AccessLevels) } the controller parameter is coming in null using this
[{"Access":[],"Id":1,"AccessLevelDesc":"TEST222"},{"Access":[],"Id":2,"AccessLevelDesc":"TEST222"}]
Below is the JS data shown via fiddler thats being posted to my MVC controller action when i pass in { accessLevels: ko.toJS(viewModel.AccessLevels) }, in this case the list has two members as expected, but the data is all null in the properties
accessLevels[0][Id] 1
accessLevels[0][AccessLevelDesc] TEST222
accessLevels[1][Id] 2
accessLevels[1][AccessLevelDesc] TEST222
If I pass in a single object to my controller it works just fine, but I cant seem to figure out the proper way to post an array of objects to my controller from an obervablearray back to a POCO entity.

Try sending it as a JSON request by specifying the correct request Content-Type header:
updateAccessLevels = function () {
$.ajax({
url: '/DataService/UpdateAccessLevels',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(viewModel.AccessLevels),
success: function(status) {
alert(status);
}
});
};

Related

Json.stringify allows HTML elements

I am trying to post values from MVC view to controller.
Request validation feature is enabled for application.
But when i tried to pass values with HTML tags to controller, I am not getting any exception.
here is my ajax post:
Group.Name = model.Name();
Group.Id = model.ID();
$.ajax({
type: 'POST',
url: /IndexController/SaveGroup',
async: true,
cache: false,
dataType: "json",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ Group: group }),
success: function (data /*, textStatus, request*/) {
try {
}
catch (error) {
showExceptionWindow('Jquery Error:' + error);
}
},
error: function (request /*, status, error*/) {
handleException(request.responseText);
}
});
}
Controller Code:
[HttpPost]
public async Task<ActionResult> SaveGroup(Group group)
{
when i tried to insert html tags,the values are passing to controller action method and getting saved.
When request validation feature is enabled,html elements should not be passed to controller.
How to make sure it is getting blocked at controller.
MVC validation dosent work since you've changed the submit button to prevent default mvc use the jquery plugin Validate.js just go through i,this code should work
var form = $("#YourFormID");
form.validate();
form.submit(function (e) {
e.preventDefault();
if (form.valid()) {
//Your ajax call
}
})
Seems you have a typo as there group does not seem to be a valid object it is undefined:
data: JSON.stringify({ group: Group }), // <-----It should have to be this Group here
And at your backend:
[HttpPost]
public async Task<ActionResult> SaveGroup(Group group) // group is {}
{
Or as Group is already an object then you can stringify it directly:
data: JSON.stringify(Group), // <-----It should have to be this Group here
[HttpPost]
public async Task<ActionResult> SaveGroup(Group Group) // group is {}
{
Why not using an HTML parser to detect HTML elements injection? This can be a clean JS solution
var containsHTML = /<[a-z][\s\S]*>/i.test("<p>HTML text to be parsed</p>")
if(containsHTML==true){
//There are HTML tags inside the string
}
else{
//You're good to go
}

Why Viewbag not show in asp.net mvc view page?

I'm beginner in asp.net mvc,write this java script code for fetch any data from controller:
$.ajax({
url: '#Url.Action("CallService", "MyScore")',
type: 'GET',
dataType: 'json',
cache: false,
data: {
'id': 29
},
success: function(color) {
//alert(color);
},
error: function() {
alert('Error occured');
}
});
and write this action in controller:
[HttpGet]
public ActionResult CallService(string id)
{
var idNum = Convert.ToInt32(id);
string color = idNum.ToString();
ViewBag.Myfamily = "razzaqi";
return Json(color, JsonRequestBehavior.AllowGet);
}
in view page write this code:
<h1> Hello Dear #ViewBag.Myfamily</h1>
when i run the project <h1> Hello Dear #ViewBag.Myfamily</h1> not show me ,but i think show me this output:
Hello Dear razzaqi
You are returning JSON not ViewBag. You need to send the "razzaqi" to as part of JSON object. Set up HTML as
<h1> Hello Dear <span id='familyname'></span></h1>
Modify You controller to return myfamily as part of JSON object.
[HttpGet]
public ActionResult CallService(int id)
{
string color = id.ToString();
return Json(new {
color = color
myfamily = "razzaqi"
}, JsonRequestBehavior.AllowGet);
}
Consume the result like
$.ajax({
url: '#Url.Action("CallService", "MyScore")',
type: 'GET',
dataType: 'json',
cache: false,
data: { 'id': 29 },
success: function (data) {
$('#familyname').text(data.myfamily)
},
error: function () {
alert('Error occured');
}
});
The Viewbag object is filled into the view, server side when making the view. Your ajax call contacts the server asking about Json data after the view is already made.
So you are too late passing objects to your viewbag if you do it this way...
There are however some workarounds/solutions for this problem:
Let the Controller return the variable in the Json it's returning.
Simple, efficient way to get the data you need
Html helpers etc. Won't work however and sometimes you just need that horrible viewbag...
Reload a partialview when doing the ajax call.
Takes more time to implement, You'll have to create a new action and partialview.
Good when you want more content to change on the call and want to use html helpers etc.

How do I update a javascript variable from controller?

I'm getting the model from the view with this:
<script>
Module.getModel(#Html.Raw(Json.Encode(Model)))
</script>
Which calls this:
var getModel = function(model) {
vModel= model;
};
This works to initially get the model, but I need to update one of the model values via dialog ajax.
var loc = $("#Location").val();
$.ajax({
url: $("#root").attr("href") + "Home/SetLocation",
context: $(this),
type: 'POST',
data: { location: loc },
success: function() {
$(this).dialog("close");
reloadGrid();
},
error: function() {
alert("There was a problem updating your Location.");
}
});
The controller action saves the location to profile and redirects to "Index" action:
public ActionResult SetLocation(string location)
{
_dashboardTasks.SaveLocationToProfile(location);
return RedirectToAction("Index");
}
Which updates the model with the new profile information and returns it to the view:
public ActionResult Index(HomeViewModel homeViewModel)
{
SetUserLocation(homeViewModel);
return View(homeViewModel);
}
At this point the breakpoint on the first code block is hit again, but the function for it, getModel, is never called and the javascript model is never updated. So the success function which calls for the grid to reload, reuses the old data instead of the new data.
How can I update vModel with the value changed in the controller?
Do I have to add a declaration to the success function explicitly redefining the value?
success: function() {
$(this).dialog("close");
vModel.Location = loc;
reloadGrid();
},
This works, but I don't understand why the model is not being updated with the current code.

Call ASP.NET C# Controller Method from Javascript

I have a var toto in a javascript file. And I want to call a C# Controller Method who return a string and of course assign the resulted string to toto.
I tried some ways to achieve this but nothing seems to work.
Somebody can explain me the simpliest way to achieve that ? It's a Windows Azure project.
Many Thanks !
You could use AJAX. For example with jQuery you could use the $.getJSON method to send an AJAX request top a controller action that returns a JSON encoded result and inside the success callback use the results:
$.getJSON('/home/someaction', function(result) {
var toto = result.SomeValue;
alert(toto);
});
and the controller action:
public ActionResult SomeAction()
{
return Json(new { SomeValue = "foo bar" }, JsonRequestBehavior.AllowGet);
}
You have to use JSON:
Controler
public class PersonController : Controller
{
[HttpPost]
public JsonResult Create(Person person)
{
return Json(person); //dummy example, just serialize back the received Person object
}
}
Javascript
$.ajax({
type: "POST",
url: "/person/create",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: jsonData,
success: function (result){
console.log(result); //log to the console to see whether it worked
},
error: function (error){
alert("There was an error posting the data to the server: " + error.responseText);
}
});
Read more: http://blog.js-development.com/2011/08/posting-json-data-to-aspnet-mvc-3-web.html#ixzz1wKwNnT34

How to send Json object (or string data) from Javascript xmlhttprequest to MVC Controller

I created a web application in ASP.NET MVC and trying to call a controller through Javascript AJAX. In Jquery we can send a json object which MVC Model Binder automatically tries to create a .NET object and pass in the controller as an argument.
However I am using a web workers in which jquery cannot be used. So I am making the AJAX call through the vanilla xmlhttprequest object. Is there a a way to send the Json object through this method?
I used the xmlhttprequest's send method but the model object comes as null in the controller :(
You should just be able to use JSON2 to stringify it and set the Content-Type header to application/json when you do the post.
http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js
You would do something like:
var xhr = new XMLHttpRequest();
xhr.open('POST', '/Controller/Action');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
xhr.send(JSON.stringify(myData));
Here's an example. It assumes that you are using ASP.NET MVC 3.0 which has a built-in JsonValueProviderFactory. If this is not your case you could take a look at this blog post.
View model:
public class MyViewModel
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult SomeAction(MyViewModel model)
{
return Content("success", "text/plain");
}
}
View:
<script type="text/javascript">
var http = new XMLHttpRequest();
var value = '{ "prop1": "value 1", "prop2": "value 2" }';
// It would be better to use JSON.stringify to properly generate
// a JSON string
/**
var value = JSON.stringify({
prop1: 'value 1',
prop2: 'value 2'
});
**/
http.open('POST', '/Home/SomeAction', true);
http.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
http.setRequestHeader('Content-Length', value.length);
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(value);
</script>
Using $.Ajax(), you can easily got the data from javascript to Controller in MVC.
For Reference,
var uname = 'Nikhil Prajapati';
$.ajax({
url: "/Main/getRequestID", // This is path of your Controller with Action Result.
dataType: "json", // Data Type for sending the data
data: { // Data that will be passed to Controller
'my_name': uname, // assign data like key-value pair
// 'my_name' like fields in quote is same with parameter in action Result
},
type: "POST", // Type of Request
contentType: "application/json; charset=utf-8", //Optional to specify Content Type.
success: function (data) { // This function is executed when this request is succeed.
alert(data);
},
error: function (data) {
alert("Error"); // This function is executed when error occurred.
}
)};
and, Now At the Controller Side,
public ActionResult getRequestID(String my_name)
{
MYDBModel myTable = new Models.MYDBModel();
myTable.FBUserName = my_name;
db.MYDBModel.Add(myTable);
db.SaveChanges(); // db object of our DbContext.cs
//return RedirectToAction(“Index”); // After that you can redirect to some pages…
return Json(true, JsonRequestBehavior.AllowGet); // Or you can get that data back after inserting into database.. This json displays all the details to our view as well.
}
For more reference..
just visit..
Send Data from Java Script to Controller in MVC

Categories

Resources