6

ASP.NET MVCを使用して、MVCモデルにバインドされた検証を使用できるように属性をアタッチしているモデルがありますが、これは MVC のルールを壊しません。ビュー、モデルに? 賢くなろうとしているわけではないことを願っていますが、他の人の意見には興味があります。

public class Payments
{
    [DataType(DataType.Text)]
    [DisplayFormat(NullDisplayText="")]
    [Display(Name="Payment Id")]
    [Required(ErrorMessage="Required")]
    public int PaymentId { get; set; } //todo: make this into a dropdown

    [DataType(DataType.Text)]
    [Display(Name="Bill Name")]
    [Required(ErrorMessage = "Required")]
    public string PaymentName { get; set; }

    [DataType(DataType.Date)]
    [Display(Name="Date to Post Payment")]
    [Required(ErrorMessage = "Required")]
    public DateTime PaymentDate { get; set; }

    [DataType(DataType.Currency)]
    [Range(0, 922337203685477.5807)]
    [Required(ErrorMessage = "Required")]
    public double PaymentAmount { get; set; }
}
4

3 に答える 3

10

はい。そのため、ViewModelsを使用する必要があります。

于 2011-05-18T14:10:28.827 に答える
10

これらの検証属性をモデルに配置できますが、必須ではありません。

ただし、ViewModel を使用することをお勧めします。

public class PaymentsViewModel
{
    [DataType(DataType.Text)]
    [DisplayFormat(NullDisplayText="")]
    [Display(Name="Payment Id")]
    [Required(ErrorMessage="Required")]
    public int PaymentId { get; set; } //todo: make this into a dropdown

    [DataType(DataType.Text)]
    [Display(Name="Bill Name")]
    [Required(ErrorMessage = "Required")]
    public string PaymentName { get; set; }

    [DataType(DataType.Date)]
    [Display(Name="Date to Post Payment")]
    [Required(ErrorMessage = "Required")]
    public DateTime PaymentDate { get; set; }

    [DataType(DataType.Currency)]
    [Range(0, 922337203685477.5807)]
    [Required(ErrorMessage = "Required")]
    public double PaymentAmount { get; set; }
}

そしてあなたのビューでは、代わりに:

@model YourProject.Models.Payments

あなたが使う:

@model YourProject.Models.PaymentsViewModel

検証のために。

于 2011-05-18T14:19:05.643 に答える
1

厳密な意味で MVC に違反していますか。それに違反しても害がない場合はありますか?もちろん。ただし、あなたを助け、懸念を分離しておくためのメカニズムがあります。

永続化されたドメイン オブジェクトをビューで使用して検証することはできますが、ビューが複雑になり始めると、ViewModel が必要になります。非常に単純なドメイン モデルまたはビューのみのビュー (編集/作成ではない) については、少しごまかして、複合オブジェクトの一部としてビューに送信することがあります。

class MyViewModel
{
    public MyDomainModel DomainObj;
    public int OtherViewInfo;
}

ただし、作成および編集のシナリオでは、ViewModel の方がはるかに優れています。ビューに送信されるデータとビューから送信されるデータを完全に制御できます。

EF 4.1 と CodeFirst を使用している場合は、ドメインと ViewModel の間で属性とプロパティが重複することになります。これは避けられませんが、ビューに固有のさまざまな検証を柔軟に行うことができます。

ビューでいくつかの検証を逃した場合に備えて、ドメインオブジェクトを実際に保存するときに、コントローラーに保護のレイヤーを追加すると便利であることがわかりました。

public class MyController : Controller
{
    [HttpPost]
    public ActionResult Edit(int id, MyViewModel model)
    {
        try
        {
            ...Do stuff, check ModelState.IsValid...
            _context.SaveChanges()
        }
        catch (DbEntityValidationException dbEx)
        {
            // Catch any validation errors on the domain that weren't duplicated
            // in the viewmodel
            ModelState.AddModelError("Form", dbEx);
        }

        return View(model);
    }
}

次の質問は、ドメイン モデルと ViewModel の間をどのようにマッピングするかです。AutoMapperValueInjecter (はい、スペルが間違っています)など、多くの戦略とツールがあります。個人的には、ValueInjecter を使用していますが、マッピング レイヤーをセットアップすれば、両方を試すことができます。どちらも 100% のケースで機能しないか、少なくとも必要なことを行う方法を理解できたことがわかりましたが、マッピング サービスを使用すると、カスタムの左から右へのマップを簡単に定義できます。

于 2011-05-18T14:38:06.813 に答える