asp.net mvc 利用视图进行渲染,无需创建控制器操作

发布于 2024-09-29 19:29:51 字数 695 浏览 3 评论 0原文

我需要生成特定于 Customer 对象的 html(用于电子邮件正文)
我想制作一个 View 来获取 Customer 对象并呈现适当的文本。

有没有办法调用视图并获取渲染的输出而不将其关联到控制器操作?

理想情况下,在 pseydocode 中我会做这样的事情

customer = new Customer();
view = new GetCustomerEmailBodyView(customer);
string htmlBody = view.SomeFunctionToRenderViewAndGetOutput()

我找到了一个解决方案来获取视图的 HTML 此处有一个操作返回 StringResult(继承自 ViewResult),而不是公开 Html 属性的 ActionResult。
然而,我仍然需要创建一个自定义操作来调用它,而且我不喜欢它依赖于 ControllerContext ,这使得测试它变得困难。

我对 MVC 负责人提出的要求是什么?对于这种情况,我的代码应该如何构建?

I need to generate html (for the body of an email message) specific to a Customer object
I thought of making a View that gets a Customer object and renders the appropriate text.

Is there a way to call a view and get the rendered output without associating it to a controller action?

Ideally in pseydocode I would do something like this

customer = new Customer();
view = new GetCustomerEmailBodyView(customer);
string htmlBody = view.SomeFunctionToRenderViewAndGetOutput()

I have found a solution to get the HTML of a view here that has an action returning a StringResult (inherits from ViewResult) instead of ActionResult which exposes an Html property.
However I still have to make a custom action to call it, and I don't like the fact that it depends on the ControllerContext making it hard to test it.

Is what I am requesting against the MVC principals? How should my code be structured for this scenario?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

分開簡單 2024-10-06 19:29:51

原始代码来自此处

protected string RenderPartialViewToString(string viewName, object model) {
    if (string.IsNullOrEmpty(viewName))
        viewName = ControllerContext.RouteData.GetRequiredString("action");
    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();
    }
}

Original code from here

protected string RenderPartialViewToString(string viewName, object model) {
    if (string.IsNullOrEmpty(viewName))
        viewName = ControllerContext.RouteData.GetRequiredString("action");
    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();
    }
}
马蹄踏│碎落叶 2024-10-06 19:29:51

您是说您希望某些程序能够在根本不处于控制器上下文中的情况下利用视图,还是您希望能够将视图从控制器内呈现为字符串,而不调用其他一些程序控制器?

对于前者,我无法提供太多帮助,但对于后者,我们在与所有其他控制器一起继承的基本控制器类型中拥有此方法:

    /// <summary>
    /// Generates a string based on the given PartialViewResult.
    /// </summary>
    /// <param name="partialViewResult"></param>
    /// <returns></returns>
    protected internal string RenderPartialViewToString(ViewResultBase partialViewResult)
    {
        Require.ThatArgument(partialViewResult != null);
        var context = ControllerContext;
        Require.That(context != null);
        using (var sw = new StringWriter())
        {
            if (string.IsNullOrEmpty(partialViewResult.ViewName))
            {
                partialViewResult.ViewName = context.RouteData.GetRequiredString("action");
            }
            ViewEngineResult result;
            if (partialViewResult.View == null)
            {
                result = partialViewResult.ViewEngineCollection.FindPartialView(context, partialViewResult.ViewName);
                Require.That(result.View != null,
                             () => new InvalidOperationException(
                                       "Unable to find view. Searched in: " +
                                       string.Join(",", result.SearchedLocations)));
                partialViewResult.View = result.View;
            }

            var view = partialViewResult.View;
            var viewContext = new ViewContext(context, view, partialViewResult.ViewData,
                                              partialViewResult.TempData, sw);
            view.Render(viewContext, sw);
            return sw.ToString();
        }
    }

用法:

public ActionResult MyAction(...) 
{
    var myModel = GetMyModel(...);
    string viewString = RenderPartialViewToString(PartialView("MyView", myModel));
    // do something with the string
    return someAction;
}

我们实际上在基于事件的 AJAX 模型中使用此方法,我们的大多数操作实际上只是返回 AJAX 编码的客户端事件列表,其中一些客户端事件可能是使用渲染此部分视图生成的字符串来更新特定的 DOM 元素。

Are you saying that you want some program to be able to leverage a View without being in a controller context at all, or are you saying that you want to be able to render a view into a string from within a controller, without calling some other controller?

For the former, I can't be of much assistance, but for the latter, we have this method in the base controller type that we inherit with all our other controllers:

    /// <summary>
    /// Generates a string based on the given PartialViewResult.
    /// </summary>
    /// <param name="partialViewResult"></param>
    /// <returns></returns>
    protected internal string RenderPartialViewToString(ViewResultBase partialViewResult)
    {
        Require.ThatArgument(partialViewResult != null);
        var context = ControllerContext;
        Require.That(context != null);
        using (var sw = new StringWriter())
        {
            if (string.IsNullOrEmpty(partialViewResult.ViewName))
            {
                partialViewResult.ViewName = context.RouteData.GetRequiredString("action");
            }
            ViewEngineResult result;
            if (partialViewResult.View == null)
            {
                result = partialViewResult.ViewEngineCollection.FindPartialView(context, partialViewResult.ViewName);
                Require.That(result.View != null,
                             () => new InvalidOperationException(
                                       "Unable to find view. Searched in: " +
                                       string.Join(",", result.SearchedLocations)));
                partialViewResult.View = result.View;
            }

            var view = partialViewResult.View;
            var viewContext = new ViewContext(context, view, partialViewResult.ViewData,
                                              partialViewResult.TempData, sw);
            view.Render(viewContext, sw);
            return sw.ToString();
        }
    }

Usage:

public ActionResult MyAction(...) 
{
    var myModel = GetMyModel(...);
    string viewString = RenderPartialViewToString(PartialView("MyView", myModel));
    // do something with the string
    return someAction;
}

We actually use this in an event-based AJAX model, where most of our actions actually just return an AJAX-encoded list of client-side events, and some of those client-side events may be to update a particular DOM element with the string produces by rendering this partial view.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文