MVC3 (Razor) Json Get deserialized data in the Controller - asp.net-mvc

I need help again with Asp.Net MVC (Razor View Engine).
In my View (Index) I have
#model IEnumerable<Movie>
I want to pass the Model to the Controller: I stringify the model in this way:
<script type="text/javascript">
function postData(){
var urlact='#Url.Action("createDoc")';
var model ='#Html.Raw(Json.Encode(Model));
$.ajax({
data: JSON.stringify(model),
type:"POST",
url:urlact,
datatype:"json",
contentType:"application/json; charset=utf-8"
});
}
</script>
Everything seems to work, cause I know the stringified data is:
'[{"ID":1,"Title":"The Lord of the Rings: The Fellowship of the Ring","ReleaseDate":"\/Date(1007938800000)\/","Genre":"Fantasy","Price":93000000.00},{"ID":2,"Title":"The Lord of the Rings: The Two Towers","ReleaseDate":"\/Date(1039042800000)\/","Genre":"Fantasy","Price":94000000.00},{"ID":3,"Title":"The Lord of the Rings: The Return of the King","ReleaseDate":"\/Date(1070233200000)\/","Genre":"Fantasy","Price":94000000.00}]';
The problem is: in Controller, methodName "createDoc" (as declared in the script) I cannot access to the stringified data.
Following some samples founded on the web, my method is something like this:
[HttpPost]
public ActionResult createDoc(IEnumerable<Movie> movies)
{
//...using movies list
return View();
}
Why can't I access to the stringified data? How can I do it, is there some method to call to deserialize the model in the Controller method?
Also, can I use the serialize() method instead of the stringify() one? If so, what's the syntax, View & Controller side?
Thank you.

You've already got stringified data in your JavaScript variable model. You only need to call JSON.stringify on objects which aren't strings.
If you want to post the data to your action without modifying model, just pass in model without the JSON.stringify and the ModelBinder will take care of deserializing it to IEnumerable<Movie> for you.
If you want to use model as something other than a string, you'll want to call JSON.parse on the string. In other words:
var model = JSON.parse('#Html.Raw(Json.Encode(Model))');
Then, you'd want to keep your JSON.stringify call.
Finally, stringify is a method on a browser-specific object JSON, whereas serialize is a method on the ASP.NET MVC-specific Json object. Two different worlds, same name.

Related

Can i pass JSON instead of Model from my controller to my Razor view

