recibir receive por net mvc enviar datos asp .net javascript asp.net-mvc json

receive - ASP.NET MVC: Cómo convertir View Model en objeto Json



recibir json mvc (8)

@ Html.Raw (Json.Encode (object)) se puede usar para convertir el objeto modal de vista a JSON

Soy un desarrollador de Java nuevo para .NET. Estoy trabajando en un proyecto .Net MVC2 donde quiero tener una vista parcial para envolver un widget. Cada objeto del widget JS tiene un objeto de datos JSON que se completará con los datos del modelo. Luego, los métodos para actualizar estos datos se vinculan a los eventos cuando los datos se cambian en el widget o si esos datos se cambian en otro widget. El código es algo como esto.

MyController

virtual public ActionResult DisplaySomeWidget(int id) { SomeModelView returnData = someDataMapper.getbyid(1); return View(myview, returnData); }

myview.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SomeModelView>" %> <script type="text/javascript"> //creates base widget object; var thisWidgetName= new Widget(); thisWidgetName.updateTable= function() { // UpdatesData }; $(document).ready(function () { thisWidgetName.data = <% converttoJSON(model) %> $(document).bind(''DATA_CHANGED'', thisWidgetName.updateTable()); }); </script> <div><%:model.name%></div>

Lo que no sé es cómo enviar los datos como SomeModelView y luego poder usarlos para llenar el widget y convertirlo a Json. Parecía que había algunas maneras realmente simples de hacerlo en el controlador pero no en la vista. Me imagino que esta es una pregunta básica que he estado haciendo durante unas horas tratando de hacer esta astilla.


Andrew tuvo una gran respuesta, pero quise tocarlo un poco. La forma en que esto es diferente es que me gusta que mis ModelViews no tengan datos generales en ellas. Solo los datos para el objeto. Parece que ViewData se ajusta a la factura de los datos generales, pero por supuesto soy nuevo en esto. Sugiero hacer algo como esto.

Controlador

virtual public ActionResult DisplaySomeWidget(int id) { SomeModelView returnData = someDataMapper.getbyid(1); var serializer = new JavaScriptSerializer(); ViewData["JSON"] = serializer.Serialize(returnData); return View(myview, returnData); }

Ver

//create base js object; var myWidget= new Widget(); //Widget is a class with a public member variable called data. myWidget.data= <%= ViewData["JSON"] %>;

Lo que esto hace por ti es que te da los mismos datos en tu JSON que en tu ModelView para que puedas regresar el JSON a tu controlador y tendrá todas las partes. Esto es similar a solo solicitarlo a través de JSONRequest; sin embargo, requiere una llamada menos, por lo que le ahorra esa sobrecarga. Por cierto, esto es funky para Dates, pero parece ser otro hilo.


Bien hecho, acabas de comenzar a usar MVC y has encontrado su primer defecto importante.

Realmente no desea convertirlo a JSON en la vista, y realmente no desea convertirlo en el controlador, ya que ninguna de estas ubicaciones tiene sentido. Lamentablemente, estás atrapado en esta situación.

Lo mejor que he encontrado hacer es enviar el JSON a la vista en un ViewModel, así:

var data = somedata; var viewModel = new ViewModel(); var serializer = new JavaScriptSerializer(); viewModel.JsonData = serializer.Serialize(data); return View("viewname", viewModel);

luego usa

<%= Model.JsonData %>

en tu opinión. Tenga en cuenta que el .NET JavaScriptSerializer estándar es bastante basura.

hacerlo en el controlador al menos lo hace comprobable (aunque no exactamente como el anterior; es probable que desee tomar un ISerializer como dependencia para que pueda simularlo)

Actualice también, con respecto a su JavaScript, sería una buena práctica para envolver TODOS los widget JS que tiene arriba así:

( // all js here )();

De esta forma, si coloca varios widgets en una página, no obtendrá conflictos (a menos que necesite acceder a los métodos desde otra parte de la página, pero en ese caso debe registrar el widget con algún widget de todos modos). Puede que no sea un problema ahora, pero sería una buena práctica agregar los corchetes ahora para ahorrar muchos esfuerzos en el futuro cuando se convierta en un requisito, también es una buena práctica de OO encapsular la funcionalidad.


En mvc3 con razor @Html.Raw(Json.Encode(object)) parece ser el truco.


Extendiendo la gran respuesta de . Puede crear un HtmlHelper simple.

public static IHtmlString RenderAsJson(this HtmlHelper helper, object model) { return helper.Raw(Json.Encode(model)); }

Y en su opinión:

@Html.RenderAsJson(Model)

De esta forma, puede centralizar la lógica para crear el JSON si, por algún motivo, desea cambiar la lógica más tarde.


Me pareció muy agradable hacerlo así (uso en la vista):

@Html.HiddenJsonFor(m => m.TrackingTypes)

Aquí está el método de ayuda según la clase de extensión:

public static class DataHelpers { public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) { return HiddenJsonFor(htmlHelper, expression, (IDictionary<string, object>) null); } public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) { return HiddenJsonFor(htmlHelper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); } public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) { var name = ExpressionHelper.GetExpressionText(expression); var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); var tagBuilder = new TagBuilder("input"); tagBuilder.MergeAttributes(htmlAttributes); tagBuilder.MergeAttribute("name", name); tagBuilder.MergeAttribute("type", "hidden"); var json = JsonConvert.SerializeObject(metadata.Model); tagBuilder.MergeAttribute("value", json); return MvcHtmlString.Create(tagBuilder.ToString()); } }

No es súper sofisticado, pero resuelve el problema de dónde colocarlo (¿en Controlador o a la vista?) La respuesta es obviamente: ninguno;)


Puedes usar Json de la acción directamente,

Tu acción sería algo como esto:

virtual public JsonResult DisplaySomeWidget(int id) { SomeModelView returnData = someDataMapper.getbyid(1); return Json(returnData); }

Editar

Acabo de ver que asumes que este es el Model de una Vista así que lo anterior no es estrictamente correcto, tendrías que hacer una llamada Ajax al método del controlador para obtener esto, el ascx no tendría un modelo per se, lo haré dejar mi código solo en caso de que sea útil para usted y puede modificar la llamada