0

私の質問の言い回しが実際にはわかりません。

私はほとんどの画面でjqgridを使用しています(この場合、関連情報があるかどうかはわかりません)。Iv'eは、追加/編集モーダルに2つの日時ピッカーを持っています。私はこの日時ピッカーコンポーネントを使用してきましたが、これはうまく機能しましたが、スライダーを使用して時間をキャプチャするのが好きではないことがわかりました。特に、頻繁に入力する必要がある場合はそうです。

will_pickdateコンポーネントが登場しました。これは、非常に明るい:Pですが、エンドユーザーの祈りに答えているようです(他のオプションは、独自のコンポーネントを作成することでしたが、今はスキップします)

保存しようとすると問題が発生します。will_pickdateコンポーネントは、日時の値をテキストとして送信しているか、TryUpdateModelメソッドを呼び出したときに正しくマッピングされていないようです。

クライアントサイドコード

      function CreateDateTimePicker(elem, ShowOn, OnClose) {

        setTimeout(function () {
    //code that works
            $(elem).datetimepicker({
                dateFormat: 'yy/mm/dd',
                timeFormat: 'hh:mm',
                showOn: ShowOn,
                buttonImageOnly: true,
                buttonImage: "/Images/date_time.jpg",
                changeYear: true,
                changeMonth: true,
                showButtonPanel: true,
                showWeek: true,
                onClose: function (dateText, inst) {
                    if (OnClose != null)
                        OnClose(dateText, inst);

                    $(this).focus();
                }
            }).attr('size', '16').next('img.ui-datepicker-trigger')
            .attr("tabIndex", "-1").css({ 'cursor': 'pointer', 'vertical-align': 'middle', 'padding-left': '3px', 'padding-bottom': '4px' });

//new code that sort of works.. eg component renders fine, but fails server side
            //$(elem).will_pickdate({
            //    timePicker: true,
            //    format: 'Y/m/d H:i',
            //    inputOutputFormat: 'Y/m/d H:i',
            //    militaryTime: true,
            //    allowEmpty: true,
            //    startView:'day',
            //    onSelect: function (date) {

            //        if (OnClose != null)
            //            OnClose();

            //        $(this).focus();


            //      //  $('#' + display[0].id).val(new Date($(elem).val()));
            //   //     $('#' + display[0].id+ '_display').val(new Date($(elem).val()));
            //       // alert($('#' + display[0].id).val());
            //    }
            //});

        }, 100);}

私のaddメソッド。

  public ActionResult Edit(Down_Time_Capture viewModel, FormCollection formCollection)
    {
        Down_Time_CaptureRepository repository = new Down_Time_CaptureRepository();

        try
        {
            if (!ModelState.IsValid)
                return ReturnValidationFailure(ViewData.ModelState.Values);

            int item_id = Convert.ToInt32(formCollection["id"]);

            var model = repository.Where(o => o.DTCP_ID == item_id).SingleOrDefault();

            if (model == null)
            {
                //append any error code to allow jqgrid modal to handle error display
                Response.StatusCode = 400;
                return Json("Record not found.", JsonRequestBehavior.AllowGet);
            }               

    ====>   //code fails here, model tries to get updated but dies
            if (TryUpdateModel(model, formCollection.ToValueProvider()))
            {
                repository.Edit(model, User.Identity.Name);
                repository.Save();
                return Json("Updated successfully.", JsonRequestBehavior.AllowGet);
            }
            else
            {
                return ReturnValidationFailure(ViewData.ModelState.Values);
            }
        }
        catch (Exception ex)
        {
           ...
        }

    }

Iv'eが気付いたのは、ビューモデルが有効であり、日時形式の値が含まれていることですが、データベースからモデルを更新しようとすると、次のメッセージが表示されて失敗します。

*タイプ'System.String'からタイプ'..Portal.Models.Down_Time_Capture'へのパラメーター変換は、タイプコンバーターがこれらのタイプ間で変換できないため失敗しました。*

javascript / jqueryで値を日付形式に変換し、それを日付入力フィールドに追加しようとしましたが、それでも文字列として送信されます

