asp.net mvc использует представление для рендеринга без создания действия контроллера - PullRequest
2 голосов
/ 30 октября 2010

Мне нужно создать html (для тела сообщения электронной почты), специфичный для Customer объекта
Я думал о создании View, который получает объект Customer и отображает соответствующий текст.

Есть ли способ вызвать представление и получить визуализированный вывод, не связывая его с действием контроллера?

В идеале в псевдокоде я бы сделал что-то вроде этого

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

Я нашел решение, чтобы получить HTML представления здесь , в котором есть действие, возвращающее StringResult (наследует от ViewResult) вместо ActionResult, которое предоставляет свойство Html.
Однако мне все еще нужно сделать специальное действие для его вызова, и мне не нравится тот факт, что это зависит от ControllerContext, затрудняющего его тестирование.

Это то, что я прошу против принципалов MVC? Как мой код должен быть структурирован для этого сценария?

Ответы [ 2 ]

3 голосов
/ 30 октября 2010

Оригинальный код от здесь

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();
    }
}
1 голос
/ 30 октября 2010

Вы говорите, что хотите, чтобы какая-то программа могла использовать View, вообще не находясь в контексте контроллера, или вы хотите, чтобы вы имели возможность рендерить представление в строку изнутри контроллера, безВызываете какой-то другой контроллер?

Для первого я не могу оказать большую помощь, но для последнего у нас есть этот метод в базовом типе контроллера, который мы наследуем со всеми другими нашими контроллерами:

    /// <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 с помощью строки, получаемой путем рендеринга этого частичного представления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...