ASP.NET MVC Razor : 컨트롤러 작업 내에서 Razor 부분보기의 HTML을 렌더링하는 방법
ASP.NET보기 엔진에서 지정된 부분보기의 HTML을 생성하는 방법 은 알려져 있습니다.
그러나이 기능이 면도기 부분보기에서 사용되면 부분보기가 "UserControl"에서 파생되지 않는다는 예외가 있기 때문에 작동하지 않습니다.
Razor 부분보기를 지원하도록 렌더링을 수정하는 방법은 무엇입니까?
이 부분보기에서 이메일을 생성하기 때문에 이것이 필요합니다 ...
최신 정보:
실패한 코드 (@mcl) :
public string RenderPartialToString(string controlName, object viewData)
{
ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() };
viewPage.Url = this.GetUrlHelper();
string fullControlName = "~/Views/Email/" + controlName + ".ascx";
viewPage.ViewData = new ViewDataDictionary(viewData);
viewPage.Controls.Add(viewPage.LoadControl(fullControlName));
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
using (HtmlTextWriter tw = new HtmlTextWriter(sw))
{
viewPage.RenderControl(tw);
}
}
return sb.ToString();
}
@Html.Partial("nameOfPartial", Model)
최신 정보
protected string RenderPartialViewToString(string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString("action");
ViewData.Model = model;
using (StringWriter sw = new StringWriter()) {
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
적절한 답변이 이미 주어졌지만 MVC 컨트롤러 클래스에서 사용할 수있는 도우미 메서드없이 사용할 수있는 덜 장황한 솔루션을 제안하고 싶습니다. "RazorEngine"이라는 타사 라이브러리를 사용하면 .Net 파일 IO를 사용하여 razor 파일의 내용을 가져오고 호출 할 수 있습니다.
string html = Razor.Parse(razorViewContentString, modelObject);
Get the third party library here.
You could also use the RenderView Controller extension
from here (source)
and use it like this:
public ActionResult Do() {
var html = this.RenderView("index", theModel);
...
}
it works for razor and web-forms viewengines
I saw that someone was wondering how to do it for another controller.
In my case I had all of my email templates in the Views/Email folder, but you could modify this to pass in the controller in which you have views associated for.
public static string RenderViewToString(Controller controller, string viewName, object model)
{
var oldController = controller.RouteData.Values["controller"].ToString();
if (controller.GetType() != typeof(EmailController))
controller.RouteData.Values["controller"] = "Email";
var oldModel = controller.ViewData.Model;
controller.ViewData.Model = model;
try
{
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindView(controller.ControllerContext, viewName,
null);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
//Cleanup
controller.ViewData.Model = oldModel;
controller.RouteData.Values["controller"] = oldController;
return sw.GetStringBuilder().ToString();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
throw ex;
}
}
Essentially what this does is take a controller, such as AccountController and modify it to think it's an EmailController so that the code will look in the Views/Email
folder. It's necessary to do this because the FindView
method doesn't take a straight up path as a parameter, it wants a ControllerContext
.
Once done rendering the string, it returns the AccountController back to its initial state to be used by the Response object.
great code; little hint: if you sometimes have to bypass more data and not only the viewmodel ..
if (model is ViewDataDictionary)
{
controller.ViewData = model as ViewDataDictionary;
} else {
controller.ViewData.Model = model;
}
Borrowing @jgauffin answer as an HtmlHelper extension:
public static class HtmlHelperExtensions
{
public static MvcHtmlString RenderPartialViewToString(
this HtmlHelper html,
ControllerContext controllerContext,
ViewDataDictionary viewData,
TempDataDictionary tempData,
string viewName,
object model)
{
viewData.Model = model;
string result = String.Empty;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controllerContext, viewName);
ViewContext viewContext = new ViewContext(controllerContext, viewResult.View, viewData, tempData, sw);
viewResult.View.Render(viewContext, sw);
result = sw.GetStringBuilder().ToString();
}
return MvcHtmlString.Create(result);
}
}
Usage in a razor view:
Html.RenderPartialViewToString(ViewContext, ViewData, TempData, "Search", Model)
'programing tip' 카테고리의 다른 글
Eclipse의 유효성 검사에서 특정 폴더 또는 파일을 제외하는 방법은 무엇입니까? (0) | 2020.08.22 |
---|---|
화면을지나 아래로 스크롤하면 div가 화면 상단에 달라 붙게 함 (0) | 2020.08.22 |
자바 스크립트에서 배열의 최대 크기 (0) | 2020.08.22 |
'인스턴스로 전송 된 인식 할 수없는 선택기'오류를 디버그하려면 어떻게해야합니까? (0) | 2020.08.22 |
Angular2 오류 : "exportAs"가 "ngForm"으로 설정된 지시문이 없습니다. (0) | 2020.08.22 |