2009-05-26 13 views
17

Ho un'app MVC con alcune azioni del controller che vengono chiamate utilizzando Ajax (jQuery) e restituiscono il contenuto di viste parziali che aggiorna una parte dello schermo. Ma quello che preferirei fare è restituire a JSON qualcosa del genere.ASP MVC Visualizza contenuto come JSON

return Json(new { 
    Result = true, 
    Message = "Item has been saved", 
    Content = View("Partial") 
}); 

Dove l'HTML è solo una proprietà di Json. Ciò significa che ho bisogno di recuperare l'HTML che viene reso dal metodo View. C'è un modo semplice per farlo, alcuni esempi che ho visto sono abbastanza contorti.

Modifica: questa domanda era originariamente per ASP.NET MVC 1, ma se la versione 2 rende più facile mi piacerebbe sentire la risposta.

+0

ho cambiato il tag per asp.net-MVC così la gente lo vedono nelle loro preferenze. –

+0

Hai trovato una risposta a questo? Sembra essere una domanda abbastanza popolare. – Jon

+0

Non ancora. Non penso che la risposta di NerdDinner faccia quello che voglio. – Craig

risposta

4

NerdDinner ha alcuni buoni esempi di questo. Ecco l'SearchController in NerdDinner, che ha un metodo chiamato SearchByLocation che restituisce un elenco di JsonDinners (source code per NerdDinner è Creative Commons):

namespace NerdDinner.Controllers { 

    public class JsonDinner { 
     public int  DinnerID { get; set; } 
     public string Title  { get; set; } 
     public double Latitude { get; set; } 
     public double Longitude { get; set; } 
     public string Description { get; set; } 
     public int  RSVPCount { get; set; } 
    } 

    public class SearchController : Controller { 

     IDinnerRepository dinnerRepository; 

     // 
     // Dependency Injection enabled constructors 

     public SearchController() 
      : this(new DinnerRepository()) { 
     } 

     public SearchController(IDinnerRepository repository) { 
      dinnerRepository = repository; 
     } 

     // 
     // AJAX: /Search/FindByLocation?longitude=45&latitude=-90 

     [AcceptVerbs(HttpVerbs.Post)] 
     public ActionResult SearchByLocation(float latitude, float longitude) { 

      var dinners = dinnerRepository.FindByLocation(latitude, longitude); 

      var jsonDinners = from dinner in dinners 
           select new JsonDinner { 
            DinnerID = dinner.DinnerID, 
            Latitude = dinner.Latitude, 
            Longitude = dinner.Longitude, 
            Title = dinner.Title, 
            Description = dinner.Description, 
            RSVPCount = dinner.RSVPs.Count 
           }; 

      return Json(jsonDinners.ToList()); 
     } 
    } 
} 
+0

Non sono sicuro che faccia ciò che voglio. Restituisce un elenco JSON di elementi. A proposito Robert, non ti ho mai scelto come sviluppatore mentre suonavo per St.Kilda. – Craig

+0

Penso che tu mi abbia confuso con qualcun altro. :) –

+0

Ho capito correttamente (dal tuo codice originale) che vuoi prendere visione per la corsa quando restituisci JsonResult? Perché è abbastanza facile restituire una cena singola piuttosto che una lista di cene. –

0

Perché non solo hanno html "parziali" statiche e afferrare tutto la dinamica contenuto da json? Dovresti essere in grado di caricare i file html con jquery quando la pagina viene caricata o quando è necessario abbastanza facilmente.

Questo link su JQuery Ajax dà questo esempio:

//Alert out the results from requesting test.php (HTML or XML, depending on what was returned). 
$.get("test.php", function(data){ 
    alert("Data Loaded: " + data); 
}); 
+0

Potrei farlo, ma il modo in cui ASP MVC funziona sarebbe un bel po 'più di lavoro di scrittura del codice idraulico. – Craig

11

Ecco la risposta! È un leggero cambiamento dal metodo Martin From's e sembra funzionare. Se ci sono cose mancanti, le persone possono apportare modifiche al codice nella sezione dei commenti. Grazie.

Da voi controller di chiamata in questo modo:

string HTMLOutput = Utils.RenderPartialToString("~/Views/Setting/IndexMain.ascx", "", items, this.ControllerContext.RequestContext); 

Aggiungere questo ad una classe

