Я хочу вывести два разных представления (одно в виде строки, которая будет отправлена по электронной почте), а другое - на страницу, отображаемую пользователю.
Возможно ли это в ASP.NET MVC beta?
Я пробовал несколько примеров:
1. RenderPartial к String в ASP.NET MVC Beta
Если я использую этот пример, я получаю сообщение «Невозможно перенаправить после отправки заголовков HTTP».
2. MVC Framework: захват вывода представления
Если я использую это, мне кажется, что я не могу выполнить redirectToAction, так как он пытается отобразить представление, которое может не существовать. Если я верну вид, он полностью испорчен и выглядит не совсем правильно.
У кого-нибудь есть какие-либо идеи / решения этих проблем, которые у меня есть, или есть предложения для лучших?
Большое спасибо!
Ниже приведен пример. Я пытаюсь создать метод GetViewForEmail :
public ActionResult OrderResult(string ref)
{
//Get the order
Order order = OrderService.GetOrder(ref);
//The email helper would do the meat and veg by getting the view as a string
//Pass the control name (OrderResultEmail) and the model (order)
string emailView = GetViewForEmail("OrderResultEmail", order);
//Email the order out
EmailHelper(order, emailView);
return View("OrderResult", order);
}
Принял ответ от Тима Скотта (немного измененный и отформатированный мной):
public virtual string RenderViewToString(
ControllerContext controllerContext,
string viewPath,
string masterPath,
ViewDataDictionary viewData,
TempDataDictionary tempData)
{
Stream filter = null;
ViewPage viewPage = new ViewPage();
//Right, create our view
viewPage.ViewContext = new ViewContext(controllerContext, new WebFormView(viewPath, masterPath), viewData, tempData);
//Get the response context, flush it and get the response filter.
var response = viewPage.ViewContext.HttpContext.Response;
response.Flush();
var oldFilter = response.Filter;
try
{
//Put a new filter into the response
filter = new MemoryStream();
response.Filter = filter;
//Now render the view into the memorystream and flush the response
viewPage.ViewContext.View.Render(viewPage.ViewContext, viewPage.ViewContext.HttpContext.Response.Output);
response.Flush();
//Now read the rendered view.
filter.Position = 0;
var reader = new StreamReader(filter, response.ContentEncoding);
return reader.ReadToEnd();
}
finally
{
//Clean up.
if (filter != null)
{
filter.Dispose();
}
//Now replace the response filter
response.Filter = oldFilter;
}
}
Пример использования
Принимая вызов от контроллера, чтобы получить подтверждение заказа по электронной почте, передав местоположение Site.Master.
string myString = RenderViewToString(this.ControllerContext, "~/Views/Order/OrderResultEmail.aspx", "~/Views/Shared/Site.Master", this.ViewData, this.TempData);
источник
Ответы:
Вот то, что я придумал, и это работает для меня. Я добавил следующие методы в базовый класс контроллера. (Вы всегда можете сделать эти статические методы где-нибудь еще, которые принимают контроллер в качестве параметра, я полагаю)
Стиль MVC2 .ascx
Бритва .cshtml стиль
Изменить: добавлен код бритвы.
источник
Этот ответ не на моем пути. Это родом из https://stackoverflow.com/a/2759898/2318354, но здесь я покажу, как использовать его со «статическим» ключевым словом, чтобы сделать его общим для всех контроллеров.
Для этого вы должны сделать
static
класс в файле класса. (Предположим, ваше имя файла класса Utils.cs)Этот пример для бритвы.
Utils.cs
Теперь вы можете вызвать этот класс из вашего контроллера, добавив NameSpace в ваш файл контроллера следующим образом, передав «this» в качестве параметра в Controller.
По предложению @Sergey этот метод расширения может также вызываться из cotroller, как указано ниже
Надеюсь, это поможет вам сделать код чистым и аккуратным.
источник
Это работает для меня:
источник
Я нашел новое решение, которое отображает строку без необходимости связываться с потоком Response текущего HttpContext (который не позволяет вам изменять ContentType ответа или другие заголовки).
По сути, все, что вам нужно сделать, это создать поддельный HttpContext для представления, которое будет отображаться само по себе:
Это работает в ASP.NET MVC 1.0 вместе с ContentResult, JsonResult и т. Д. (Изменение заголовков исходного HttpResponse не приводит к исключению « Сервер не может установить тип содержимого после отправки заголовков HTTP »).
Обновление: в ASP.NET MVC 2.0 RC код немного меняется, потому что мы должны передать
StringWriter
используемый для записи представления вViewContext
:источник
StringWriter
вы используете для записиStringBuilder
, а не новый экземпляр, иначе выходные данные представления будут потеряны.В этой статье описывается, как визуализировать представление в строку в различных сценариях:
Решение / код предоставляется в виде класса с именем ViewRenderer . Это часть WestwindToolkit Рика Штала в GitHub .
Использование (3. - пример WebAPI):
источник
Если вы хотите полностью отказаться от MVC, избегая тем самым всего беспорядка HttpContext ...
Здесь используется потрясающий движок Razor с открытым исходным кодом: https://github.com/Antaris/RazorEngine
источник
CompilerErrors
свойстве исключения.Вы получаете представление в строке, используя этот способ
Мы называем этот метод двумя способами
ИЛИ
источник
Дополнительный совет для ASP NET CORE:
Интерфейс:
Реализация:
Регистрация в
Startup.cs
И использование в контроллере:
источник
Я использую MVC 1.0 RTM, и ни одно из вышеперечисленных решений не помогло мне. Но этот сделал:
источник
Я видел реализацию MVC 3 и Razor с другого сайта, у меня это сработало:
Подробнее о Razor render - MVC3 View Render to String
источник
Чтобы визуализировать представление строки в слое обслуживания без необходимости передавать ControllerContext, здесь есть хорошая статья Рика Строла http://www.codemag.com/Article/1312081, которая создает универсальный контроллер. Краткое содержание кода ниже:
Затем для рендеринга View в классе Service:
источник
Быстрая подсказка
Для строго типизированной модели просто добавьте ее в свойство ViewData.Model, прежде чем переходить к RenderViewToString. например
источник
Чтобы повторить более неизвестный вопрос, взгляните на MvcIntegrationTestFramework .
Это избавляет вас от написания собственных помощников для потоковой передачи результатов и доказывает, что работает достаточно хорошо. Я предполагаю, что это будет в тестовом проекте, и в качестве бонуса у вас будут другие возможности тестирования, как только вы получите эту настройку. Главным беспокойством, вероятно, будет сортировка цепочки зависимостей.
источник
Вот класс, который я написал, чтобы сделать это для ASP.NETCore RC2. Я использую его, чтобы я мог генерировать html электронную почту, используя Razor.
источник
Я нашел лучший способ визуализации страницы просмотра бритвой, когда у меня возникли ошибки с помощью описанных выше методов, это решение как для среды веб-форм, так и для среды MVC. Контроллер не нужен.
Вот пример кода, в этом примере я смоделировал действие mvc с помощью асинхронного http-обработчика:
источник