必要に応じて他の情報を提供しますが、これは奇妙な情報です:/

アップデート:

私のビューには、jqgridコンポーネントのhtmlのみが含まれています。以下にjsfiddleリンクを追加しました。

JsFiddleへのリンク-両方の日付ピッカーのコードが含まれています

4

2 に答える 2

1

コントローラーのメソッドを変更することになりました。

ジェネリックを使って作りたいのですが…うーん。ジェネリック。しかし、それ自体はまったく新しい質問です。

        [HttpPost]
        [AuthorizeAD]
        public ActionResult Edit(long id, VM_Down_Time_Capture viewModel)
        {
            using (Down_Time_CaptureRepository repository = new Down_Time_CaptureRepository())
            {
                //checks to see if data is valid
                if (!ModelState.IsValid)
                    return ReturnValidationFailure(ViewData.ModelState.Values);

                //find model to update
                var model = repository.Where(o => o.DTCP_ID == id).SingleOrDefault();

                if (model == null)
                    RecordNotFoundError();

                //update model using value injector
                model.InjectFrom(new Me().Ignore(new[] { "DTCP_ID" }), viewModel).InjectFrom<StringToDate>(viewModel);

                //perform edit
                string mserMsg = repository.Edit(model, User.Identity.Name);

                //notify user of any errors/notifications
                if (!string.IsNullOrEmpty(mserMsg))
                    return ReturnCustomValidationFailure(Server.HtmlEncode(mserMsg));

                //apply changes to db
                repository.Save();
                return Json("Updated successfully.", JsonRequestBehavior.AllowGet);
            }
        }

ValueInjectorヘルパーコード

public class StringToDate : LoopValueInjection
    {
        //by default is sourceType == targetType; override to change behaviour
        protected override bool TypesMatch(Type sourceType, Type targetType)
        {
            return sourceType == typeof(string)
                   && targetType == typeof(DateTime);
        }

        //by default is return sourcePropertyValue; override to change behaviour 
        protected override object SetValue(object sourcePropertyValue)
        {                
            return DateTime.Parse(sourcePropertyValue.ToString());
        }
    }

    public class Me : LoopValueInjection
    {
        private string[] ignore;

        public Me Ignore(string[] ignore)
        {
            this.ignore = ignore;
            return this;
        }

        protected override bool UseSourceProp(string sourcePropName)
        {
            return !ignore.Contains(sourcePropName);
        }
    }
于 2012-05-09T20:17:22.077 に答える
1

通常、ビューモデルアプローチを使用する場合は、マッパー(Automapperなど)を使用して、キャプチャされた値をビューモデルから永続化されたオブジェクトに移動します。あなたがしているのは、MVCにキャプチャされた値をビューモデルにバインドさせることです。次に、基本的にDown_Time_Captureインスタンスを破棄し、フォームからDown_Time_CaptureRepositoryによって返されるタイプにバインドします(Down_Time_Captureではありませんか?)。その場合、2倍の作業を行っています)。

まず、アクションを少しクリーンアップしてみましょう。

  public ActionResult Edit(int id)
    {
        Down_Time_CaptureRepository repository = new Down_Time_CaptureRepository();

        var model = repository.Where(o => i.DTCP_ID == id).SingleOrDefault();

        if (model == null)
            {
                //append any error code to allow jqgrid modal to handle error display
                Response.StatusCode = 400;
                return Json("Record not found.", JsonRequestBehavior.AllowGet);
            }  


            if (TryUpdateModel(model))
            {
                repository.Edit(model, User.Identity.Name);
                repository.Save();
                return Json("Updated successfully.", JsonRequestBehavior.AllowGet);
            }

            return ReturnValidationFailure(ViewData.ModelState.Values);
    }

このwill_pickdateコンポーネントは、DateTime値を有効に送信しているようです(値は文字列としてネットワーク経由で送信され、フォームフィールドの名前がバインドされているモデルのプロパティ名と一致すると、MVCのバインダーが値をDateTimeに変換します) 。

于 2012-05-09T09:06:17.260 に答える