2009-05-26 13 views
17

Ich habe eine MVC-App mit einigen Controller-Aktionen, die mit Ajax (jQuery) aufgerufen werden und Teilansichten zurückgeben, die einen Teil des Bildschirms aktualisieren. Aber was ich lieber tun würde ist, JSON so etwas zurückzugeben.ASP MVC Inhalt als JSON anzeigen

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

Wo das HTML nur eine Eigenschaft des Json ist. Das bedeutet, dass ich den HTML-Code abrufen muss, der von der View-Methode gerendert wird. Gibt es einen einfachen Weg, dies zu tun, ein paar Beispiele, die ich gesehen habe, sind ziemlich verworren.

Edit: Diese Frage war ursprünglich für ASP.NET MVC 1, aber wenn Version 2 macht es einfacher würde ich gerne die Antwort hören.

+0

ich den Tag zu asp.net-mvc geändert, damit die Leute sie sehen in ihrer Prefs. –

+0

Haben Sie eine Antwort darauf gefunden? Es scheint eine ziemlich populäre Frage zu werden. – Jon

+0

Noch nicht. Ich glaube nicht, dass die NerdDinner-Antwort das macht, was ich will. – Craig

Antwort

4

NerdDinner hat einige ziemlich gute Beispiele dafür. Hier ist die SearchController in NerdDinner, die eine Methode namens SearchByLocation hat, die eine Liste von JsonDinners gibt (source code für NerdDinner ist 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

Ich bin mir nicht sicher, das macht was ich will. Es gibt eine Json-Liste von Elementen zurück. BTW Robert, ich habe dich nie als Entwickler ausgewählt, als du für St.Kilda gespielt hast. – Craig

+0

Ich denke du hast mich mit jemand anderem verwechselt. :) –

+0

Verstehe ich richtig (von Ihrem ursprünglichen Code), dass Sie einen Blick für die Fahrt mitnehmen möchten, wenn Sie das JsonResult zurückgeben? Weil es einfach genug ist, ein einzelnes Abendessen anstatt einer Liste von Abendessen zurückzugeben. –

0

Warum nicht einfach haben statische HTML „partials“ und greifen alle dynamischen Inhalt von der Json? Sie sollten in der Lage sein, die HTML-Dateien mit jquery zu laden, wenn die Seite geladen wird oder wenn sie recht einfach benötigt wird.

Dieser Link auf JQuery Ajax gibt folgendes Beispiel:

//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

Ich könnte dies tun, aber die Art, wie ASP MVC funktioniert, wäre es ein bisschen mehr Arbeit schreiben Sanitär-Code. – Craig

11

Hier ist die Antwort! Es ist eine geringfügige Änderung von Martin From's Methode und es scheint zu funktionieren. Wenn etwas fehlt, können Leute Codeänderungen im Kommentarbereich vornehmen. Vielen Dank.

Von Sie es wie folgt Controller nennen:

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

Fügen Sie diese zu einer Klasse

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

Danke dafür. Ich schaue mir an, dies etwas zu ändern, um ein bisschen besser zu sein und werde das Ergebnis veröffentlichen. – Craig

+0

Freuen Sie sich darauf, zu sehen, was Sie kommen – Jon

1

ich damit verbracht habe schon versucht, das Gleiche zu tun. Ich habe eine schnelle Lösung, die weiter ausgebaut werden muss.

HINWEIS: Ich kann ein Problem bereits sehen ..Jegliche Cookies und andere Variablen sind verloren :(

Was ich tat:

  1. neue Action erstellen

    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. Die Datenklasse

    public interface IJsonHtml 
    { 
        String HtmlContent { get; set; } 
    } 
    
    public class DefaultJsonHtml : IJsonHtml 
    { 
        public String HtmlContent { get; set; } 
    } 
    
  3. Die Controller-Erweiterungen

    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

ich eine neuere Antwort mit Razor gefunden 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

ich seit dem Versionsnummer Sie tun können, wissen don nicht hilfreich sein können dies, aber heutzutage können Sie JSON auf sehr einfache Art und Weise zurückgeben:

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

keine Notwendigkeit für aufwendige Helfer usw.

Daten sind natürlich Ihre Daten von Ihrem Modell JsonRequestBehavior gibt an, ob HTTP GET-Anfragen vom Client erlaubt sind. (source) ist optional DenyGet Standardverhalten ist, so verwendet, wenn meist JsonRequestBehavior.AllowGet und here ist, warum dies in ihm

+0

Das Problem ist nicht zurückgeben Json, sondern eine Sicht auf die Json. – Craig