MVC passes JSON ViewModel for viewing

I have an MVC application in which I use various JsonResult to populate the javascript ViewModel.

I used several jQuery Ajax requests to populate the model, but I would like most of the original model to be passed to the view on the server.

ViewModel has 3-5 parts (depending on where the user is in the application):

  • The main links to pages, they do not change very often and can be accurate throughout the user's session.
  • Custom notifications.
  • User data.
  • (optional) Viewable data
  • (optional) different data

I am currently using this code to download the first three parts:

 $(document).ready(function () { ko.applyBindings(viewModel); @Html.Raw(ViewBag.Script) // Piece 1. Almost always the same thing postJSON('@Url.Action("HomeViewModelJson", "Home")', function (data) { if (data == null) return; for (var i in data.Tabs) { viewModel.tabs.push({ name: data.Tabs[i] }); } for (var i in data.Buttons) { viewModel.metroButtons.push({ name: data.MetroButtons[i] }); } for (var i in data.Ribbons) { viewModel.ribbons.push(data.Ribbons[i]); } ApplyButtonThemes(); }); }); // Piece 2. Changes constantly. OK as is postJSON('@Url.Action("GetNotifications", "NotificationAsync")', function (nots) { viewModel.notifications.removeAll(); ko.utils.arrayForEach(nots, function (item) { item.readNotification = function () { hub.markNotificationAsRead(this.Id); return true; }; viewModel.notifications.push(item); }); }); // Piece 3. Changes but should also be loaded at startup postJSON('@Url.Action("GetUser", "UserAsync")', function (user) { viewModel.user(koifyObject(user)); }); postJSON = function(url, data, callback) { if($.isFunction(data)) { callback = data; data = {}; } $.ajax({ 'type': 'POST', 'url': url, 'contentType': 'application/json', 'data': ko.toJSON(data), 'dataType': 'json', 'success': callback }); }; 

I tried to do something similar, but found that using @Html.Action("HomeViewModelJson", "Home") the HTTP headers change and the whole page is sent as if it were JSON

  (function (data) { if (data == null) return; for (var i in data.Tabs) { viewModel.tabs.push({ name: data.Tabs[i] }); } for (var i in data.MetroButtons) { viewModel.metroButtons.push({ name: data.MetroButtons[i] }); } for (var i in data.Ribbons) { viewModel.ribbons.push(data.Ribbons[i]); } ApplyMetroButtonThemes(); })('@Html.Action("HomeViewModelJson", "Home")'); 

What I would like to do is use the existing JsonResult to receive Json data in my server-side ViewModel before the page is sent to the user.

Are there any options that will allow me to do this without rewriting my controllers?

+6
source share
1 answer

When you render the main view, you use the view model, right? In this view, the model simply populates the properties that you do not want to retrieve using AJAX before returning the view:

 public ActionResult Index() { MyViewModel model = ... model.Prop1 = ... model.Prop2 = ... return View(model); } 

for example, if you have the following action that is used for AJAX requests:

 public JsonResult GetProp1() { Property1ViewModel model = ... return Json(model, JsonRequestBehavior.AllowGet); } 

you can use it from the main action to populate individual properties:

 model.Prop1 = (Property1ViewModel)GetProp1().Data; model.Prop2 = (Property2ViewModel)GetProp2().Data; 

and then in the appropriate view, you can use the Json.Encode method to serialize the entire model into a JSON string:

 @model MyViewModel <script type="text/javascript"> var model = @Html.Raw(Json.Encode(Model)); // You could use model.Prop1 and model.Prop2 here </script> 

or you can also serialize individual properties if you do not need all of them:

 @model MyViewModel <script type="text/javascript"> var prop1 = @Html.Raw(Json.Encode(Model.Prop1)); </script> 
+9
source

Source: https://habr.com/ru/post/914858/


All Articles