2017-11-19 2 views
0

MVC 5 프로젝트에 가입 된 모든 사용자에게 생성 된 메일을 보내도록 뉴스 레터 기능을 추가했습니다.
나는 public async Task<NewsletterLogResult> SendNewsletters(int? id = null, ControllerContext ControllerContext = null)와 클래스가 public async Task<ActionResult>SendMail(int id)
SendNewslettersViewrenderer 구현하는 액션에서 호출되는이 MVC에서 완벽하게 작동되는이 cBody = ViewRenderer.RenderPartialView(ViewRenderer.TemplatePath + "Newsletters/" + record.Newsletter_Template + "Body.cshtml", record, ControllerContext);.NET 콘솔 응용 프로그램에서 MVC ViewRenderer 구현

public class ViewRenderer 
{ 
    protected ControllerContext Context { get; set; } 

    public const string TemplatePath = "~/Views/Templates/"; 

    public ViewRenderer(ControllerContext controllerContext = null) 
    { 
     // Create a known controller from HttpContext if no context is passed 
     if (controllerContext == null) 
     { 
      if (HttpContext.Current != null) 
       controllerContext = CreateController<EmptyController>().ControllerContext; 
      else 
       throw new InvalidOperationException(
        "ViewRenderer must run in the context of an ASP.NET Application and requires HttpContext.Current to be present."); 
     } 
     Context = controllerContext; 
    } 

    public string RenderViewToString(string viewPath, object model = null) 
    { 
     return RenderViewToStringInternal(viewPath, model, false); 
    } 

    public void RenderView(string viewPath, object model, TextWriter writer) 
    { 
     RenderViewToWriterInternal(viewPath, writer, model, false); 
    } 

    public string RenderPartialViewToString(string viewPath, object model = null) 
    { 
     return RenderViewToStringInternal(viewPath, model, true); 
    } 

    public void RenderPartialView(string viewPath, object model, TextWriter writer) 
    { 
     RenderViewToWriterInternal(viewPath, writer, model, true); 
    } 

    public static string RenderView(string viewPath, object model = null, 
            ControllerContext controllerContext = null) 
    { 
     ViewRenderer renderer = new ViewRenderer(controllerContext); 
     return renderer.RenderViewToString(viewPath, model); 
    } 

    public static void RenderView(string viewPath, TextWriter writer, object model, 
            ControllerContext controllerContext) 
    { 
     ViewRenderer renderer = new ViewRenderer(controllerContext); 
     renderer.RenderView(viewPath, model, writer); 
    } 

    public static string RenderView(string viewPath, object model, 
            ControllerContext controllerContext, 
            out string errorMessage) 
    { 
     errorMessage = null; 
     try 
     { 
      ViewRenderer renderer = new ViewRenderer(controllerContext); 
      return renderer.RenderViewToString(viewPath, model); 
     } 
     catch (Exception ex) 
     { 
      errorMessage = ex.GetBaseException().Message; 
     } 
     return null; 
    } 

    public static void RenderView(string viewPath, object model, TextWriter writer, 
            ControllerContext controllerContext, 
            out string errorMessage) 
    { 
     errorMessage = null; 
     try 
     { 
      ViewRenderer renderer = new ViewRenderer(controllerContext); 
      renderer.RenderView(viewPath, model, writer); 
     } 
     catch (Exception ex) 
     { 
      errorMessage = ex.GetBaseException().Message; 
     } 
    } 

    public static string RenderPartialView(string viewPath, object model = null, 
              ControllerContext controllerContext = null) 
    { 
     ViewRenderer renderer = new ViewRenderer(controllerContext); 
     return renderer.RenderPartialViewToString(viewPath, model); 
    } 

    public static void RenderPartialView(string viewPath, TextWriter writer, object model = null, 
              ControllerContext controllerContext = null) 
    { 
     ViewRenderer renderer = new ViewRenderer(controllerContext); 
     renderer.RenderPartialView(viewPath, model, writer); 
    } 

    protected void RenderViewToWriterInternal(string viewPath, TextWriter writer, 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(); 

     // get the view and attach the model to view data 
     var view = viewEngineResult.View; 
     Context.Controller.ViewData.Model = model; 

     var ctx = new ViewContext(Context, view, 
            Context.Controller.ViewData, 
            Context.Controller.TempData, 
            writer); 
     view.Render(ctx, writer); 
    } 

    private string RenderViewToStringInternal(string viewPath, object model, 
               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 || viewEngineResult.View == null) 
     { 
      //throw new FileNotFoundException(Resources.ViewCouldNotBeFound); 
      throw new Exception("Can't find view."); 
     } 

     // 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; 
    } 

    public static T CreateController<T>(RouteData routeData = null, params object[] parameters) 
       where T : Controller, new() 
    { 
     // create a disconnected controller instance 
     T controller = (T)Activator.CreateInstance(typeof(T), parameters); 

     // get context wrapper from HttpContext if available 
     HttpContextBase wrapper = null; 
     if (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; 
    } 

} 

public class EmptyController : Controller 
{ 
} 

뭔가를했습니다.
웹 응용 프로그램에서 보내는 보내는 뉴스 레터를 실행하는 것이 좋지 않지만 Windows 서비스에서이 기능을 구현하고 싶습니다. 용이하게하기 위해 나는 콘솔 앱에서 전화를 걸어 여기 SendNewsletters에서 테스트하고 있습니다. Consolapp에서는 WIndowsService와 마찬가지로 HttpContext이 없으므로 가짜 HttpContext를 만들 수 있습니다. MVC 라우팅에 액세스 할 수있는 것이 좋습니다 (내 면도기 뷰는 라우팅 도우미를 구현합니다 (url.action)?).

+0

MVC 응용 프로그램에서 작동하는 Quartz.NET JobScheduler를 사용해 볼 수 있습니까? – Saineshwar

답변

0

데이터베이스에 저장하는이 문제를 해결하고 뷰 렌더링 결과도 해결했습니다. 이 정보는 MVC 응용 프로그램에서 처리되므로 HttpContext 또는 모든 라우팅이 필요하지 않습니다.

관련 문제