C# 从MVC3中的单个操作返回多个视图&;剃须刀

C# 从MVC3中的单个操作返回多个视图&;剃须刀,c#,asp.net,asp.net-mvc-3,C#,Asp.net,Asp.net Mvc 3,场景:有三个视图(Razor)名为“InvoicePill”、“Index”、“Create” “创建”视图包含用于输入发票数据的表单页面 索引页包含所有当前日期发票账单的列表 InvoicePill包含基于此链接生成excel文档(作为发票报告)的代码() 一旦我提交表单(创建视图),它就可以将表单数据发布到DB(使用EF)。插入数据后,返回索引页 [HttpPost] public ActionResult Create(FormCollection collection, InvoiceV

场景:有三个视图(Razor)名为“InvoicePill”、“Index”、“Create”

  • “创建”视图包含用于输入发票数据的表单页面
  • 索引页包含所有当前日期发票账单的列表
  • InvoicePill包含基于此链接生成excel文档(作为发票报告)的代码()
  • 一旦我提交表单(创建视图),它就可以将表单数据发布到DB(使用EF)。插入数据后,返回索引页

    [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");
       }
    }
    
    但是现在我需要在调用索引页之前调用“invoiceill”视图

    [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");
       }
    }
    
    [HttpPost]
    公共操作结果创建(FormCollection集合、InvoiceViewModel INVViewModel)
    {
    if((collection!=null)&&(this.ModelState.IsValid))
    {
    salesOrder.AccountNumber=INVViewModel.AccountNumber;
    salesOrder.BillToAddressID=INVViewModel.BillToAddressID;
    salesforder.Comment=INVViewModel.Comment;
    salesOrder.ContactID=INVViewModel.ContactID;
    .
    .
    .
    .
    int sID=Using().Execute(0,salesOrder);
    *****从这里,我需要调用InvoicePill页面。或者指导我实现这一目标的任何其他好方法
    返回操作(“索引”);
    }
    }
    
    现在我通过一些变通方法来实现这一点。但我觉得这不好。请指导我如何以正确的方式实现这一目标? 谢谢

    编辑:

    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);
            }
    
    public ActionResult打印发票(int-id)
    {
    InvoiceReportViewModel invoiceReport=新的InvoiceReportViewModel();
    var soToView=Using().ExecuteForReport(id);
    invoiceReport.InvoiceBillName=“发票”+id.ToString();
    invoiceReport.CustomerName=soToView.Customer.Name;
    invoiceReport.SalesOrderNumber=soToView.SalesOrderNumber;
    .
    .
    .
    .
    返回视图(发票报告);
    }
    
    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>
    
    @model eItemBox.Web.Models.InvoiceReportViewModel
    @{
    布局=空;
    Response.ContentType=“application/vnd.ms excel”;
    Response.AddHeader(“内容处置”、“附件;文件名=“+Model.InvoiceBillName”);
    //内容处置在RFC-2183中定义
    }
    .
    .
    .
    
    我想你的问题与我的非常相似。唯一的区别是,您需要将输出保存为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;
      }
    }
    

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

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

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

    是否要返回多个视图或不同的视图?是否要返回多个视图或不同的视图?谢谢Alex。但我不太可能在excel文档中遇到以下错误。“发送HTTP头后无法重定向。”我想来自更新的链接是关于处理完全相同的情况的:在view Word中,
    HttpContext.Current
    应该使用,而不是
    controllerContext.HttpContext.Response.Filter
    我已经编辑了问题,你能告诉我在哪里可以进行更改吗Hanks Alex。但我不太可能在excel文档中遇到以下错误。“发送HTTP头后无法重定向。”我想来自更新的链接是关于处理完全相同的情况的:在view Word中,
    HttpContext.Current
    应该使用,而不是
    controllerContext.HttpContext.Response.Filter
    我已经编辑了问题,你能告诉我在哪里可以进行更改吗