public static string RenderPartialToString(string controlName, object viewData, object model, System.Web.Routing.RequestContext viewContext) 
{ 
    ViewDataDictionary vd = new ViewDataDictionary(viewData); 
    ViewPage vp = new ViewPage { ViewData = vd }; 

    vp.ViewData = vd; 
    vp.ViewData.Model = model; 
    vp.ViewContext = new ViewContext(); 
    vp.Url = new UrlHelper(viewContext); 

    Control control = vp.LoadControl(controlName); 

    vp.Controls.Add(control); 

    StringBuilder sb = new StringBuilder(); 

    using (StringWriter sw = new StringWriter(sb)) 
    using (HtmlTextWriter tw = new HtmlTextWriter(sw)) 
    { 
     vp.RenderControl(tw); 
    } 

    return sb.ToString(); 
} 
+0

Grazie per questo. Sto cercando di modificare leggermente questo aspetto per essere un po 'migliore e posterò il risultato. – Craig

+0

Non vedo l'ora di vedere cosa viene fuori – Jon

1

Ho passato età cercando di fare la stessa cosa. Ho una soluzione rapida che dovrà essere estesa.

NOTA: Posso vedere già un problema ..I cookie e le altre variabili vengono perse :(

Quello che ho fatto:

  1. Crea nuovo ActionResult

    public class JsonHtmlViewResult : ViewResult 
    { 
        public IJsonHtml Data { get; set; } 
    
        public override void ExecuteResult(ControllerContext context) 
        { 
         if (Data == null) 
         { 
          Data = new DefaultJsonHtml(); 
         } 
    
         using (StringWriter sw = new StringWriter()) 
         { 
          HttpRequest request = HttpContext.Current.Request; 
          HttpContext.Current = new HttpContext(request, new HttpResponse(sw)); 
    
          base.ExecuteResult(context); 
    
          Data.HtmlContent = sw.ToString(); 
         } 
    
         // Do the serialization stuff. 
         HttpResponseBase response = context.HttpContext.Response; 
         response.ClearContent(); 
         response.ContentType = "application/json"; 
    
         JavaScriptSerializer serializer = new JavaScriptSerializer(); 
         response.Write(serializer.Serialize(Data)); 
        } 
    } 
    
  2. la classe di dati

    public interface IJsonHtml 
    { 
        String HtmlContent { get; set; } 
    } 
    
    public class DefaultJsonHtml : IJsonHtml 
    { 
        public String HtmlContent { get; set; } 
    } 
    
  3. Le estensioni del controller

    public static ActionResult JsonHtmlViewResult(this Controller controller, string viewName, string masterName, object model, IJsonHtml data) 
    { 
        if (model != null) 
        { 
         controller.ViewData.Model = model; 
        } 
    
        return new JsonHtmlViewResult 
        { 
         Data = data, 
         ViewName = viewName, 
         MasterName = masterName, 
         ViewData = controller.ViewData, 
         TempData = controller.TempData 
        }; 
    } 
    
1

ho trovato una risposta più recente utilizzando rasoio che può essere utile http://codepaste.net/8xkoj2

public static string RenderViewToString(string viewPath, object model,ControllerContext context) 
{    
    var viewEngineResult = ViewEngines.Engines.FindView(context, viewPath, null); 
    var view = viewEngineResult.View; 


    context.Controller.ViewData.Model = model; 

    string result = String.Empty; 
    using (var sw = new StringWriter()) 
    { 

     var ctx = new ViewContext(context, view, 
            context.Controller.ViewData, 
            context.Controller.TempData, 
            sw); 
     view.Render(ctx, sw); 

     result = sw.ToString(); 
    } 

    return result; 
} 
0

Io non lo so in quanto che il numero di versione si può fare questo, ma al giorno d'oggi si può tornare JSON in un modo molto semplice:

public ActionResult JSONaction() 
{ 
    return Json(data, JsonRequestBehavior); 
} 

senza bisogno di aiutanti elaborati ecc

dati sono naturalmente i dati dal modello JsonRequestBehavior specifica se le richieste HTTP GET dal client sono consentite. (source), è opzionale DenyGet è il comportamento di default, quindi se usato principalmente JsonRequestBehavior.AllowGet e here Ecco perché questo è in là

+0

Il problema non sta restituendo Json ma allegando una visualizzazione a Json. – Craig