ASP.NETMVCのViewModelについて学び始めました。そこで、以下のようなサンプル例を実装することを考えました。
事業体
public class AddModel
{
public int a { get; set; }
public int b { get; set; }
public int Add()
{
return (this.a + this.b);
}
}
ViewModelを追加
public class AddViewModel
{
public AddModel addModel;
public int Total { get; set; }
}
コントローラー
public class AddController : Controller
{
[HttpPost]
public JsonResult Add(AddViewModel model)
{
int iSum = model.addModel.a + model.addModel.b;
model.Total = iSum;
return Json(model);
}
public ActionResult Index()
{
return View();
}
}
実装の表示
@model ViewModelApplication.AddViewModel
<script type="text/javascript" src="../../Scripts/MicrosoftAjax.js"></script>
<script src="../../Scripts/MicrosoftMvcAjax.debug.js" type="text/javascript"></script>
<script type="text/javascript">
function Callback(data) {
alert("I am sucess call");
}
function Failed() {
alert("I am a failure call");
}
</script>
@using (Ajax.BeginForm("Add", "Add", new AjaxOptions { OnSuccess = "Callback", OnFailure = "Failed" }))
{
<table align="center">
<tr>
<td class="tdCol1Align">
<label>
Number1</label>
</td>
<td class="tdCol2Align">
@Html.TextBoxFor(Model => Model.addModel.a)
</td>
</tr>
<tr>
<td class="tdCol1Align">
<label>
Number2</label>
</td>
<td class="tdCol2Align">
@Html.TextBoxFor(Model => Model.addModel.b)
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Add" class="button" />
</td>
</tr>
</table>
}
ここでの問題は、Add
ボタンがクリックされるたびにテキストボックスに入力された値を取得できないことです。対応するAJAXアクションがそれです。
a
とb
の値にアクセスしようとすると、テキストボックスに入力された値の代わりにnullが表示されます。
どこが間違っているのかわかりません。助けてください。
ビューモデルは次のようになります
public class AddViewModel
{
public int a { get; set; }
public int b { get; set; }
public int Total { get; set; }
}
とcshtmlで
<td class="tdCol2Align">
@Html.TextBoxFor(m=> m.a)
</td>
<td class="tdCol2Align">
@Html.TextBoxFor(m=> m.b)
</td>
コントローラーで
[HttpPost]
public JsonResult Add(AddViewModel model)
{
int iSum = model.a + model.b;
model.Total = iSum;
return Json(model);
}
編集
ビューモデルは、ビューをレンダリングするためにあり、その中にロジックを配置しません。より複雑なモデルがある場合、Model
をViewModel
にマッピングするのは困難です。このために、モデルとビューモデル間のマッピングにAutoMapperまたはValueInjectorを使用できます。
automapperのリンク http://automapper.codeplex.com/
バリューインジェクターのリンク http://valueinjecter.codeplex.com/
お役に立てれば
ビューモデルでドメイン(ビジネス)エンティティを使用しないでください。そうした場合、ビューモデルには、ビューに必要のないビジネスロジックがまだ含まれているため、まったく役に立ちません。あなたの例のモデルは実際には実際のシナリオを表していないので、とにかくビューモデルは実際には必要ありません。
ビューモデルのより一般的で簡単な例は、ログインフォームです。おそらくUser
というドメインモデルがあり、それらにログインさせたいと考えています。User
ドメインモデルは大きく、そのごく一部が認証に必要です。また、ログインフォームの検証ロジックを表さないデータベースの検証ロジックも含まれています。
User
ドメインモデル:
public class User
{
[Required]
public string UserName { get; set; }
[Required]
[MaxLength(36)] // The password is hashed so it won't be bigger than 36 chars.
public string Password { get; set; }
public string FullName { get; set; }
public string SalesRepresentative { get; set; }
// etc..
}
上記のドメインモデルはデータベーステーブルを表しているため、整合性を確保するための検証ロジックが含まれています。
public class LoginModel
{
[Display(Name = "User Name")]
[Required(ErrorMessage = "Please fill in your user name.")]
public string UserName { get; set; }
[Required(ErrorMessage = "Please fill in your password.")]
public string Password { get; set; }
public bool RememberMe { get; set; }
}
上記のビューモデルには、ログインフォームに必要なプロパティのみが含まれており、独自のデータ注釈があります。これは、ビューロジックとビジネス/データロジックを明確に分離するのに役立ちます。