ASP MVC Просмотр в виде JSON
У меня есть приложение 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 упрощает, я бы хотел услышать ответ.
Ответы
Ответ 1
Вот ответ! Это небольшое изменение от метода Martin From и, похоже, это работает. Если есть недостающие вещи, можете ли люди вносить какие-либо изменения в код в разделе комментариев. Спасибо.
С вашего контроллера вызывается так:
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();
}
Ответ 2
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());
}
}
}
Ответ 3
Это хорошее решение проблемы:
http://craftycode.wordpress.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/
Ответ 4
Я потратил века, пытаясь сделать то же самое. У меня есть быстрое решение, которое нужно будет продолжить.
ПРИМЕЧАНИЕ. Я вижу уже одну проблему. Любые файлы cookie и другие переменные теряются: (
Что я сделал:
-
Создать новый 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));
}
}
-
Класс Datap >
public interface IJsonHtml
{
String HtmlContent { get; set; }
}
public class DefaultJsonHtml : IJsonHtml
{
public String HtmlContent { get; set; }
}
-
Расширения контроллера
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
};
}
Ответ 5
Я использую HTML-помощник из этой статьи: Отказывать частичное представление строки в ASP.NET MVC. Он отлично работает!
Ответ 6
Я нашел более свежий ответ с помощью 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;
}
Ответ 7
Почему бы не просто статические html-частичные части и захватить все динамическое содержимое из 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);
});
Ответ 8
Craig,
Посмотрите на это. Джеффри Палермо написал SubController для ASP.NET MVC, который должен выполнить то, что вы хотите:
MvcContrib - теперь с поддержкой SubController для ASP.NET MVC:
http://jeffreypalermo.com/blog/mvccontrib-now-with-subcontroller-support/
Ответ 9
Я не знаю, с какого номера версии вы можете это сделать, но в настоящее время вы можете вернуть JSON очень простым способом:
public ActionResult JSONaction()
{
return Json(data, JsonRequestBehavior);
}
нет необходимости в сложных помощниках и т.д.
данные, конечно, ваши данные из вашей модели
JsonRequestBehavior указывает, разрешены ли запросы HTTP GET от клиента. (источник), необязательно DenyGet
является поведением по умолчанию, поэтому, если используется в основном JsonRequestBehavior.AllowGet
и здесь, почему это там