2011-12-10 15 views
2

シナリオ:「請求書の請求書」、「索引」、「作成」という3つのビュー(レーザー)があります。MVC3&Razorの単一アクションから複数のビューを返す

  1. [作成]ビューには、請求書データを入力するためのフォームページがあります。
  2. [索引]ページには、現在のすべての日付請求書請求書のリストが含まれています。
  3. InvoiceBillには、このリンク(http://forums.asp.net/t/1711971.aspx/1)に基づいてExcel文書を(請求書レポートとして)生成するコードが含まれています。

フォームを送信すると(ビューの作成)、フォームデータをDBに送信できます(EFを使用)。データが挿入されると、インデックスページが返されます。

しかし、私はインデックスページを呼び出す前に "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"); 
    } 
} 

現在、私はいくつかの回避策でこれを達成しています。しかし、私はそれが良くないと感じます。どのように私は正しい方法でこれを達成することができますか教えてください? おかげ

EDIT:

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> 
+0

上記の質問からRenderViewToStringメソッドを使用してみてください。複数のビューまたは異なるビューを返したいですか? – saintedlama

+0

異なるビュー – getmk

答えて

0

は、私はあなたの質問はthis questionに非常によく似ていると仮定します。唯一の違いは、出力を電子メールではなくExcelとして保存する必要があることです。

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

UPDATE: これを行うためのもう一つの(少し異なる)の方法が、見つけることができますhere

+0

ありがとうアレックス。しかし、私はExcelの次のエラーを取得する可能性は低いです。 "HTTPヘッダーが送信された後にリダイレクトできません。" – getmk

+0

私は更新からのリンクがまったく同じ状況を扱うことだと考えます:http://mikehadlow.blogspot.com/2008/06/mvc-framework-capturing-output-of-view_05.html –

+0

言い換えれば、 'HttpContext。現在は 'controllerContext.HttpContext.Response.Filter'の代わりに使用してください –

関連する問題