0

实际上不确定如何表达我的问题。

我在我的大部分屏幕中都使用 jqgrid(不确定在这种情况下是否相关信息),我在添加/编辑模式上有两个日期时间选择器。我一直在使用这个日期时间选择器组件,它运行良好,除了我发现人们不喜欢使用滑块来捕捉时间,尤其是如果它需要经常输入。

随之而来的是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);}

我的添加方法。

  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)
        {
           ...
        }

    }

我注意到的是视图模型是有效的并且包含日期时间格式的值,但是当我尝试从数据库更新我的模型时,它会失败并显示以下消息。

*从类型“System.String”到类型“..Portal.Models.Down_Time_Capture”的参数转换失败,因为没有类型转换器可以在这些类型之间进行转换。*

我已经尝试在我的 javascript/jquery 中将值转换为日期格式,并将其附加到我的日期输入字段......但它仍然将其作为字符串提交

如果需要,我会提供任何其他信息,但这是一个奇怪的信息:/

更新:

我的视图只包含 jqgrid 组件的 html。我在下面添加了一个 jsfiddle 链接。

链接到 JsFiddle - 包括两个日期选择器的代码

4

2 回答 2

1

Ended up changing my controller methods.

I'd like to attempt to use generics and make it... uhm. generic. but its a completely new question on its own.

        [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 Helper Code

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,是吗?在这种情况下,你正在做双倍的工作)。

首先让我们尝试清理一下您的操作:

  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 回答