0

データベースの最初のアプローチから、変更できないテーブルから生成された DateTime フィールド内の時間のみを編集しようとしています (したがって、SQL の日時から別のものに変更することは問題外です)。私が抱えている問題は、日付も含めない限り、ボックスにあるものは有効な日付ではないとバリデーターが言い続けることです。

これが私がこれまでに持っているものです:

モデル:

[DisplayName("Time")]
[DisplayFormat(DataFormatString = "{0:h:mm tt}", ApplyFormatInEditMode = true)]
public System.DateTime PrintTime { get; set; }

意見:

    <div class="editor-field">
        @Html.EditorFor(model => model.PrintTime)
        @Html.ValidationMessageFor(model => model.PrintTime)
    </div>

ModelBinder を試してみましたが、カスタム検証属性 (どちらも正常にコンパイルされ、ここから取得されたもの) を使用してみましたが、これらのソリューションを使用しても、検証で得られるエラーは次のとおりです。

「フィールド時間は日付でなければなりません」

jquery が過去に取得できない日付要件を持つ可能性を示す他のスレッドを見てきました (スレッドが解決策を提案している限り)、検証を完全に無効にする解決策があるようです。明らかに、検証を維持したいと思います (他のすべてに対しては正常に機能します)。

それで、これを修正するにはどうすればよいですか?

4

1 に答える 1

1

これを回避策で解決しました。最初に、データベースにない文字列をモデルに追加し、次にいくつかのメソッドをモデルに追加しました。データベースからモデルを更新すると問題が発生するため、注意してください。

モデルに追加されたものは次のとおりです。

    [DisplayName("Daily Print Time")]
    [RegularExpression("^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9][\\s]*[apAP][mM][\\s]*", ErrorMessage="Invalid Time Format")]
    [Required]
    public string sPrintTime { get; set; }
    [DisplayName("Daily Print Time")]
    [DisplayFormat(DataFormatString = "{0:h:mm tt}", ApplyFormatInEditMode = true)]
    [Required]
    public System.DateTime PrintTime { get; set; }

方法:

    public void UpdatePrintTime()
    {
        //This is a workaround to get past jquery validation errors when
        //attempting to edit a DateTime value directly with just a time string.
        DateTime dt = DateTime.MinValue;
        DateTime.TryParse("12/30/1899 " + sPrintTime.ToUpper(), out dt);
        if (dt != DateTime.MinValue)
        {
            PrintTime = dt;
        }
    }
    public void UpdatePrintString()
    {
        sPrintTime = PrintTime.ToString("h:mm tt");
    }

正規表現の検証は完全ではありません (たとえば、「23:59 am」と入力することはできますが、メソッド UpdatePrintTime() は TryParse() でそれを処理します)。

次に、Edit.cshtml ファイルを次のように更新しました。

@Html.HiddenFor(model => model.PrintTime)

フィールドの欠落による実行時エラーを回避するために、上記の行を追加する必要がありました

<div class="editor-field">
    @Html.EditorFor(model => model.sPrintTime)
    @Html.ValidationMessageFor(model => model.sPrintTime)
</div>

また、Create.cshtml ファイルを上記の <div> で更新する必要がありました。注: 追加したメソッドのため、非表示の PrintTime フィールドは含めませんでした。これは、コントローラー アクションの Edit および Create で次のように使用します。

    [HttpPost]
    public ActionResult Create(PrintJob printjob)
    {
        if (ModelState.IsValid)
        {
            printjob.UpdatePrintTime();
            db.PrintJobs.Add(printjob);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ...
        return View(printjob);
    }

    public ActionResult Edit(int id = 0)
    {
        PrintJob printjob = db.PrintJobs.Find(id);
        if (printjob == null)
        {
            return HttpNotFound();
        }
        printjob.UpdatePrintString();
        ...
        return View(printjob);
    }

    [HttpPost]
    public ActionResult Edit(PrintJob printjob)
    {
        if (ModelState.IsValid)
        {
            printjob.UpdatePrintTime();
            db.Entry(printjob).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        printjob.UpdatePrintString();
        ...
        return View(printjob);
    }

これを機能させるには、これらすべてが必要でした。何か間違ったことを入力しようとすると、別の検証エラーが発生し、検証に合格したとしても、入力された内容を再確認します。クライアント側の検証に合格するが、TryParse() に合格しない場合、編集モードの場合、時刻はそのままになります。作成モードの場合、例外がスローされます。

したがって、2 つの欠陥は、1) 検証が TryParse() と一致しないため、2) 例外を引き起こす不正な時間文字列をスリップさせる可能性があることです。

それ以外は、これが私が思いついた完全な解決策です。:)

于 2013-02-27T18:43:34.987 に答える