在ASP.NET MVC控制器中,我可以通过在不同的控制器上调用操作来获取视图结果

时间:2010-10-26 12:18:13

标签: asp.net-mvc controller

我试图简单地新建一个不同的控制器,然后调用action方法。返回值的类型为ViewResult,并且已创建模型,但View为null。我想运行时尝试查找正确视图的上下文是错误的。

我怎样才能做到这一点?

背景

尝试查看模板控制器是否可以使用视图将HTML电子邮件呈现给浏览器,以及呈现为要附加到MailMessage对象主体的字符串。第二种情况将在不同的控制器中发生,因此调用模板控制器的操作的问题不会解析视图。

这可能类似于您想要检查视图结果是否包含您期望的内容的单元测试环境。

谢谢!

1 个答案:

答案 0 :(得分:1)

michielvoo - 正如OT评论中所提到的,如果您还需要将视图或偏见视图输出为字符串(这来自我的BaseController),可能会有一些有用的方法:

public static class ExtensionMethods
{
    // usage
    /*
        var model = _repository.Find(x => x.PropertyID > 3).FirstOrDefault();
        var test = this.RenderViewToString("DataModel", model);
        return Content(test);
     */
    public static string RenderViewToString<T>(this ControllerBase controller, string viewName, T model)
    {
        using (var writer = new StringWriter())
        {
            ViewEngineResult result = ViewEngines
                      .Engines
                      .FindView(controller.ControllerContext, viewName, null);

            var viewPath = ((WebFormView)result.View).ViewPath;
            var view = new WebFormView(viewPath);
            var vdd = new ViewDataDictionary<T>(model);
            var viewCxt = new ViewContext(controller.ControllerContext, view, vdd, new TempDataDictionary(), writer);
            viewCxt.View.Render(viewCxt, writer);
            return writer.ToString();
        }
    }

    public static string RenderPartialToString<T>(this ControllerBase controller, string partialName, T model)
    {
        var vd = new ViewDataDictionary(controller.ViewData);
        var vp = new ViewPage
        {
            ViewData = vd,
            ViewContext = new ViewContext(),
            Url = new UrlHelper(controller.ControllerContext.RequestContext)
        };

        ViewEngineResult result = ViewEngines
                                  .Engines
                                  .FindPartialView(controller.ControllerContext, partialName);

        if (result.View == null)
        {
            throw new InvalidOperationException(
            string.Format("The partial view '{0}' could not be found", partialName));
        }
        var partialPath = ((WebFormView)result.View).ViewPath;

        vp.ViewData.Model = model;

        Control control = vp.LoadControl(partialPath);
        vp.Controls.Add(control);

        var sb = new StringBuilder();

        using (var sw = new StringWriter(sb))
        {
            using (var tw = new HtmlTextWriter(sw))
            {
                vp.RenderControl(tw);
            }
        }
        return sb.ToString();
    }
}

在这种情况下可能有用也可能没用,但值得一看......