I have a view that inherit the following:-
#model MvcApplication.Models.Application
But i need to know if it is possible to pass JSON objects to my view in the same way i am passing the model objects?
Since i have the following Controller:-
public ActionResult ListPackages()
{
using (var client = new WebClient())
{
var query = HttpUtility.ParseQueryString(string.Empty);
//code goes here ....
return Content(json, "application/json");
}
}
which returns JSON using a API call, and then i am displaying the JSON on the view using JavaScript as follow:
$.ajax({
url: $('#geturl').data('url'),
type: 'GET',
cache: false,
success: function (result) {
$.each(result.data, function (key, val) {
var str = val.packageName;
$('<li/>', { text: str })
.appendTo($('#products'));
});
}
The problem with displaying the JSON using JavaScript is that it will make too difficult for me to work easily with the JSON objects, such as creating links based on the returned JSON or creating table that contain the JSON. So my question is: Is it possible to pass a JSON object instead of a Model object from my controller to my view?
Server- vs client-side confusion
You're talking two things here:
Creating a view: controller passes model to the view on the server side and it doesn't make much sense to do so using JSON, because an in-memory object is being passed to view engine.
Consuming JSON data on the client: what you're talking about here is client-server Ajax communication where you request data from the client and get JSON returned from the server. This has arguably nothing to do with model data being passed to the view
Best solution using JSON
In order to easily consume JSON data (in your case it's an array of packages) on the client to generate resulting populated HTML is to use some sort of templating on the client side. jQuery used to have non-final templating plugin which is now a separate project. I've had great experience with it but there are other plugins as well. Use the one that you feel most comfortable with its syntax.
Where to put those templates?
If you know the structure of your JSON objects passed from the server at the point of creating your view, you can put templates in the view itself and they'll just wait untill being used on the client.
If you don't know the structure of your JSON objects then you'll have to pass templates either along JSON object or as a separate request.
The first approach is the usual one, the second one is rarely used and is much more dynamic.
Best solution not using JSON
If you don't like parsing JSON to HTML results (either manually or using templates), you can always make Ajax requests to your controller action, which would return a prepared HTML as a partial view instead of JSON result. This way, you could easily just put that HTML onto your page without any JSON data manipulation.
What do you gain here? Well suppose you have this functionality in your app:
You have a view that displays a paged list of packages.
When user first accesses the page first page of packages are being returned
Paging to next page is done via Ajax and the list is being replaced by returned data
If you'd create a partial view for your subsequent Ajax request, you can use the same partial view in your main view to display the first page of packages. This will ensure that you only have to change one partial view and display would change on inital page load as well as subsequent package paging.
If you used view + JSON + templating that means that you have to maintain two presentations of package list: the one being used in the view for the first page and the template that displays subsequent paging.
Which one then?
All things being equal it makes the second solution better. But the choice of course depends on your case (of things not being equal) and you should be able to determine which one is best in your scenario.
No, you can't. A view must be strongly typed to a model. So one solution would be to deserialize this JSON into a model object before passing it to the view:
public ActionResult ListPackages()
{
using (var client = new WebClient())
{
var query = HttpUtility.ParseQueryString(string.Empty);
//code goes here ....
var model = new JavaScriptSerializer().Deserialize<MyViewModel>(json);
return View(model);
}
}
where MyViewModel would of course reflect the JSON structure that you are working with.

knockoutjs submit with ko.utils.postJson issue

I followed the http://blog.stevensanderson.com/2010/07/12/editing-a-variable-length-list-knockout-style/ article to submit data using ko.utils.postJson and navigate to a different view from the controller
I used ko.utils.postJson(location.href, {model: ko.toJson(viewModel)}); to submit the data but the model submitted to the server has empty properties.
ko.utils.postJson(location.href, {model: viewModel}); failed too.
The client viewModel has additional properties than the server model but I believe if it works with $ajax post method, it should work with KO post
It worked if I pass the model as under
ko.utils.postJson(location.href,
{model: {P1:this.p1(), P2:this.p2(), P3: this.p3()}});
Do I have to map each property before submission? Its also really confusing when to use () for viewModel properties
Server Code
[HttpPost]
public ActionResult SearchProperty([FromJson]MyModel model)
{
try
{
return View("XYZ", model);
}
catch (Exception e)
{
}
}
Knockout provides a utility function that will turn an object containing observables into a plain JavaScript object. The utility function is ko.toJS. So, if you did:
{ model: ko.toJS(viewModel) }
Then, it would handle unwrapping all of your observables.
Additionally, there is another function ko.toJSON that will do a ko.toJS and then do JSON.stringify on the result. This is useful when you really need JSON instead of a JavaScript object.

Asp.Net MVC Passing an object from Url.Action in View to Controller

While there appears to be similar questions I do not believe I found one where somebody was passing the entire model from view to controller, the closest I found was passing a data value in the model to the controller... which is not what I want to do...
I want to pass the model object to the applicable controller action result as a parameter
and do what I want to do with the data in the model object from within the controller...
code abbreviated...
in the view i am using Url.Action(string, string, object) to pass the controller method name, and the route to it as the 2nd parameter, and the entire model object as the 3rd parameter...
my third parameter is the problem, the Url.Action(string, string) over load works fine with the same values, so I don't have any problem getting to the controller action result method, with the values I am using...
view code snippet...
$('#ControllerActionResult').click(function (e) {
window.location = '<%: Url.Action("ControllerActionResult", TheRoute, new { pModel = Model } ) %>';
});
controller code snippet...
public ActionResult ControllerActionResult(object pModel)
{
}
My error is "CS1502: The best overloaded method match for 'System.Web.Mvc.UrlHelper.Action(string, string, object)' has some invalid arguments" and the window location line is highlighted...
Am I missing something obvious?
I don't think you can do that. Url is trying to build a url, not call the action method directly. You can pass individual key value pairs via the anonymous object, which Url can then use to build a link. Model binding can take care of putting the key value pairs into the incoming model for you.
Also, is TheRoute a string as well?
If you need a Url you don't have many alternatives. Either pass all the values to rebuild the model, or just pass a key value to retreive the model from the database again (or maybe session / viewdata / tempdata, if you're using that).
There might be several issues in your code. But I will answer what you want to know, how to send data to controller from js. You have to first send "model" in json format, possibly with jquery.ajax. For example,
$.ajax({
url: '#Url.Action("ControllerActionResult")',
type: 'POST',
data: JSON.stringify(model),
dataType: 'json',
processData: false,
contentType: 'application/json; charset=utf-8',
success: OnSuccess
});
In controller, you have to have a defined class for the "model" and that should be the parameter of your controller.
[HttpPost]
public ActionResult ControllerActionResult(Model model) {
if (Request.IsAjaxRequest()) {
//to do
}
}
Otherwise, MVC cannot find a right controller to call.
try with following code it works for me
Javascript:
var location ='#url,action(string ,obj)'; window.location=location;
Controller:
public ActionResult index(string obj){return view();}
hope this works for you.

How can I post an object in ASP.NET MVC?

I have a View that receives a List of an object and for each object in this list I generate a Partial View.
It's a seach result, such as Google. Each result will be wrapped in a form and each result will have its "save" post button.
So, when I post a form, I will lead user to another page where he will confirm the result he chose.
Some itens of the result I can save them to hidden fields and pass them in a FormCollection to this other page.
But, I was wondering if there's a way that I could pass this result object via post, in stead of creating hidden fields (?).
Thanks a lot!!
Hmmm, I think the answer is probably "no", but have a look at TempData and see if that might do the trick.
How about storing them in the database and assigning a resource identifier such as a GUID to the whole thing and only posting that?
You could write a custom serialize method in JS and then stuff the serialized object in a hidden field, like this:
<script type="text/javascript">
object; // from your search
var serialized = serialize(object);
$("#objectHidden").val(serialized);
</script>
Then on the ASP.NET MVC side, you would write a custom Deserialize() method and deserialize it into the object you want:
public ActionResult foo(FormCollection form)
{
MyObject object = MyObject.Deserialize(form["objectHidden"]);
}
This code is quick and dirty, but I hope it conveys the idea.

Accessing ASP.NET MVC model data from with Javascript

I have a strongly typed View that accepts a Customer model, this customer model is a LINQ2SQL partial class that has a property called Journeys which returns all Journeys that are associated with this Customer.
I was wondering if it would be possible to access the Customer.Journeys property as a JSON object from within the Javascript.
Is this possible? If so how would I go about accessing it? Would I be best to create a FormViewModel and store the Customer details and Journey details as a JSON object there and pass it to the javascript function using something like:
<% MyJavascriptFunction(Model.JSONJourneys) %>
Or should I alter the Journeys partial class and add a .ToJson() property? Or something completely different?
Thanks.
I would do this:
Using NewtonSoft Json Library, you can convert any C# model object to Json at the client end
http://james.newtonking.com/pages/json-net.aspx
in the view
<script>
var jsobject = <%= JsonConvert.SerializeObject(Model.Journeys) %>;
function myfunction (){
//work with object
}
</script>
How about exposing your Customer model through a Javascript view and loading it as a regular javascript file in your HTML?
Like this:
In your HTML view:
<script type="text/javascript" src="/customers/123/json">
And in your controller:
public ActionResult CustomerJson(int customerId)
{
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var customer = Customer.Get(customerId);
var serializedCustomer = serializer.Serialize(customer);
return JavaScript(
"function getCustomer() { return (" + serializedCustomer + "); }");
}
This question has long been answered (and accepted), but I wanted to pass along a response to a similar question that helped me. His answer takes advantage of MVC3/Razor syntax:
https://stackoverflow.com/a/7486214/249153:
In mvc3 with razor #Html.Raw(Json.Encode(object)) seems to do the
trick.

Resources