웹 양식 내부에 부분 보기를 포함하는 방법
프로그래밍 중인 일부 사이트에서 ASP.NET MVC와 웹 양식을 모두 사용하고 있습니다.
나는 부분적인 견해를 가지고 있으며 이것을 웹 양식에 포함시키고 싶습니다.부분 보기에는 서버에서 처리해야 하는 코드가 있으므로 응답을 사용합니다.쓰기 파일이 작동하지 않습니다.자바스크립트가 비활성화된 상태에서 작동해야 합니다.
어떻게 해야 하나요?
MVC 소스를 보고 어떻게 하면 좋을지 알아봤습니다.컨트롤러 컨텍스트, 뷰, 뷰 데이터, 라우팅 데이터 및 html 렌더링 방법 사이에는 매우 밀접한 결합이 있는 것으로 보입니다.
기본적으로 이를 실현하기 위해서는 이러한 추가 요소를 모두 생성해야 합니다.일부는 보기 데이터와 같이 비교적 단순하지만 일부는 약간 더 복잡합니다. 예를 들어 라우팅 데이터는 현재 웹 양식 페이지를 무시합니다.
큰 문제는 HttpContext인 것 같습니다. MVC 페이지는 (WebForms와 같은 HttpContext가 아닌) HttpContextBase에 의존하며 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() ); %>
시간이 좀 걸렸지만, 저는 훌륭한 해결책을 찾았습니다.Keith의 솔루션은 많은 사람들에게 효과가 있지만, 특정 상황에서는 최선이 아닙니다. 애플리케이션이 보기를 렌더링하는 컨트롤러 프로세스를 거치길 원할 때가 있기 때문입니다. Keith의 솔루션은 주어진 모델을 사용하여 보기를 렌더링합니다. 제가 여기서의 모델로 보기를 렌더링하기 때문입니다.
일반 단계:
- 유틸리티 클래스 만들기
- 더미 뷰가 있는 더미 컨트롤러 만들기
- 의 신의에서.
aspx
또는master page
모델(을 확인합니다.
이 예에서 자세히 확인해 보겠습니다.
.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; }
}
이제 이름이 지정된 컨트롤러를 만듭니다.DummyController
//Here the Dummy controller with Dummy view
public class DummyController : Controller
{
public ActionResult PartialRender()
{
return PartialView();
}
}
Dummy라는 .PartialRender.cshtml
된 보기) 에 (표시된 보기)DummyController
다음 내용을 사용하여 Html 도우미를 사용하여 다른 렌더 작업을 수행합니다.
@model Portal.MVC.MvcUtility.RenderActionViewModel
@{Html.RenderAction(Model.ActionName, Model.ControllerName, Model.RouteValues);}
이제 이것을 당신의 안에 넣으세요.MasterPage
또는aspx
파일: 원하는 보기를 부분 렌더링합니다.이 방법은 여러 면도기 뷰를 사용할 때 유용합니다.MasterPage
또는aspx
페이지. (컨트롤러 홈에 대한 로그인이라는 부분 보기가 있다고 가정합니다.
<% MyApplication.MvcUtility.RenderAction("Home", "Login", new { }); %>
또는 Action에 전달하기 위한 모델이 있는 경우
<% MyApplication.MvcUtility.RenderAction("Home", "Login", new { Name="Daniel", Age = 30 }); %>
이 솔루션은 훌륭하며, Ajax 호출을 사용하지 않으므로 중첩된 보기에 대해 지연된 렌더를 발생시키지 않습니다. 새 WebRequest를 만들지 않으므로 새 세션을 가져오지 않습니다. 원하는 보기에 대한 ActionResult를 검색하는 방법을 처리합니다. 모델을 통과하지 않고 작동합니다.
덕분에. 웹 양식에서 MVC 렌더 액션 사용
가장 확실한 방법은 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>
정말 잘됐네요, 감사합니다!
.NET 4에서 MVC 2를 사용하고 있습니다. 이 경우 텍스트 작성기가 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();
}
}
뒤에 있는 페이지 코드에서, 당신은 할 수 있습니다.
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
모든 웹 양식에 배치할 수 있으며 MVC 부분 보기를 포함하여 모든 URL에서 콘텐츠를 표시하도록 구성할 수 있습니다.이 접근 방식은 URL 쿼리 문자열을 통해 매개 변수(있는 경우)가 제공된다는 점에서 HTML에 대한 AJAX 호출과 유사합니다.
먼저 두 개의 파일에 사용자 컨트롤을 정의합니다.
/controls/PartialViewControl.ascx 파일
<%@ Control Language="C#"
AutoEventWireup="true"
CodeFile="PartialViewControl.ascx.cs"
Inherits="PartialViewControl" %>
/http/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/" />
FWIW, 기존 웹폼 코드에서 부분 뷰를 동적으로 렌더링하고 지정된 컨트롤의 맨 위에 삽입할 수 있어야 했습니다.나는 키스의 대답이 부분적인 견해가 외부로 렌더링될 수 있다는 것을 발견했습니다.<html />
꼬리표를 달다
HttpContext로 직접 렌더링하는 대신 Keith와 Hilahrius의 답변을 영감에 사용합니다.현재의.대답.출력, HTML 문자열을 렌더링하여 관련 컨트롤에 리터럴 컨트롤로 추가했습니다.
정적 도우미 클래스:
public static string RenderPartial(string partialName, object model)
{
//get a wrapper for the legacy WebForm context
var httpCtx = new HttpContextWrapper(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(), new StringWriter());
// This will render the partial view direct to the output, but be careful as it may end up outside of the <html /> tag
//view.Render(vctx, HttpContext.Current.Response.Output);
// Better to render like this and create a literal control to add to the parent
var html = new StringWriter();
view.Render(vctx, html);
return html.GetStringBuilder().ToString();
}
호출 클래스:
internal void AddPartialViewToControl(HtmlGenericControl ctrl, int? insertAt = null, object model)
{
var lit = new LiteralControl { Text = MvcHelper.RenderPartial("~/Views/Shared/_MySharedView.cshtml", model};
if (insertAt == null)
{
ctrl.Controls.Add(lit);
return;
}
ctrl.Controls.AddAt(insertAt.Value, lit);
}
언급URL : https://stackoverflow.com/questions/702746/how-to-include-a-partial-view-inside-a-webform
'programing' 카테고리의 다른 글
python에서 인수 목록이 있는 함수 호출 (0) | 2023.06.16 |
---|---|
의 크기와 문자의 혼동스러운 동작 (0) | 2023.06.16 |
웹팩 4 모듈을 자스민이 멤버를 감시할 수 있도록 구성할 수 있습니까? (0) | 2023.06.11 |
JDBC 씬 드라이버에 대한 NLS_LANG 설정? (0) | 2023.06.11 |
파이썬으로 단어가 영어 단어인지 확인하는 방법은 무엇입니까? (0) | 2023.06.11 |