ASP MVC Просмотр содержимого в формате JSON - PullRequest
17 голосов
/ 26 мая 2009

У меня есть приложение MVC с несколькими действиями контроллера, которые вызываются с помощью Ajax (jQuery) и возвращают частичное представление содержимого, которое обновляет часть экрана. Но я бы предпочел вернуть JSON примерно так.

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

Где HTML это просто свойство Json. Это означает, что мне нужно получить HTML-код, отображаемый методом View. Есть ли какой-нибудь простой способ сделать это, несколько примеров, которые я видел, довольно запутанные.

Изменить: Этот вопрос изначально был для ASP.NET MVC 1, но если версия 2 облегчает, я хотел бы услышать ответ.

Ответы [ 9 ]

11 голосов
/ 26 мая 2009

Вот ответ! Это небольшое изменение от метода Мартина От , и, похоже, оно работает. Если чего-то не хватает, пожалуйста, люди могут внести какие-либо изменения в код в разделе комментариев. Спасибо.

С вашего контроллера назовите это так:

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

Добавить это в класс

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();
}
4 голосов
/ 26 мая 2009

NerdDinner имеет несколько хороших примеров этого. Вот SearchController в NerdDinner, который имеет метод с именем SearchByLocation, который возвращает список JsonDinners ( исходный код для 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());
        }
    }
}
2 голосов
/ 29 мая 2010
1 голос
/ 18 мая 2012

Я нашел более свежий ответ, используя Razor, который может быть полезен 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;
}
1 голос
/ 06 мая 2010

Я использую HTML Helper из этой статьи: Визуализация частичного представления в строку в ASP.NET MVC . Работает отлично!

1 голос
/ 22 июня 2009

Я провел целую вечность, пытаясь сделать то же самое. У меня есть быстрое решение, которое нужно будет расширить.

ПРИМЕЧАНИЕ. Я уже вижу одну проблему. Все файлы cookie и другие переменные потеряны

Что я сделал:

  1. Создать новый 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. Класс данных

    public interface IJsonHtml
    {
        String HtmlContent { get; set; }
    }
    
    public class DefaultJsonHtml : IJsonHtml
    {
        public String HtmlContent { get; set; }
    }
    
  3. Контроллер расширения

    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
        };
    }
    
0 голосов
/ 09 апреля 2013

Я не знаю, с какого номера версии вы можете сделать это, но в настоящее время вы можете вернуть JSON очень простым способом:

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

не нужны сложные помощники и т. Д.

данные, конечно, ваши данные из вашей модели JsonRequestBehavior указывает, разрешены ли запросы HTTP GET от клиента. ( source ), необязательно DenyGet является поведением по умолчанию, поэтому, если используется в основном JsonRequestBehavior.AllowGet и здесь , то почему это там

0 голосов
/ 26 мая 2009

Craig,

Посмотрите на это. Джеффри Палермо написал SubController для ASP.NET MVC, который должен выполнять то, что вы хотите:

MvcContrib - теперь с поддержкой SubController для ASP.NET MVC: http://jeffreypalermo.com/blog/mvccontrib-now-with-subcontroller-support/

0 голосов
/ 26 мая 2009

Почему бы просто не использовать статические html "partials" и не захватывать весь динамический контент из json? Вы должны иметь возможность загружать html-файлы с помощью jquery, когда страница загружается или когда это достаточно просто.

Эта ссылка на JQuery Ajax дает следующий пример:

//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);
});
...