2017-11-02 7 views
1

私はユーザーが日付を入れ、日付に応じてデータの表を表示できるフォームを持っています。ユーザーが望む場合は、データをCSVファイルとしてダウンロードできます。 これは私のコントローラである:ASP.NET MVCは別のインデックスに現在のモデルを投稿します

public class SomeController : Controller 
{ 
    [HttpGet] 
    public ActionResult Index() 
    {    
     ModelClass model = new ModelClass(); 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(ModelClass data) 
    { 
     if (data != null) 
     { 
      data.ReadData(); 

      return View(data); 
     } 
     else 
     { 
      return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
     } 
    } 

    [HttpPost] 
    public FileContentResult DownloadCSV(ModelClass data) 
    { 
     if (data != null) 
     { 
      // generate CSV  
     } 
     else 
     { 
      // ... 
     } 
    } 
} 

Basicly私のGET-指数は、デフォルト値(デフォルトの日付とデータ= NULL)で空のモデルを生成します。フォームを介してユーザーは日付を変更し、モデルをPOST-Indexに送信します。関数ReadDataが実行され、データベース要求からモデル内のデータが生成され、ビューに表示されます。モデル内のデータがヌルでない場合、ビューにはDownloadCSVにリンクする別のフォームの表が表示されます。自分のデータを持つ同じモデルがDownloadCSV -siteに掲載されることが期待されます。しかし、代わりに空のモデルが得られます。これはヌルではなく、データなしです。どのように私は私の希望の行動を達成することができ、なぜ記述された行動が期待されるのですか?ここで

ビューです:

@using System.Data 

@model Project.Models.ModelClass 

@{ 
    ViewBag.Title = "Index"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

<h2>Title</h2> 


@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <h4>SubTitle</h4> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 

      <div class="form-group"> 
       @Html.LabelFor(model => model.Date, htmlAttributes: new { @class = "control-label col-md-4" }) 
       <div class="col-md-8"> 
        <div class="input-group date"> 
         @Html.EditorFor(model => model.Date, new { htmlAttributes = new { @class = "form-control form-date datecontrol", id = "datecontrol1" } }) 
         <label class="input-group-addon btn" for="datecontrol1"> 
          <i class="glyphicon glyphicon-calendar"></i> 
         </label> 
        </div> 
        @Html.ValidationMessageFor(model => model.Date, "", new { @class = "text-danger" }) 
       </div> 
      </div> 
     </div> 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Submit" class="btn btn-default" /> 
      </div> 
     </div> 

    </div> 
} 

@if (Model.Data != null) 
{ 
    <hr /> 

    <div class="pre-scrollable"> 
     <table class="table table-bordered table-responsive table-hover"> 
      <tr> 
       <th style="white-space: nowrap; width: 1%;">Zeit</th> 
       @foreach (DataColumn col in Model.Data.Columns) 
       { 
        <th>@col.ColumnName</th> 
       } 
      </tr> 

      @foreach (DataRow row in Model.Data.Rows) 
      { 
       <tr> 
        @foreach (DataColumn field in Model.Data.Columns) 
        { 
         if (field.ColumnName != "Zeit") 
         { 
          <td>@(row[field.ColumnName] != DBNull.Value ? Convert.ToDouble(row[field.ColumnName]).ToString("F1") : "0")</td> 
         } 
        } 
       </tr> 
      } 
     </table> 
    </div> 

    using (Html.BeginForm("DownloadCSV", "Some")) 
    { 
     @Html.AntiForgeryToken() 

     <div class="form-group"> 
      <div class="col-md-offset-9 col-md-12"> 
       <input type="submit" value="Export CSV" class="btn btn-default" /> 
      </div> 
     </div> 
    } 
} 


@*<div> 
    @Html.ActionLink("Back to List", "Index") 
</div>*@ 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
} 

とモデル:

public class ModelClass 
{ 
    [Required] 
    [DataType(DataType.Date)] 
    [DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true)]   
    public DateTime Date { get; set; } 

    public DataTable Data { get; private set; } 

    public ModelClass() 
    { 
     Date = DateTime.Now; 
    } 

    public void ReadData() 
    { 
     Data = new DataTable(); 

     // ... read data from database into datatable 
    } 
} 

あなたが見ることができるようにReadDataが実行されなかった場合、Dataにのみヌルでなければなりません。だから私がDownloadCSVに入るのはちょうどModelClassのインスタンスを作成したものです。

更新:

私はこの質問次TempDataを使用して再度データを要求することなく、DownloadCSVへPOST- IndexからData場の移転を解決することができます:C# MVC pass data from one action method to another

+0

あなたの2番目のフォームにはフォームコントロールが含まれていません - 送信ボタンだけなので、投稿時に何も送信されません –

+0

'Index()' POSTの 'if(data!= null)メソッドは意味をなさない。なぜなら、それは決して 'ヌル 'にならないからである。 –

+0

私は、モデル全体をポストするために、モデルと一緒に隠しフィールドに入れなければならないだろうか? –

答えて

0

スティーブンMueckesのコメントに感謝し、このSO

更新コントローラー:質問 C# MVC pass data from one action method to another 私はこの問題に以下の方法を解決することができ

public class SomeController : Controller 
{ 
    [HttpGet] 
    public ActionResult Index() 
    {    
     ModelClass model = new ModelClass(); 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(ModelClass model) 
    { 
     model.ReadData(); 
     TempData['data'] = model.Data 

     return View(data); 
    } 

    [HttpPost] 
    public FileContentResult DownloadCSV(ModelClass model) 
    { 
     // model only has the date populated from the form, so take the data from TempData 
     model.Data = TempData['data'] 

     // ... generate CSV  
    } 
} 

更新されたビュー:

using (Html.BeginForm("DownloadCSV", "Some")) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-group"> 
     <div class="col-md-offset-9 col-md-12"> 
      @Html.HiddenFor(model => model.Date) 
      <input type="submit" value="Export CSV" class="btn btn-default" /> 
     </div> 
    </div> 
} 

この方法で、私はTempDataに結果を保存し、私はCSVをエクスポートする際にそれらを再度要求する必要はありません。 TempDataは、次の要求に対してのみ保存されます。

関連する問題