재우니의 블로그

 

ASP.NET MVC 에서 특정 VIEW 의 랜더링 값(HTML) 을 가져오는 방법에 대해 알아보죠.

 

 


샘플1


설명 : view 를 랜더링 하기 위해선, ControllerContext 가 필요하다는 점이 있습니다. 하나의 컨트롤러 안에 문자열을 view 의 razor 로 랜더링이 가능합니다.


static string RenderViewToString(ControllerContext context,
                                    string viewPath,
                                    object model = null,
                                    bool partial = false)
{
    // first find the ViewEngine for this view
    ViewEngineResult viewEngineResult = null;
    if (partial)
        viewEngineResult = ViewEngines.Engines.FindPartialView( context, viewPath);
    else
        viewEngineResult = ViewEngines.Engines.FindView(context, viewPath, null);
     
    if (viewEngineResult == null)
        throw new FileNotFoundException("View cannot be found.");
     
    // get the view and attach the model to view data
    var view = viewEngineResult.View;
    context.Controller.ViewData.Model = model;
     
    string result = null;
     
    using (var sw = new StringWriter())
    {
        var ctx = new ViewContext(context, view,
                                    context.Controller.ViewData,
                                    context.Controller.TempData,
                                    sw);
        view.Render(ctx, sw);
        result = sw.ToString();
    }
     
    return result;
}

 


샘플2


설명 :  Context 와 Controller 의 인스턴스를 생성하는 구문입니다.


public static T CreateController<T>(RouteData routeData = null)
    where T : Controller, new()
{
    // create a disconnected controller instance
    T controller = new T();
     
    // get context wrapper from HttpContext if available
    HttpContextBase wrapper;
    if (System.Web.HttpContext.Current != null)
        wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
    else
        throw new InvalidOperationException(
            "Can't create Controller Context if no "+
            "active HttpContext instance is available.");
     
    if (routeData == null)
        routeData = new RouteData();
     
    // add the controller routing if not existing
    if (!routeData.Values.ContainsKey("controller") &&
        !routeData.Values.ContainsKey("Controller"))
        routeData.Values.Add("controller",
                             controller.GetType()
                                       .Name.ToLower() .Replace("controller", ""));
     
    controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
    return controller;
}

샘플3

설명 : Http Module 에서 MVC 를 랜더링 하는 방법

public class ErrorModule : ApplicationErrorModule
{
     
   
protected override void OnDisplayError(
                              
WebErrorHandler errorHandler,
                              
ErrorViewModel model)
   
{
       
var response = HttpContext.Current.Response;
     
       
// Create an arbitrary controller instance
       
var controller =
           
ViewRenderer.CreateController<GenericController>();
           
       
string html = ViewRenderer.RenderPartialView(
                                   
"~/views/shared/Error.cshtml",
                                    model
,
                                    controller
.ControllerContext);
     
       
HttpContext.Current.Server.ClearError();
        response
.TrySkipIisCustomErrors = true;
        response
.ClearContent();
     
        response
.StatusCode = 500;
        response
.Write(html);
   
}
}
     
// *any* controller class will do for the template
public class GenericController : Controller
{ }



샘플4


설명 : Web api 를 통해 view 의 Razor 의 결과값을 전달하는 방법입니다.


public class CustomerController : ApiController
{
   
[HttpGet]
   
public HttpResponseMessage Customer(int id = 0)
   
{
       
var customer = new Customer()
       
{
           
Id = id,
           
Name = "Jimmy Roe",
           
Address = "123 Nowhere Lane\r\nAnytown, USA",
           
Email = "jroe@doeboy.com"
       
};
     
       
string accept = Request.Headers
                               
.GetValues("Accept")
                               
.FirstOrDefault();
     
       
if (!string.IsNullOrEmpty(accept) &&
            accept
.ToLower().Contains("text/html"))
       
{
           
var html = ViewRenderer
                       
.RenderView(
                             
"~/views/samples/customerapi.cshtml",
                              customer
);
           
var message=new HttpResponseMessage(HttpStatusCode.OK);
            message
.Content =new StringContent(html, Encoding.UTF8,
                                               
"text/html");
           
return message;
       
}
     
       
return Request.CreateResponse<Customer>(HttpStatusCode.OK,
                                                customer
);
   
}
     
}