ASP.NET MVC-combiner le résultat Json avec ViewResult

puis-je retourner un résultat Json qui contient aussi une vue rendue?

j'en ai besoin pour retourner la nouvelle ID d'un formulaire soumis avec son HTML et d'autres propriétés.

cela peut aussi être utile quand j'ai besoin de retourner deux (ou plus) Résultats de vue d'une action à l'intérieur d'un objet Json.

Merci!

29
demandé sur elado 2009-07-25 14:54:49

4 réponses

vous pouvez aussi rendre un ViewResult Partielà une chaîne, puis passer cette chaîne via JSON à votre vue, le rendant dans votre page en utilisant jQuery.

vous pouvez le voir dans ce post: http://www.atlanticbt.com/blog/asp-net-mvc-using-ajax-json-and-partialviews/.

j'ai créé une extension pour la rendre plus facile:

public static class MvcHelpers
{
    public static string RenderPartialView(this Controller controller, string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
            viewName = controller.ControllerContext.RouteData.GetRequiredString("action");

        controller.ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
            var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
            viewResult.View.Render(viewContext, sw);

            return sw.GetStringBuilder().ToString();
        }
    }
}

Dans mon contrôleur je l'appelle comme suit:

const string msg = "Item succesfully updated!";
return new JsonResult
           {
               Data = new
                          {
                              success = true, 
                              message = msg,
                              view = this.RenderPartialView("ProductItemForm", model)
                          },
               JsonRequestBehavior = JsonRequestBehavior.AllowGet
           };

Où "cela" est le contrôleur dans le cas, "ProductItemForm" est mon point de vue et "modèle" est mon productItem objet :)

Espérons que cette aide ;)

40
répondu Diego Ponciano 2010-06-12 06:13:36

Dans le premier cas, je pense que vous pouvez simplement retourner HTML, mais intégrer les données dans le formulaire retourné. Utilisez jQuery pour accéder aux données de votre callback succès.

$.ajax({
    url: '<%= Url.Action( "MyAction" )',
    dataType: 'html',
    data: $('form').serialize(),
    success: function(data) {
                $('form').html(data);
                var id = $('form').find('input#formId[type=hidden]').val();
             }
});

dans le second cas, une vue partagée qui prend deux ou plusieurs noms de vues et utilise RenderPartial est probablement une meilleure solution que retourner HTML par JSON.

Multiview.aspx

 ...
<% foreach (string viewName in Model.Views)
   {
       Html.RenderPartial( viewName );
   }
%>

Puis dans votre action:

public ActionResult MyAction(...)
{
     ... set up model with data
     model.Views = new List<string> { "View1", "View2" };

     return View( "Multiview", model );
}
1
répondu tvanfosson 2009-07-25 13:33:20

je pense à ce problème depuis un moment. Ma solution est similaire à retourner la vue partielle HTML comme une chaîne JSON, mais le contraire. Renvoie une vue partielle avec JSON intégré. Je n'ai pas aimé cette approche jusqu'à ce que jQuery 1.4.3 fusionne leur.méthode data () avec l'attribut de données HTML 5. Cela rend beaucoup plus facile de générer JSON dans un ASP.NET MVC view, and read it via jQuery.

Voir exemple... Il n'est pas parfait, mais j'aime beaucoup mieux que de créer des entrées de forme cachées ou des helpers qui rendent la vue partielle avant de la retourner.

Vue Partielle:

<div id="content">
  <h1>Some Title</h1>
  <p>Ipsum Lorem</p>
</div>
<div id="dataDiv" data-stuff='{ "name": "Jason", "color": "Blue"}'></div>

JavaScript qui lit le JSON

$(document).ready(function () {
  var name = $('#dataDiv').data('stuff').name;
  var color = $('#dataDiv').data('stuff').color;
  alert(name + ' ' + color);
});

Cela peut sembler aller à l'encontre du "principe de responsabilité unique" (si vous l'appliquez à vue). Toutefois, si votre application exige que les deux éléments de données soient transmis en réponse, Je ne vois aucun inconvénient à cela. Et tant que votre modèle est construit correctement, ça ne va pas à l'encontre des principes de conception.

1
répondu Jason Capriotti 2010-10-26 01:38:48

cela pourrait être un peu hacky (et j'écris du haut de ma tête) mais vous pourriez vouloir créer votre propre sous-classe D'ActionResult et aussi mettre en œuvre un ResultFilter qui intercepterait ces types spécifiques D'ActionResult et rendre les vues pertinentes et remplir un JsonResult et le retourner.

Par exemple, vous pouvez définir:

public CompoundResult: ActionResult
{
    public string ViewName { get; set; }
    public JsonResult JsonResult { get; set; }
    public CompoundResult(string viewName, JsonResult jsonResult)
    {
       ViewName = viewName;
       JsonResult = jsonResult;
    }
}

puis, dans un ResultFilter, rendre la vision pertinente et fusionner dans l'endroit correspondant dans le JsonResult et enfin retourner le JsonResult au client.

en dehors de tout cela, vous pourriez vouloir changer votre approche dans la façon dont vous faites ceci, par exemple. vous pouvez essayer de retourner une vue complète (i.e. HTML) à partir de votre action dont une partie est la vue que vous voulez retourner mais qui inclut également quelques informations supplémentaires qui auraient autrement été dans votre objet JSON. Vous pouvez extraire les composants pertinents du HTML retourné en utilisant des opérations jQuery simples du côté client.

0
répondu paracycle 2009-07-25 11:41:19