从MVC3中的单个动作返回多个视图;剃须刀

本文关键字:视图 剃须刀 返回 MVC3 单个动 | 更新日期: 2023-09-27 18:17:29

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

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

一旦我提交表单(创建视图),它可以将表单数据发布到DB(使用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>

从MVC3中的单个动作返回多个视图;剃须刀

我想你的问题和这个问题很相似。唯一的区别是,您需要将输出保存为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;
  }
}

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