つまり、必須フィールド、長さ検証、正規表現などのデータアノテーションは、ビューモデルで実行し、エラーが発生した場合はモデル状態に追加する必要があります。
あなたはおそらく単なる「フォーム」以上のものに依存するビジネス/ドメインのルールを持っているでしょうから、ドメインモデルでそれを行う(それらがマップされた後に検証を実行する)か、サービス層。
すべてのモデルには、「検証」と呼ばれるメソッドがあり、永続化する前にサービスで呼び出します。ビジネス検証に失敗した場合、カスタム例外がスローされます。ビジネス検証は、コントローラによって捕捉され、モデル状態に追加されます。
誰もが紅茶ではないかもしれませんが、一貫しています。
ビジネス検証の例は、要求通り:
public abstract class Post
{
// .. fields, properties, domain logic, etc
public void Validate()
{
if (!this.GeospatialIdentity.IsValidForThisTypeOfPost())
throw new DomainException(this, BusinessException.PostNotValidForThisSpatial.);
}
}
:ここ は、一般的な「ポスト」(質問、写真、動画など)を表し、我々が持っているドメインモデルの例です
私はビジネスルールをチェックしており、カスタム例外を投げています。 DomainException
が私たちの拠点であり、多くの派生的な実装があります。 BusinessException
と呼ばれる列挙型がありますが、これにはすべての例外の値が含まれています。列挙型の拡張メソッドを使用して、リソースベースのエラーメッセージを提供します。
これは単純にモデルのチェックのフィールドではありません。たとえば、「すべての投稿には件名が必要です」ということです。これはドメインの一部ですが、まず入力の検証が行われるため、データ注釈ビューモデル上で今
、コントローラ: [HttpPost]
public ActionResult Create(QuestionViewModel viewModel)
{
if (!ModelState.IsValid)
return View(viewModel);
try
{
// Map to ViewModel
var model = Mapper.Map<QuestionViewModel,Question>(viewModel);
// Save.
postService.Save(model); // generic Save method, constraint: "where TPost: Post, new()".
// Commit.
unitOfWork.Commit();
// P-R-G
return RedirectToAction("Index", new { id = model.PostId });
}
catch (Exception exc)
{
var typedExc = exc as DomainException;
if (typedExc != null)
{
// Internationalised, user-friendly domain exception, so we can show
ModelState.AddModelError("Error", typedExc.BusinessError.ToDescription());
}
else
{
// Could be anything, e.g database exception - so show generic msg.
ModelState.AddModelError("Error", "Sorry, an error occured saving the Post. Support has been notified. Please try again later.");
}
}
return View(viewModel);
}
だから、我々はサービスの「保存」の方法を取得時までに、モデルが経過した入力の検証。次に、Saveメソッドはビジネス・ルールを呼び出すpost.Validate()
を呼び出します。
例外が発生した場合、コントローラはそれをキャッチしてメッセージを表示します。それがSaveメソッドをパスし、別のエラーが発生すると(例えば、90%の時間、Entity Frameworkなど)、一般的なエラーメッセージが表示されます。
私が言ったように、皆にとってではないが、これは私たちのチームにとってはうまくいく。私たちは、プレゼンテーションとドメインの検証を明確に分離しており、生のHTTP POSTから成功後のリダイレクトへの一貫した制御フローを持っています。
HTH
「ビジネスモデル」は何ですか? –
PersonはEntityFrameworkによって追跡されるクラスです。 PersonViewModelは明らかに私がリンクしているブログの記事を読んでいないので、あなたが従うべきことを理解しようとしています。したがって、検証ロジックはどこに行くべきかという疑問です。 – ignaciofuentes
ありがとう - 申し訳ありませんが、記事をスキャンし、その中で "ビジネスモデル"を検索しましたが、ヒットしませんでした。 –