validation - Conditionally require all fields in class depending on property -
i have address class, used 2 properties - mailingaddress , streetaddress.
how can make streetaddress required , mailingaddress not?
public address mailingaddress { get; set; } [required(errormessage = "address, city, state, , zip code required.")] public address streetaddress { get; set; } public class address { [displayname("address")] public string streetaddress { get; set; } [displayname("city")] public string city { get; set; } [displayname("state")] public string selectedstate { get; set; } [datatype(datatype.postalcode)] [regularexpression(@"^\d{5}$|^\d{5}-\d{4}$", errormessage="the postal code should in format 00000 or 00000-0000")] [displayname("zip")] public string zip { get; set; } }
i treat them little differently. propose have 2 different address models , put them single viewmodel.
let's take address
class , give virtual
keywords can override class properties.
public class address { [displayname("address")] public virtual string streetaddress { get; set; } [displayname("city")] public virtual string city { get; set; } [displayname("state")] public virtual string selectedstate { get; set; } [datatype(datatype.postalcode)] [regularexpression(@"^\d{5}$|^\d{5}-\d{4}$", errormessage="the postal code should in format 00000 or 00000-0000")] [displayname("zip")] public virtual string zip { get; set; } }
now let's create new model inherits our address class.
public class mandatoryaddress : address { [required] public override string streetaddress { get; set; } [required] public override string city { get; set; } [required] public override string selectedstate { get; set; } [required] public override string zip { get; set; } }
now let's create our viewmodel
public class myformviewmodel { public mandatoryaddress streetaddress { get; set; } public address mailingaddress { get; set; } }
a view might this
@{ viewbag.title = "my sample form"; } @model testapp.models.myformviewmodel <h2>@viewbag.title</h2> @using (html.beginform()) { <fieldset> <legend>street address</legend> <div> @html.labelfor(x => x.streetaddress.streetaddress) @html.editorfor(x => x.streetaddress.streetaddress) @html.validationmessagefor(x => x.streetaddress.streetaddress) </div> <div> @html.labelfor(x => x.streetaddress.city) @html.editorfor(x => x.streetaddress.city) @html.validationmessagefor(x => x.streetaddress.city) </div> <div> @html.labelfor(x => x.streetaddress.selectedstate) @html.editorfor(x => x.streetaddress.selectedstate) @html.validationmessagefor(x => x.streetaddress.selectedstate) </div> <div> @html.labelfor(x => x.streetaddress.zip) @html.editorfor(x => x.streetaddress.zip) @html.validationmessagefor(x => x.streetaddress.zip) </div> </fieldset> <fieldset> <legend>mailing address</legend> <div> @html.labelfor(x => x.mailingaddress.streetaddress) @html.editorfor(x => x.mailingaddress.streetaddress) @html.validationmessagefor(x => x.mailingaddress.streetaddress) </div> <div> @html.labelfor(x => x.mailingaddress.city) @html.editorfor(x => x.mailingaddress.city) @html.validationmessagefor(x => x.mailingaddress.city) </div> <div> @html.labelfor(x => x.mailingaddress.selectedstate) @html.editorfor(x => x.mailingaddress.selectedstate) @html.validationmessagefor(x => x.mailingaddress.selectedstate) </div> <div> @html.labelfor(x => x.mailingaddress.zip) @html.editorfor(x => x.mailingaddress.zip) @html.validationmessagefor(x => x.mailingaddress.zip) </div> </fieldset> <div> <input type="submit" /> </div> }
a controller might this:
public class formcontroller : controller { // // get: /form/ [httpget] public actionresult index() { myformviewmodel viewmodel = new myformviewmodel(); return view(viewmodel); } [httppost] public actionresult index(myformviewmodel viewmodel) { return view(viewmodel); } }
bonus experience points:
an alternative way (more complex arguably 'better') create own custom [required]
attribute can apply class (i.e. streetaddress
). attribute have go through each property of class , apply [required]
attribute.
Comments
Post a Comment