2

これは、スタック オーバーフローに関する最初の質問です。現在取り組んでいる ASP.NET MVC2 プロジェクトで発生した問題についてサポートが必要です。私はMVC設計に比較的慣れていないことに注意してください。ここに行きます:私は、人に関するさまざまな詳細が表示される通常のフォームを持っています。その一つが「生年月日」です。私の見解はこんな感じです

<div class="form-items">
            <%: Html.Label("DateOfBirth", "Date of Birth:") %>
            <%: Html.EditorFor(m => m.DateOfBirth) %>
            <%: Html.ValidationMessageFor(m => m.DateOfBirth) %>
</div>

日付のみを正しく表示するために、見つけたエディター テンプレートを使用しています。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>"%>
<%= Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty))%>

LinqToSql デザイナーを使用して、SQL データベースからモデルを作成しました。いくつかの検証を行うために、部分クラス Person を作成して、デザイナーによって作成されたものを拡張します (同じ名前空間の下):

[MetadataType(typeof(IPerson))]
public partial class Person : IPerson
{        //To create buddy class    }

public interface IPerson
{
    [Required(ErrorMessage="Please enter a name")]
    string Name { get; set; }
    [Required(ErrorMessage="Please enter a surname")]
    string Surname { get; set; }
    [Birthday]
    DateTime? DateOfBirth { get; set; }
    [Email(ErrorMessage="Please enter a valid email")]
    string Email { get; set; }
}

正しい日付が入力されていることを確認したい。そこで、日付を検証するためにカスタム DataAnnotation 属性を作成しました。

public class BirthdayAttribute : ValidationAttribute
{
    private const string _errorMessage = "Please enter a valid date";

    public BirthdayAttribute() : base(_errorMessage) { }

    public override bool  IsValid(object value)
    {
        if (value == null)
        {
            return true;
        }
        DateTime temp;
        bool result = DateTime.TryParse(value.ToString(), out temp);
        return result;
    }
}

さて、私の問題はこれです。DateOfBirth フィールドに間違った日付を入力すると、[Birthday(ErrorMessage=".....")] のような属性を使用してもカスタム メッセージが表示されません。表示されるメッセージは、データベースから返されたもの、つまり「値 '32/4/1967' は DateOfBirth には無効です。」 です。コードの周りにいくつかのブレークポイントを入力しようとしましたが、日付が正しくない場合、属性の「値」は常に null ですが、日付が正しい形式の場合は常に値を取得することがわかりました。デザイナが生成したコードにも同じ ( value == null ) が渡されます。

このことは私を夢中にさせています。誰でも私がこれに対処するのを手伝ってくれますか? また、ビューからデータベースへのエントリポイントが正確にどこにあるかを誰かが教えてくれれば。モデルバインダーと関係ありますか?「送信」ボタンを押すと、渡される値を正確に確認したかったためです。ありがとうございました。

4

1 に答える 1

1

一般的に言えば、すべての検証は、バインダーにバインドされた値の後に行われます。ご存じのとおり、"asdvfvk" のような文字列から dateTime 値をバインドすることはできません。したがって、バインダーがそのようなエラーに遭遇すると、それを ModelState に追加し (ModelState["DateOfBirth"].Errors[0].ErrorMessage を見てください)、デフォルト値をバインドします。DateTime のデフォルト値? は null であるため、常に IsValid メソッドで取得します。それは正常です。たとえば、他の日付よりも大きいかどうかを確認したい場合は、日付の検証に意味があります。入力文字列が正しくない場合、それ以上の検証は意味がありません。

あなたは何ができますか?

最初の簡単な方法-このようにアクションを修正できます

 [HttpPost]
        public ActionResult About(Person person, string dateOfBirth) {
            var birthdayAttribute = new BirthdayAttribute();
            if( !birthdayAttribute.IsValid(dateOfBirth)) {
                ModelState["DateOfBirth"].Errors.Clear();
                ModelState.AddModelError("DateOfBirth", birthdayAttribute.ErrorMessage);
            }
           .......
        }

ご覧のとおり、文字列 dateOfBirth があるため、バインダーは文字列値のバインドに問題はありません。しかし、これではユーザーは満足しません。

より良い方法 - 文字列がクライアント Javascript で正しい形式であることを確認してください。実際、人々は日付に日付ピッカー コントロールを使用しており、気分が良いと感じています。

さらに、ここhttp://forums.asp.net/t/1512140.aspx 特にブラッド・ウィルソンの答えを見てください。

于 2010-04-25T18:12:22.450 に答える