문제

나는 모델은 다음과 같다:

public class MainModel
{
   public string Id {get;set;}
   public string Title {get;set;}
   public TimePicker TimePickerField {get;set;}
}

TimePicker 내 모델는 다음과 같습니다:

public class TimePicker 
{
   public TimeSpan {get;set;}
   public AmPmEnum AmPm {get;set;}
}

나를 만들려고 사용자 정의 모델이 바인딩에 대한 내부 모델: TimePicker

질문입니다:나는 어떻게 값을 사용자 정의 모델이 바인더는 제출된 형태로 TimePicker 모델 필드?

면 내가 그것을 얻을하려고 다음과 같다:

var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

nullvalue.

나는 확실하지 않을 구현하는 방법을 모형 바인더습니다.

public class TimePickerModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException("bindingContext");
        }
        var result = new TimePicker();

        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (value != null)
        {
            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
            try
            {
                //result = Duration.Parse(value.AttemptedValue);
            }
            catch (Exception ex)
            {
               bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex.Message);
            }
        }    

        return result;
    }
}
도움이 되었습니까?

해결책

다음과 같은 나를 위해 작동 합니다.

모델:

public enum AmPmEnum
{
    Am, 
    Pm
}

public class TimePicker 
{
    public TimeSpan Time { get; set; }
    public AmPmEnum AmPm { get; set; }
}

public class MainModel
{
    public TimePicker TimePickerField { get; set; }
}

컨트롤러:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MainModel
        {
            TimePickerField = new TimePicker
            {
                Time = TimeSpan.FromHours(1),
                AmPm = AmPmEnum.Pm
            }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MainModel model)
    {
        return View(model);
    }
}

View(~/Views/Home/Index.cshtml):

@model MainModel
@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.TimePickerField)
    <button type="submit">OK</button>
}

사용자 지정 편집기 템플릿(~/Views/Shared/EditorTemplates/TimePicker.cshtml 도)병합 TimeAmPm 속성을 하나 입력 필드에 입력을 필요로하는 사용자 정의 모델이 바인더에서 나중에 순서를 분리 할 때 그들을 양식이 제출되:

@model TimePicker
@Html.TextBox("_picker_", string.Format("{0} {1}", Model.Time, Model.AmPm))

모델 binder:

public class TimePickerModelBinder : IModelBinder
{
    public object BindModel(
        ControllerContext controllerContext, 
        ModelBindingContext bindingContext
    )
    {
        var key = bindingContext.ModelName + "._picker_";
        var value = bindingContext.ValueProvider.GetValue(key);
        if (value == null)
        {
            return null;
        }

        var result = new TimePicker();

        try
        {
            // TODO: instead of hardcoding do your parsing
            // from value.AttemptedValue which will contain the string
            // that was entered by the user
            return new TimePicker
            {
                Time = TimeSpan.FromHours(2),
                AmPm = AmPmEnum.Pm
            };
        }
        catch (Exception ex)
        {
            bindingContext.ModelState.AddModelError(
                bindingContext.ModelName, 
                ex.Message
            );
            // This is important in order to preserve the original user
            // input in case of error when redisplaying the view
            bindingContext.ModelState.SetModelValue(key, value);
        }
        return result;
    }
}

마지막으로 등록하는 모델에 바인더 Application_Start:

ModelBinders.Binders.Add(typeof(TimePicker), new TimePickerModelBinder());
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top