2016-06-25 3 views
1

私はWCFサービスを実装し、どのタイプのクライアントからでも呼び出すことができます。私はすでにコンソール、winform、WPFアプリについていくつかの経験がありますので、これをASP.NET MVCを学ぶチャンスとして使いたいと思っていました。ASP.NET MVCフォーム - 以前のフォームの値を持つビューに戻る正しい方法は何ですか?

私はまだ正しく "M"部分を実装していないことを知っていますが、結果を表示するためにフォーム上でデータを処理する正しい方法が、持っているこれまでのところ(作業):

ビュー:

@using (Html.BeginForm("UseSimpleMathClient", "Home")) 
{ 
    <div style="width:450px"> 
     <table style="width:100%"> 
      <tr><td><h4>@Html.Label("First number", new { @for = "num1" })</h4></td> <td> @Html.TextBox("num1", ViewData["num1"])</td></tr> 
      <tr><td><h4>@Html.Label("Second number", new { @for = "num2" })</h4></td> <td> @Html.TextBox("num2", ViewData["num2"])</td></tr> 
      <tr> 
       <td colspan="2"> 
        <h2 style="text-align:center"> 
         <input type="submit" name="operation" value="+" /> 
         <input type="submit" name="operation" value="-" /> 
         <input type="submit" name="operation" value="*" /> 
         <input type="submit" name="operation" value="÷" /> 
        </h2> 
       </td> 
      </tr> 
      <tr> 
       <td colspan="2"><b>@Html.Label("Result")</b> &nbsp; @Html.TextBox("result", ViewData["result"], new {disabled = "disabled", style="min-width:80%;text-align:center" })</td> 
      </tr> 
      </table> 
    </div> 
} 

コントローラー:

 public ActionResult USeSimpleMathClient(char operation) 
    { 
     float num1, num2; 
     float? result = null; 

     if (!float.TryParse(Request.Form[0], out num1) || !float.TryParse(Request.Form[1], out num2)) 
     { 
      ViewData["result"] = "Please enter valid numbers before selecting an operation."; 
     } 
     else 
     { 
      switch (operation) 
      { 
       case '+': 
        result = mathClient.Add(num1, num2); 
        break; 
       case '-': 
        result = mathClient.Subtract(num1, num2); 
        break; 
       case '*': 
        result = mathClient.Multiply(num1, num2); 
        break; 
       case '÷': 
        if (num2 != 0) 
         result = mathClient.Divide(num1, num2); 
        break; 
       default: 
        break; 
      } 

      ViewData["result"] = result != null ? String.Format("{0} {1} {2} = {3}", num1, operation, num2, result) : "You can't divide by zero!"; 
     } 

     ViewData["num1"] = Request.Form[0]; 
     ViewData["num2"] = Request.Form[1]; 
     return View("Index"); 
    } 
+0

こんにちは@Dinerdo、以前はWPFを使用したことがあるとお伝えします。あなたはViewModelsを使い慣れていますか? –

+2

Request.Formを使用して値を取得する代わりに、Geoff Jamesが提案したようにViewModelを作成します。次に、コントローラーアクションでそのモデルを使用して、すべての値を取得します。したがって、 'char operation'を渡す代わりに 'SimpleMathVM model'を渡します。必要なフォームの値を使ってSimpleMathVMクラスを作成するだけです(フォームの値の名前がモデルのプロパティ名と一致することを確認してください)。以前のフォームの値を持つフォームを返す場合は、viewmodelをビューに戻します。最後の行は次のようになります:return View( "Index"、ViewModel)。 – firecape

+2

@firecape:コメントではなく答えにしてみませんか? – quetzalcoatl

答えて

1

[OK]をので、私はあなたのコードを取り、ビューモードを使用して、コントローラのアクションの迅速な実装を行いましたl。いくつかのビューモデルプロパティの上部にデータ注釈属性があるので、num1とnum2が実際に数値であるかどうかを手動で確認する必要はありません。

のViewModel:

public class SimpleMathVM 
{ 
    [Required(ErrorMessage = "Please enter valid numbers before selecting an operation.")] 
    [Display(Name = "First number")] 
    public float Num1 { get; set; } 


    [Required(ErrorMessage = "Please enter valid numbers before selecting an operation.")] 
    [Display(Name = "Second number")] 
    public float Num2 { get; set; } 

    public string Result { get; set; } 

    public char Operation { get; set; } 

} 

コントローラ(GETとPOSTアクションの両方):

