Получение частичного просмотра HTML изнутри контроллера
Я разработал простой механизм для моего веб-сайта mvc, чтобы вытащить html через jquery, который затем заполняет указанный div. Все хорошо, и это выглядит круто.
Моя проблема заключается в том, что я теперь создаю html-разметку внутри моего контроллера (что очень легко сделать в VB.net btw). Я бы предпочел не смешивать разделение проблем.
Возможно ли использовать пользовательский "MVC View User Control" для удовлетворения этой потребности? Могу ли я создать экземпляр элемента управления, передать данные модели и отобразить в html? Тогда было бы просто сделать рендеринг и передать обратно вызывающему браузеру.
Ответы
Ответ 1
У вас есть несколько вариантов.
Создайте MVC View User Control и обработчик действий в вашем контроллере для представления. Для отображения вида используйте
<% Html.RenderPartial("MyControl") %>
В этом случае ваш обработчик действий должен будет передать данные модели в представление
public ActionResult MyControl ()
{
// get modelData
render View (modelData);
}
Другой вариант - передать данные модели с родительской страницы. В этом случае вам не нужен обработчик действий, а тип модели совпадает с родительским:
<% Html.RenderPartial("MyControl", ViewData.Model) %>
Если ваш пользовательский элемент управления имеет собственный тип данных, вы также можете его создать на странице
В MyControl.ascx.cs:
public class MyControlViewData
{
public string Name { get; set; }
public string Email { get; set; }
}
public partial class MyControl : System.Web.Mvc.ViewUserControl <MyControlViewData>
{
}
И на вашей странице вы можете инициализировать свою модель данных управления:
<% Html.RenderPartial("MyControl", new MyControlViewData ()
{
Name= ViewData.Model.FirstName,
Email = ViewData.Model.Email,
});
%>
Ответ 2
Это решение, которое работает с ASP.Net MVC 1.0 (многие из тех, кто утверждает, что работают с бета-версией 3, не работают с 1.0), не страдает от того, что "Сервер не может установить тип контента после того, как заголовки HTTP были послал 'и может быть вызван из контроллера (а не только для представления):
/// <summary>
/// Render a view into a string. It a hack, it may fail badly.
/// </summary>
/// <param name="name">Name of the view, that is, its path.</param>
/// <param name="data">Data to pass to the view, a model or something like that.</param>
/// <returns>A string with the (HTML of) view.</returns>
public static string RenderPartialToString(string controlName, object viewData) {
ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() };
viewPage.Url = GetBogusUrlHelper();
viewPage.ViewData = new ViewDataDictionary(viewData);
viewPage.Controls.Add(viewPage.LoadControl(controlName));
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb)) {
using (HtmlTextWriter tw = new HtmlTextWriter(sw)) {
viewPage.RenderControl(tw);
}
}
return sb.ToString();
}
public static UrlHelper GetBogusUrlHelper() {
var httpContext = HttpContext.Current;
if (httpContext == null) {
var request = new HttpRequest("/", Config.Url.ToString(), "");
var response = new HttpResponse(new StringWriter());
httpContext = new HttpContext(request, response);
}
var httpContextBase = new HttpContextWrapper(httpContext);
var routeData = new RouteData();
var requestContext = new RequestContext(httpContextBase, routeData);
return new UrlHelper(requestContext);
}
Это статический метод, который вы можете отбросить где-нибудь, когда найдете его удобным. Вы можете называть это следующим образом:
string view = RenderPartialToString("~/Views/Controller/AView.ascx", someModelObject);
Ответ 3
Я собрал грубую структуру, которая позволяет визуализировать представления строки из метода контроллера в бета-версии MVC. Это должно помочь решить это ограничение на данный момент.
Кроме того, я также собрал Rails-структуру RJS javascript для создания бета-версии MVC.
Посмотрите на http://www.brightmix.com/blog/how-to-renderpartial-to-string-in-asp-net-mvc и сообщите мне, что вы думаете.
Ответ 4
Вы создали бы свое действие следующим образом:
public PartialViewResult LoginForm()
{
var model = // get model data from somewhere
return PartialView(model);
}
И действие вернет обработанное частичное представление вашему ответу jquery.
Ваш jquery может выглядеть примерно так:
$('#targetdiv').load('/MyController/LoginForm',function(){alert('complete!');});
Ответ 5
Вы должны использовать jquery для заполнения ваших div (и при необходимости создавать новые html-элементы) и сериализации Json для ActionResult.
Другой способ - использовать jquery для вызова некоторого контроллера/действия, но вместо этого json использует обычный View (aspx или ascx, механизм просмотра веб-форм) для рендеринга контента, а с jquery просто вставляйте этот html в какой-либо div. Это половина пути к UpdatePanels от asp.net ajax...
Я бы, вероятно, пошел с первым методом, с json, где у вас еще немного работы, но он намного более "оптимизирован", потому что вы не переносите весь html поверх проводов, есть только сериализованные объекты. Это так, как это делают "большие" (gmail, g docs, hotmail,..) - много JS-кода, который манипулирует с пользовательским интерфейсом.
Если вам не нужен ajax, у вас в основном есть два способа вызова частичных представлений:
- html.renderpartial( "имя ascx" )
- html.RenderAction(x = > x.ActionName) из Microsoft.web.mvc(фьючерсы mvc)
Ответ 6
После долгих поисков в google я нашел ответ.
Вы не можете получить легкий доступ к html, выводимому представлением.
http://ayende.com/Blog/archive/2008/11/11/another-asp.net-mvc-bug-rendering-views-to-different-output-source.aspx
Ответ 7
Я сделал что-то подобное для приложения, над которым я работаю. У меня есть частичные представления, возвращаемые отображаемым контентом, которые можно вызвать, используя их путь REST или используя:
<% Html.RenderAction("Action", "Controller"); %>
Затем в моем фактическом отображении HTML у меня есть DIV, который заполняется из jQuery:
<div class="onload">/controller/action</div>
jQuery выглядит так:
<script type="text/javascript">
$.ajaxSetup({ cache: false });
$(document).ready(function () {
$('div.onload').each(function () {
var source = $(this).html();
if (source != "") {
$(this).load(source);
}
});
});
</script>
Это сканирование всех DIV, которые соответствуют классу "onload", и считывает путь REST из их содержимого. Затем он выполняет jQuery.load на этом пути REST и заполняет DIV результатом.
Извините, пойди, поймай мою поездку домой. Дайте мне знать, если вы хотите, чтобы я уточнил больше.
Ответ 8
В рельсах это называется рендерингом частичного представления, и вы делаете это с помощью render :partial => 'yourfilename'
. Я считаю, что ASP.NET MVC имеет аналогичный метод RenderPartial
, но я не могу найти официальные документы для MVC, чтобы подтвердить или опровергнуть такую вещь.
Ответ 9
очень просто вам просто нужно создать строго типизированный частичный вид (или пользовательский контроль), а затем в вашем контролере что-то вроде этого:
public PartialViewResult yourpartialviewresult()
{
var yourModel
return PartialView("yourPartialView", yourModel);
}
то вы можете использовать JQuery для выполнения запроса, когда вы хотите:
$.ajax({
type: 'GET',
url: '/home/yourpartialviewresult',
dataType: 'html', //be sure to use html dataType
contentType: 'application/json; charset=utf-8',
success: function(data){
$(container).html(data);
},
complete: function(){ }
});
Ответ 10
Я нашел, что этот один строковый код работает отлично. orderModel - мой модельный объект. В моем случае у меня был вспомогательный метод, в котором мне пришлось объединить частичный вид html.
System.Web.Mvc.Html.PartialExtensions.Partial(html, "~/Views/Orders/OrdersPartialView.cshtml", orderModel).ToString();