Как включить частичное представление внутри веб-формы
какой-то сайт, который я программирую, использует оба ASP.NET MVC и WebForms.
У меня есть частичный вид, и я хочу включить это в форму. Частичное представление имеет некоторый код, который должен быть обработан на сервере, поэтому с помощью ответа.WriteFile не работает.
Он должен работать с отключенным javascript.
Как я могу это сделать?
6 ответов:
Я посмотрел на источник MVC, чтобы узнать, могу ли я понять, как это сделать. Кажется, что существует очень тесная связь между контекстом контроллера, представлениями, данными представления, данными маршрутизации и методами рендеринга html.
в основном для того, чтобы это произошло, нужно создать все эти дополнительные элементы. Некоторые из них относительно просты (например, данные представления), но некоторые немного сложнее - например, данные маршрутизации будут считать текущую страницу WebForms игнорируемый.
большая проблема, по - видимому, заключается в том, что страницы HttpContext-MVC полагаются на HttpContextBase (а не HttpContext, как это делают веб-формы), и хотя оба реализуют IServiceProvider, они не связаны. Дизайнеры MVC приняли сознательное решение не изменять устаревшие веб-формы для использования новой контекстной базы, однако они предоставили оболочку.
это работает и позволяет добавить частичное представление в форме:
public class WebFormController : Controller { } public static class WebFormMVCUtil { public static void RenderPartial( string partialName, object model ) { //get a wrapper for the legacy WebForm context var httpCtx = new HttpContextWrapper( System.Web.HttpContext.Current ); //create a mock route that points to the empty controller var rt = new RouteData(); rt.Values.Add( "controller", "WebFormController" ); //create a controller context for the route and http context var ctx = new ControllerContext( new RequestContext( httpCtx, rt ), new WebFormController() ); //find the partial view using the viewengine var view = ViewEngines.Engines.FindPartialView( ctx, partialName ).View; //create a view context and assign the model var vctx = new ViewContext( ctx, view, new ViewDataDictionary { Model = model }, new TempDataDictionary() ); //render the partial view view.Render( vctx, System.Web.HttpContext.Current.Response.Output ); } }тогда в вашей форме вы можете сделать это:
<% WebFormMVCUtil.RenderPartial( "ViewName", this.GetModel() ); %>
это заняло некоторое время, но Iv нашел отличное решение. Как Кит решение работает для многих людей, но в некоторых ситуациях это не самое лучшее, потому что иногда вы хотите, чтобы ваше приложение пройдите через процесс контроллера для отображения, и решение кита просто визуализирует представление с заданной моделью я представляю здесь новое решение, которое будет запускать нормальный процесс.
Действия:
- создать служебный класс
- создать фиктивный контроллер с фиктивным видом
- в своем
aspxилиmaster page, вызовите метод утилиты для рендеринга частичной передачи контроллера, просмотра и, если вам нужно, модели для рендеринга (как объекта),давайте проверим его внимательно в этом примере
1) Создайте класс с именем
MVCUtilityи создать следующие методы://Render a partial view, like Keith's solution private static void RenderPartial(string partialViewName, object model) { HttpContextBase httpContextBase = new HttpContextWrapper(HttpContext.Current); RouteData routeData = new RouteData(); routeData.Values.Add("controller", "Dummy"); ControllerContext controllerContext = new ControllerContext(new RequestContext(httpContextBase, routeData), new DummyController()); IView view = FindPartialView(controllerContext, partialViewName); ViewContext viewContext = new ViewContext(controllerContext, view, new ViewDataDictionary { Model = model }, new TempDataDictionary(), httpContextBase.Response.Output); view.Render(viewContext, httpContextBase.Response.Output); } //Find the view, if not throw an exception private static IView FindPartialView(ControllerContext controllerContext, string partialViewName) { ViewEngineResult result = ViewEngines.Engines.FindPartialView(controllerContext, partialViewName); if (result.View != null) { return result.View; } StringBuilder locationsText = new StringBuilder(); foreach (string location in result.SearchedLocations) { locationsText.AppendLine(); locationsText.Append(location); } throw new InvalidOperationException(String.Format("Partial view {0} not found. Locations Searched: {1}", partialViewName, locationsText)); } //Here the method that will be called from MasterPage or Aspx public static void RenderAction(string controllerName, string actionName, object routeValues) { RenderPartial("PartialRender", new RenderActionViewModel() { ControllerName = controllerName, ActionName = actionName, RouteValues = routeValues }); }создать класс для передачи параметров, я позвоню RendeActionViewModel (можно создать в том же файле класса MvcUtility)
public class RenderActionViewModel { public string ControllerName { get; set; } public string ActionName { get; set; } public object RouteValues { get; set; } }2) Теперь создайте контроллер с именем
DummyController//Here the Dummy controller with Dummy view public class DummyController : Controller { public ActionResult PartialRender() { return PartialView(); } }создать фиктивный вид под названием
PartialRender.cshtml(вид бритвы) дляDummyControllerпри следующем содержании обратите внимание, что он выполнит другое действие рендеринга с помощью помощника Html@model Portal.MVC.MvcUtility.RenderActionViewModel @{Html.RenderAction(Model.ActionName, Model.ControllerName, Model.RouteValues);}3) Теперь просто поместите это в ваш
MasterPageилиaspxфайл, чтобы частично отобразить представление, которое вы хотите. Обратите внимание, что это отличный ответьте, когда у вас есть несколько представлений бритвы, которые вы хотите смешать с вашимMasterPageилиaspxстраницы. (предполагая, что у нас есть PartialView называется Login для контроллера Home<% MyApplication.MvcUtility.RenderAction("Home", "Login", new { }); %>или если у вас есть модель для перехода в действие
<% MyApplication.MvcUtility.RenderAction("Home", "Login", new { Name="Daniel", Age = 30 }); %>это отличное решение,не использует ajax call, что не вызовет отложенная отрисовка для вложенных представлений, это doenst сделать новый WebRequest так будет не приносите вам новую сессию, и обработает метод для получения ActionResult для просмотра вы хотите, он работает без передачи любой модели
наиболее очевидным способом было бы через AJAX
что-то вроде этого (с использованием jQuery)
<div id="mvcpartial"></div> <script type="text/javascript"> $(document).load(function () { $.ajax( { type: "GET", url : "urltoyourmvcaction", success : function (msg) { $("#mvcpartial").html(msg); } }); }); </script>
Это здорово, спасибо!
Я использую MVC 2 на .NET 4, который требует TextWriter передается в ViewContext, поэтому вы должны передать в httpContextWrapper.Ответ.Вывод, как показано ниже.
public static void RenderPartial(String partialName, Object model) { // get a wrapper for the legacy WebForm context var httpContextWrapper = new HttpContextWrapper(HttpContext.Current); // create a mock route that points to the empty controller var routeData = new RouteData(); routeData.Values.Add(_controller, _webFormController); // create a controller context for the route and http context var controllerContext = new ControllerContext(new RequestContext(httpContextWrapper, routeData), new WebFormController()); // find the partial view using the viewengine var view = ViewEngines.Engines.FindPartialView(controllerContext, partialName).View as WebFormView; // create a view context and assign the model var viewContext = new ViewContext(controllerContext, view, new ViewDataDictionary { Model = model }, new TempDataDictionary(), httpContextWrapper.Response.Output); // render the partial view view.Render(viewContext, httpContextWrapper.Response.Output); }
вот подобный подход, который работает для меня. Стратегия состоит в том, чтобы отобразить частичное представление в строку, а затем вывести его на странице веб-формы.
public class TemplateHelper { /// <summary> /// Render a Partial View (MVC User Control, .ascx) to a string using the given ViewData. /// http://www.joeyb.org/blog/2010/01/23/aspnet-mvc-2-render-template-to-string /// </summary> /// <param name="controlName"></param> /// <param name="viewData"></param> /// <returns></returns> public static string RenderPartialToString(string controlName, object viewData) { ViewDataDictionary vd = new ViewDataDictionary(viewData); ViewPage vp = new ViewPage { ViewData = vd}; 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(); } }на странице codebehind, вы можете сделать
public partial class TestPartial : System.Web.UI.Page { public string NavigationBarContent { get; set; } protected void Page_Load(object sender, EventArgs e) { NavigationVM oVM = new NavigationVM(); NavigationBarContent = TemplateHelper.RenderPartialToString("~/Views/Shared/NavigationBar.ascx", oVM); } }и на странице вы будете иметь доступ к отображаемому контенту
<%= NavigationBarContent %>надеюсь, что это поможет!
это решение принимает другой подход. Он определяет
System.Web.UI.UserControlкоторый можно разместить в любой веб-форме и настроить для отображения содержимого с любого URL-адреса...включая частичное представление MVC. Этот подход аналогичен вызову AJAX для HTML в том, что параметры (если таковые имеются) задаются через строку запроса URL.сначала определите пользовательский элемент управления в 2 файлах:
/ controls / PartialViewControl.ascx и файл
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="PartialViewControl.ascx.cs" Inherits="PartialViewControl" %>/ controls / PartialViewControl.ascx вносятся.cs:
public partial class PartialViewControl : System.Web.UI.UserControl { [Browsable(true), Category("Configutation"), Description("Specifies an absolute or relative path to the content to display.")] public string contentUrl { get; set; } protected override void Render(HtmlTextWriter writer) { string requestPath = (contentUrl.StartsWith("http") ? contentUrl : "http://" + Request.Url.DnsSafeHost + Page.ResolveUrl(contentUrl)); WebRequest request = WebRequest.Create(requestPath); WebResponse response = request.GetResponse(); Stream responseStream = response.GetResponseStream(); var responseStreamReader = new StreamReader(responseStream); var buffer = new char[32768]; int read; while ((read = responseStreamReader.Read(buffer, 0, buffer.Length)) > 0) { writer.Write(buffer, 0, read); } } }затем добавьте пользовательский элемент управления на страницу веб-формы:
<%@ Page Language="C#" %> <%@ Register Src="~/controls/PartialViewControl.ascx" TagPrefix="mcs" TagName="PartialViewControl" %> <h1>My MVC Partial View</h1> <p>Below is the content from by MVC partial view (or any other URL).</p> <mcs:PartialViewControl runat="server" contentUrl="/MyMVCView/" />
Comments