public ActionResult USeSimpleMathClient() 
    { 
     return View("Index"); 
    } 


    [HttpPost] 
    public ActionResult USeSimpleMathClient(SimpleMathVM viewModel) 
    { 

    //I moved the checking for zero up here, that way you could immediately return the view. 
    //I kept your version where you populate the Result textbox with the error message, 
    //but really you should probably only add the error message to the ModelState. 

     if (viewModel.Num2 == 0 && viewModel.Operation == '÷') 
     { 
      ModelState.AddModelError(string.Empty, "You can't divide by zero!"); 
      viewModel.Result = "You can't divide by zero!"; 

     //You can pick which one of the above two lines work better for you. 
     //Usually adding error messages to the ModelState is the way to go. 
     } 

     if (!ModelState.IsValid) 
     { 
      return View("Index", viewModel); 
     } 

     switch (viewModel.Operation) 
     { 
      case '+': 
       viewModel.Result = mathClient.Add(viewModel.Num1, viewModel.Num2).ToString(); 
       break; 
      case '-': 
       viewModel.Result = mathClient.Subtract(viewModel.Num1, viewModel.Num2).ToString(); 
       break; 
      case '*': 
       viewModel.Result = mathClient.Multiply(viewModel.Num1, viewModel.Num2).ToString(); 
       break; 
      case '÷': 
       viewModel.Result = mathClient.Divide(viewModel.Num1, viewModel.Num2).ToString(); 
       break; 
      default: 
       break; 
     } 

     return View("Index", viewModel); 
    } 

ビュー:今、あなたのフォームフィールドを強くおに入力することができ

//must bring in the View Model so you can access the MVC lambda helpers below 
@model WebApplication11.Models.SimpleMathVM 

@using (Html.BeginForm("UseSimpleMathClient", "Home")) 
{ 
//You can use ValidationSummary to display object level model errors, 
//such as the division by zero error we directly added to the ModelState 
//in the controller 
@Html.ValidationSummary(true); 

<style type="text/css"> 
    .navbar { 
     display: none !important; 
    } 

    body { 
     padding: 0px 0px 0px 0px !important; 
    } 
</style> 
<div style="width:450px"> 
    <table style="width:100%"> 
     <tr><td><h4>@Html.LabelFor(x => x.Num1)</h4></td> <td> @Html.TextBoxFor(x => x.Num1)</td><td> @Html.ValidationMessageFor(x => x.Num1)</td></tr> 
     <tr><td><h4>@Html.LabelFor(x => x.Num2)</h4></td> <td> @Html.TextBoxFor(x => x.Num2)</td><td> @Html.ValidationMessageFor(x => x.Num2)</td></tr> 
     <tr> 
      <td colspan="2"> 
       <h2 style="text-align:center"> 
        <input type="submit" name="operation" value="+" /> 
        <input type="submit" name="operation" value="-" /> 
        <input type="submit" name="operation" value="*" /> 
        <input type="submit" name="operation" value="÷" /> 
       </h2> 
      </td> 
     </tr> 
     <tr> 
      <td colspan="2"> 
       <b>@Html.LabelFor(x => x.Result)</b> &nbsp; @Html.TextBoxFor(x => x.Result, new { disabled = "disabled", style = "min-width:80%;text-align:center" }) 
       @Html.ValidationMessageFor(x => x.Result) 
      </td> 
     </tr> 
    </table> 
</div> 
} 

注意フォームでモデルを表示できます。 ASP.NET MVCのモデルバインディングシステムは、投稿されたフォームフィールドをポストコントローラアクションのビューモデルインスタンスに単純に取り込みます。フィールドのマッチングの手作業を行う必要はありません。そして、もうViewbagを使う必要はありません。

ポストコントローラーのアクションでは、2番目の数値が0であることを確認し、ModelStateに直接エラーを追加し、結果ビューにもエラーメッセージを表示するので、エラーメッセージが2回表示されます景色。最初は結果ビューにエラーメッセージを表示していましたが、これを保存しましたが、結果テキストボックスに入力するのではなく、ModelStateオブジェクトを介してエラー処理メッセージを追加することを検討することもできます。また、WCFサービスで除算を0でチェックすることもできます。もう1つの選択肢は、ゼロによる除算をチェックするカスタムデータ注釈を作成することです。お役に立てれば。

+0

この説明と詳細レベルをありがとうございます。これはまさに私が探していたものです。 –

+0

よろしくお願いします。 – firecape

関連する問題