【问题标题】:ControllerContext and ViewData Outside Scope of Controller - MVC3 C#ControllerContext 和 ViewData 超出控制器范围 - MVC3 C#
【发布时间】:2012-02-04 22:33:04
【问题描述】:

我正在使用以下方法渲染 PartialViews/Models,以便对发送出去的电子邮件进行模板化。

我正在使用下面的代码将部分和模型转换为我可以传递给我的电子邮件发送代码的 html 字符串。

public class BaseController : Controller
{
    public string RenderPartialViewToString(string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
            throw new ArgumentException("No View Path Provided.");

        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();
        }
    }
}

目前,它存在于 BaseController 中,我想将其移出到辅助方法中,以便我也可以将构建/发送的电子邮件模型移出控制器。

问题是我无权访问 ViewData/TempData/ControllerContext

我可以新建一个 ControllerContext,但我不知道如何处理 ViewData/TempData。

这就是我目前在控制器中使用的方式:

//Do Stuff in Controller

var html = RenderPartialViewToString("~/Views/Mail/_ForgotPassword.cshtml", new MailModel { Username = "Skrillex", SomethingElse = "foo" });

//Send the Email

【问题讨论】:

  • 在视图的渲染中是否使用了 tempdata/viewdata?如果不是,为什么不传递空的?
  • 我正在使用 ViewData 设置模型。
  • 那么为什么它不是强类型视图呢?您必须使用松散视图吗?
  • "~/Views/Mail/_ForgotPassword.cshtml" 是强类型的。看来 ViewData.Model = model;正在设置模型。

标签: c# asp.net-mvc-3


【解决方案1】:

我认为你是在正确的轨道上,但问题是你急于完成分离,太急了。

您正在使用 Razor 视图引擎来呈现您的富文本 HTML 电子邮件。一种非常高尚的方法。但是,这意味着您将非常接近您的表示层并且从控制器外部运行它 - 在我看来 - 没有多大意义。

我相信您需要制作(如果尚未制作):

  • 您的电子邮件 Razor 视图为强类型
  • 让渲染像往常一样在控制器中调用
  • 渲染就像将模型传递给渲染方法一样简单
  • 将电子邮件模型的构建交给您希望的助手。这不需要任何表示层逻辑,因此完全没有注意到它。

所以关键是,渲染的调用不需要离开控制器,电子邮件模型的构建应该。

现在,如果您正在做所有这些,则意味着我没有理解您的问题,需要更多解释。

【讨论】:

  • 那么,例如,我会创建一个返回字符串的 MailController 吗?只需将 RenderToHTML 方法留在 BaseController 中,甚至将其移至 MailController 中?然后在 Account/Register 操作中,例如,当我需要发送一封成功的电子邮件时:做我的注册工作,构建邮件模型,调用 Mail/RenderRegisterEmail 操作并将它生成的字符串传递给电子邮件发件人吗?
【解决方案2】:

可以在helper类中创建BaseController的实例或者静态属性,如下图,

public sealed class Helper {
///Gets or sets BaseController
public BaseController { get; set; }
#region "Constructors"
/// <summary>
/// Initialises a new instance of the <see cref="Helper" /> class.
/// </summary>
public Helper() : base() {

}
/// <summary>
/// Initialises a new instance of the <see cref="Helper" /> class.
/// </summary>
public Helper(BaseController baseController) : this() {
   this.BaseController = baseController;
}
#endregion
public void SendEmail(){
   // Here you can call your RenderPartialViewToString from the BaseController
 var m_RenderPartialViewToString = this.BaseController.RenderPartialViewToString( .......);
}}

问候。希望这会有所帮助。

【讨论】:

    【解决方案3】:

    我使用了 2 种方法来渲染需要从控制器发送出去的电子邮件……首先我将 ControllerContext 传递给我的服务层,它按预期工作,但并不理想……我的服务通常是由命令行应用程序使用或编译到没有可用 ControllerContext 的 Windows 服务中......在我第二次尝试时,我使用了这个 Razor 渲染引擎:http://razorengine.codeplex.com/https://github.com/Antaris/RazorEngine

    【讨论】:

      猜你喜欢
      • 2014-02-08
      • 1970-01-01
      • 2022-09-27
      • 1970-01-01
      • 1970-01-01
      • 2020-06-17
      • 2022-06-14
      • 1970-01-01
      • 2012-12-24
      相关资源
      最近更新 更多