asp.net - Predefine entity values on creation -


i have following model classes related one-to-many relationship. classes persisted sql server database via code first approach:

public class topic {     [key]     public int id { get; set; }      [inverseproperty("topic")]     public virtual ilist<chapter> chapters { get; set; }      //some other properties... }  public class chapter : ivalidatableobject {     [key]     public int id { get; set; }      [required]     public string key { get; set }      public virtual topic topic { get; set; }      //some other properties... } 

each topic contains bunch of chapters. each chapter has key must unique within topic.

i trying validate following method:

public ienumerable<validationresult> validate(validationcontext validationcontext) {       var chapterswithsamekey = topic.chapters.where(t => t.key == key);     foreach (var item in chapterswithsamekey)     {         if (item.id != id)         {             yield return new validationresult("the key must unique.", new string[] { "key" });             break;         }     }             } 

however, topic null when validation occurs after posting create or edit action. seems reasonable because views contain no information topic. however, can extract topic in controller because topic's id part of url.

my first attempt set topic right @ beginning of post create action in controller:

[httppost] public actionresult create(int topicid, chapter chapter) {     var topic = db.topics.find(topicid);     if (topic == null)         return httpnotfound();     chapter.topic = topic;     if(modelstate.isvalid)         ... } 

however, chapter's validate method called before controller can anything. therefore, chapter's topic again null.

another approach tell create view topic belongs by:

[httpget] public actionresult create(int topicid) {     var topic = ...     var newchapter = new chapter() { topic = topic };     return view(newchapter); } 

and set hidden field in view:

@html.hiddenfor(model => model.topic) @html.hiddenfor(model => model.topic.id) 

the first 1 gives null topic before. seems natural because rendered hidden field's value topic's tostring() result.

the second 1 seemingly tries validate topic, fails because there missing properties. actual reason nullreferenceexception when read-only property of topic tries evaluate null property. have no clue why read-only property accessed @ all. call stack has validate... methods.

so best solution above scenario? i'm trying validation in model, necessary values missing retrieved in controller.

i create view model task contains int topicid instead of topic topic. have copy every property , annotation view model or via inheritance. first approach seems quite inefficient.

so inheritance method best option. there other options not come need introduce additional type?

first, have realize validation (then validate() method) performed modelbinder, before action executes.

second, argue main problem aren't using viewmodel rather return entity/model view , controller.

your views have different responsibilities , concerns models/entities (just in case). different data structure, different validation rules , importantly, shape viewmodel object accommodate exact page/view needs.

your current validate() method seem suit data-layer validation needs, not views validation needs.

try this:

public class createchapterviewmodel : ivalidatableobject {     public int id { get; set; }  // possible not needed 'create' flow     public string key { get; set }      public ienumerable<validationresult> validate(validationcontext validationcontext)     {            // validation logic applies chapter creation only, example:          // if (this.key == null) ...     } } 

then in action:

[httppost] public actionresult create(int topicid, createchapterviewmodel chapter) {      ... } 

to summarize, don't try force entities on views, have different needs, feed them viewmodels , let them send viewmodels well.

the trade-off approach you'll have map entities viewmodels , back, either create own mappers or use automapper.


Comments

Popular posts from this blog

Unable to remove the www from url on https using .htaccess -