2017-11-19 19 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 
{ 
} 

ような何かをしました。
Webアプリケーションから送信するニュースレターを実行するのは良い方法ではありません。この機能をWindowsサービスに実装したいと考えています。私はそれをテストすることを容易にするためコンソールアプリケーション、ここからSendNewslettersを呼び出す。 Consolappでは、WIndowsServiceと同様に、HttpContextを持っていないので、偽のHttpContextを作成することができます。MVCルーティングにアクセスすることができます(私のカミソリビューはルーティングヘルパーを実装しています、url.action)。

+0

MVCアプリケーションで動作するQuartz.NET JobSchedulerを試すことができますか – Saineshwar

答えて

0

私はこの問題をデータベースに保存し、さらにviewrenderedの結果を解決しました。この情報はMVCアプリケーションで処理されるため、HttpContextやルーティングは必要ありません。

関連する問題