eKe*_*ek0 78 asp.net asp.net-mvc webforms partial-views
我正在编程的一些网站正在使用ASP.NET MVC和WebForms.
我有局部视图,我想将其包含在webform中.部分视图有一些必须在服务器中处理的代码,因此使用Response.WriteFile不起作用.它应该与禁用javascript一起使用.
我怎样才能做到这一点?
Kei*_*ith 96
我看了一下MVC源代码,看看我是否能弄清楚如何做到这一点.控制器上下文,视图,视图数据,路由数据和html渲染方法之间似乎存在非常紧密的耦合.
基本上为了实现这一点,您需要创建所有这些额外元素.其中一些相对简单(例如视图数据)但有些更复杂 - 例如路由数据将考虑忽略当前的WebForms页面.
最大的问题似乎是HttpContext - MVC页面依赖于HttpContextBase(而不是像WebForms那样的HttpContext),虽然两者都实现了IServiceProvider,但它们并不相关.MVC的设计者故意决定不改变遗留的WebForms以使用新的上下文库,但是他们确实提供了一个包装器.
这有效,并允许您向WebForm添加局部视图:
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 );
}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的WebForm中,您可以这样做:
<% WebFormMVCUtil.RenderPartial( "ViewName", this.GetModel() ); %>
Run Code Online (Sandbox Code Playgroud)
Dan*_*iel 34
花了一段时间,但我找到了一个很好的解决方案.由于Keith解决方案适用于很多人,但在某些情况下它并不是最好的,因为有时你希望你的应用程序通过控制器的过程来渲染视图,而Keith的解决方案只是用给定的方式呈现视图model我在这里展示一个将运行正常过程的新解决方案.
一般步骤:
aspx或者master page,调用实用程序方法来渲染部分传递Controller,查看并且如果需要,要渲染的模型(作为对象),我们在这个例子中仔细检查一下
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 });
}
Run Code Online (Sandbox Code Playgroud)
创建一个用于传递参数的类,我将在这里调用RendeActionViewModel(您可以在MvcUtility类的同一文件中创建)
public class RenderActionViewModel
{
public string ControllerName { get; set; }
public string ActionName { get; set; }
public object RouteValues { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
2)现在创建一个名为的Controller DummyController
//Here the Dummy controller with Dummy view
public class DummyController : Controller
{
public ActionResult PartialRender()
{
return PartialView();
}
}
Run Code Online (Sandbox Code Playgroud)
PartialRender.cshtml为DummyController
以下内容创建一个名为(razor视图)的虚拟视图,请注意它将使用Html帮助程序执行另一个渲染操作
@model Portal.MVC.MvcUtility.RenderActionViewModel
@{Html.RenderAction(Model.ActionName, Model.ControllerName, Model.RouteValues);}
Run Code Online (Sandbox Code Playgroud)
3)现在只是把这个在您的MasterPage或aspx文件,局部呈现你想要的景色.请注意,当您有多个想要与您MasterPage或您的aspx页面混合的剃刀视图时,这是一个很好的答案.(假设我们有一个名为Login for Controller Home的PartialView
<% MyApplication.MvcUtility.RenderAction("Home", "Login", new { }); %>
Run Code Online (Sandbox Code Playgroud)
或者如果你有一个传递给Action的模型
<% MyApplication.MvcUtility.RenderAction("Home", "Login", new { Name="Daniel", Age = 30 }); %>
Run Code Online (Sandbox Code Playgroud)
这个解决方案很棒,不使用ajax调用,这不会导致嵌套视图的延迟渲染,它不会创建新的WebRequest,因此它不会为您带来新的会话,它将处理检索方法对于您想要的视图的ActionResult,它可以在不传递任何模型的情况下工作
感谢 在Webform中使用MVC RenderAction
Ale*_*ran 20
最明显的方式是通过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>
Run Code Online (Sandbox Code Playgroud)
Dr.*_*ius 10
这很好,谢谢!
我在.NET 4上使用MVC 2,这需要将TextWriter传递给ViewContext,因此您必须传入httpContextWrapper.Response.Output,如下所示.
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);
}
Run Code Online (Sandbox Code Playgroud)
这是一个类似的方法,一直在为我工作.策略是将部分视图呈现为字符串,然后在WebForm页面中输出.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
在页面代码隐藏中,你可以做到
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);
}
}
Run Code Online (Sandbox Code Playgroud)
在页面中,您可以访问呈现的内容
<%= NavigationBarContent %>
Run Code Online (Sandbox Code Playgroud)
希望有所帮助!
| 归档时间: |
|
| 查看次数: |
52099 次 |
| 最近记录: |