asp.net mvc 3 - Custom model binder for inner model -
asp.net mvc 3 - Custom model binder for inner model -
i got model this:
public class mainmodel { public string id {get;set;} public string title {get;set;} public timepicker timepickerfield {get;set;} }
timepicker
inner model looks this:
public class timepicker { public timespan {get;set;} public ampmenum ampm {get;set;} }
i'm trying create custom model binding inner model: timepicker
the question is: how values in custom model binder submitted in form timepicker
model fields?
if seek this:
var value = bindingcontext.valueprovider.getvalue(bindingcontext.modelname);
i null
in value
.
i'm not sure how implement model binder correctly.
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); seek { //result = duration.parse(value.attemptedvalue); } grab (exception ex) { bindingcontext.modelstate.addmodelerror(bindingcontext.modelname, ex.message); } } homecoming result; } }
the next works me.
model:
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; } }
controller:
public class homecontroller : controller { public actionresult index() { var model = new mainmodel { timepickerfield = new timepicker { time = timespan.fromhours(1), ampm = ampmenum.pm } }; homecoming view(model); } [httppost] public actionresult index(mainmodel model) { homecoming view(model); } }
view (~/views/home/index.cshtml
):
@model mainmodel @using (html.beginform()) { @html.editorfor(x => x.timepickerfield) <button type="submit">ok</button> }
custom editor template (~/views/shared/editortemplates/timepicker.cshtml
) merges time
, ampm
properties single input field , require custom model binder later in order split them when form submitted:
@model timepicker @html.textbox("_picker_", string.format("{0} {1}", model.time, model.ampm))
and model 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) { homecoming null; } var result = new timepicker(); seek { // todo: instead of hardcoding parsing // value.attemptedvalue contain string // entered user homecoming new timepicker { time = timespan.fromhours(2), ampm = ampmenum.pm }; } grab (exception ex) { bindingcontext.modelstate.addmodelerror( bindingcontext.modelname, ex.message ); // of import in order preserve original user // input in case of error when redisplaying view bindingcontext.modelstate.setmodelvalue(key, value); } homecoming result; } }
and register model binder in application_start
:
modelbinders.binders.add(typeof(timepicker), new timepickermodelbinder());
asp.net-mvc-3 asp.net-mvc-2 custom-model-binder custom-binding
Comments
Post a Comment