开发者

In ASP.NET MVC controller, can I get the view result by calling an action on a different controller

I tried to simply new up a different controller and then calling the action method. The return value is of type ViewResult and the model was created, but the View is null. I guess the context in which the runtime tries to find the correct view is wrong.

开发者_StackOverflow社区How can I achieve this?

Background

Trying to see if a template controller can use a view to both render HTML e-mail to the browser as well as render to a string to be appended to the body of an MailMessage object. The second scenario will happen in a different controller, hence the problem that calling the template controller's action does not resolve the view.

This may be similar to a unit test environment where you want to check if the view result contains the content you expected.

Thanks!


michielvoo - as mentioned in the comment on OT, a few methods that may be useful if you also need to output your views or partialviews as strings (this is from my 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();
    }
}

may or may not be of use in this scenario, but worth a wee look..

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