【问题标题】:Returning multiple views from single action in MVC3 & Razor从 MVC3 和 Razor 中的单个操作返回多个视图
【发布时间】:2011-12-10 06:31:09
【问题描述】:

场景:共有三个视图(Razor),分别命名为“InvoiceBill”、“Index”、“Create”。

  1. 创建视图包含用于输入发票数据的表单页面。
  2. 索引页面包含所有当前日期发票清单。
  3. InvoiceBill 包含基于此链接 (http://forums.asp.net/t/1711971.aspx/1) 生成 excel 文档(作为发票报告)的代码。

一旦我提交表单(创建视图),它就可以将表单数据发布到数据库(使用 EF)。插入数据后,返回Index页面。

但现在我需要在调用索引页面之前调用“InvoiceBill”视图。

[HttpPost]
public ActionResult Create(FormCollection collection, InvoiceViewModel INVViewModel)
{
   if ((collection != null) && (this.ModelState.IsValid))
   {
        salesOrder.AccountNumber = INVViewModel.AccountNumber;
        salesOrder.BillToAddressID = INVViewModel.BillToAddressID;
        salesOrder.Comment = INVViewModel.Comment;
        salesOrder.ContactID = INVViewModel.ContactID;
        .
        .
        .
        .
        int sID = Using<CreateSalesOrder>().Execute(0, salesOrder);
***** From here i need to call the InvoiceBill page. Or guide me any other good way to achieve this
        return RedirectToAction("Index");
   }
}

现在我正在通过一些解决方法来实现这一点。但是我觉得这样不好。请指导我如何以正确的方式实现这一目标? 谢谢

编辑:

public ActionResult PrintInvoice(int id)
        {
            InvoiceReportViewModel invoiceReport = new InvoiceReportViewModel();
            var soToView = Using<GetSalesOrders>().ExecuteForReport(id);

            invoiceReport.InvoiceBillName = "Invoice" + id.ToString();
            invoiceReport.CustomerName = soToView.Customer.Name;
            invoiceReport.SalesOrderNumber = soToView.SalesOrderNumber;
            .
            .
            .
            .

            return View(invoiceReport);
        }

InvoiceReport.cshtml

@model eItemBox.Web.Models.InvoiceReportViewModel
@{
    Layout = null;
    Response.ContentType = "application/vnd.ms-excel";
    Response.AddHeader("Content-Disposition", "attachment; filename=" + Model.InvoiceBillName);
    //Content-Disposition is defined in RFC-2183
}
<Worksheet ss:Name="MyInvoice">
.
.
.

</Workbook>

【问题讨论】:

  • 您要返回多个视图还是不同的视图?

标签: c# asp.net asp.net-mvc-3


【解决方案1】:

我想您的问题与this question 非常相似。唯一的区别是,您需要将输出保存为 Excel,而不是作为电子邮件发送。

请尝试使用上述问题中的RenderViewToString 方法:

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;
  }
}

更新: 另一种(有点不同)的方法,可以找到here

【讨论】:

  • 谢谢亚历克斯。但我不太可能在 excel 文档中收到以下错误。 “发送 HTTP 标头后无法重定向。”
  • 我想更新中的链接是关于处理完全相同的情况:mikehadlow.blogspot.com/2008/06/…
  • 在视图词中,应该使用HttpContext.Current而不是controllerContext.HttpContext.Response.Filter
  • 我已经编辑了问题,你能指导我在哪里可以做改变
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多