사용자 정의 모델이 바인더를 위한 내부 모델
-
13-11-2019 - |
문제
나는 모델은 다음과 같다:
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);
그 null
에 value
.
나는 확실하지 않을 구현하는 방법을 모형 바인더습니다.
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
도)병합 Time
고 AmPm
속성을 하나 입력 필드에 입력을 필요로하는 사용자 정의 모델이 바인더에서 나중에 순서를 분리 할 때 그들을 양식이 제출되:
@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());
제휴하지 않습니다 StackOverflow