I *would like* to use things like DataAnnotaitons for the reasons that they solve duplicaiton of validation (eg at DB when using EF and UI with (some parts of) MVC) but I'm having issues with some of the databinding/modelbinding stuff.
eg: qty and value are settable by user but when the model binder creates the model it does it in such an order that the value is always 0...
(a possible/probable answer to this is "custom model binder"... which I'm avoiding like the plague, but maybe you can convince me this isn't as bad an idea as I think it sounds...)
The code is along these lines:
get "Value": return _value; get "Quantity": return _value / _packageType.unitvalue;
set "Value": _value = Value; set "Quantity": _value = Value * _packageType.unitvalue;
With hte complex heirachies of the modesl you create if you are using POCO and EF then often something that is dependant on something else, like _packageType in above code example, is often "null" when (or while) the model binding is done, and so can fail
when "setting quantity" because the "value of that quantity" is not able to be determined yet...
Just want to know how "we are supposed to be working with this stuff"?
Is the idea to make your POCOs 100% stupid and litterally just datastructures with decorations?
Should I NOT be including helpful things like "quantity" that are self determining on the POCOs? (ie NO logic at all in data/model classes?) Should I perhaps have extensions or helper classes that can do "quantity to value" conversions and use them to set
the "dumb" POCOs?
This must be a common "thing" so how are you supposed to go from things like "value, package type, quantity" in a line item thing into something versatile that you can use around your MVC app without having to create 14 different models for each unique way
you want to display a given data/model?
OR... are the use of POCOs across all layers still a bit of a pipe dream and we should still be creating DATA classes with validation separate to the UI validation and not be shooting for the reuse that tools like MVC and EF promise with their reuse of DataAnnotations
to define both the model and the validation rules?!
Opinions expressed are mine alone...
Unless I cut and pasted them from somewhere...or my wife told me to have them...
view models should hold the data that passes between the controller and view and back to the controller. all data from the view to the controller must be in a form field element as a simple string. on postback the data is sent as a collection of name/value
strings (if its a json post, the json is converted to name/value string collection before being sent to the binder).
the view models should be simple POCO objects that the binder can create and update. as all the data in the view can be manipated by the user, it should not contains keys or data the user is not allowed to change (becuase a hacker can change the data before
post). if you need to send keys to the view, they should be encrypted first.
on postback the binder fills in the view model. you can then use the view model to update the data model. in applications where the database is just session data to support it (ROR model), like say a shopping cart (but not the the purchase/inventory system),
POCO entity objects can be used as the view model.
bruce (sqlwork.com)
Marked as answer by smerlon on Feb 02, 2013 12:29 PM
Not "confusing" them as such, I understand the "concept", but was under the impression you could use them for both when taking advantage of tools such as EF4 "CodeFirst" approach, however, you final paragraph indicates that this is "only for use in its simplest
form"...
So, just to clarify, am I to take it that in essence the "[Required, StringLength(3,MinimumLength=3)]" integration between validation and entity definition (where the preceding decoration will allow EF to define a database field that is "char(3)" but also
for MVC framework to tell the user "<fieldname> must be 3 characters in length" (or whatever it says) is pretty much a pipe dream for all but the most basic of scenarios?
And as an extension of this that putting this kind of thing (System.ComponentModel/System.ComponentModel.DataAnnotations):
on your DATA models is useless - since EF4 (afaik) doesn't support it and if you aren't using the POCO (ie I will have to create a VIEW model to do the "display" stuff) in the UI then it will not have any formatting effect...?
Is there a blog or something that outlines what's worthwhile using in the "Data/View" models/layers (in terms of annotations)?
Because, its not like they are in distinct namespaces or anything - the implication that I drew from namespaces was that they were trying to unify them so that they will be the same across all "layers" (and further inferred that they were intended to be
used to reduce the amount of duplication).
*A lot of the (EF) doco/tutorials talk about DRY and how this is achievable via data annotations (when used with MVC) - sounds like this is marketing BS if it doesn't really work in "real world" scenarios... are they just doing this for "simplicity" in the
examples? If so I wish they would mention it... eg: "This sounds great, but you can't really take advantage of it in a properly architectured scenario"... :)
Opinions expressed are mine alone...
Unless I cut and pasted them from somewhere...or my wife told me to have them...
Okay the pros and cons aside, it looks like there is no really sensible way to start a project with any level of complexity and have the entities be DRY across all layers...
So what I'm thinking is to do this:
split the existing "many annotated" POCOs into
Data layer => bunch of classes that will be the Entities. and will have things like [Required, String(3,3)]
service layer => bunch of classes that are almost identical to the above, but may have annotations like [Required, String(3,3)] if they will be the Domain models and used as (simple?) DTOs in the ViewModels.
UI layer => bunch of classes that are view specific, sometimes containing the service layer objs as elements as they are returned by the service. and these will all have things like [Required, String(3,3)] as well as [DisplayFormatString()] type of annotations
as requried for display and validation.
Probably gonna need to share some kind of "vlaidation class" to add custom validaitons to both the viewmodels and entity classes... that'll probably get messy tho...
Write lots of code that copies fields and properties back and forth between objects at the different layers.
Is that how you are supposed to do it?
Along these lines, I have the follow up (related? need new thread?) question does the [DataType(DataType.Date)] in the below code actually do anything?! I can't see/know which "layer" it applies to... it doesn't appear to do anything interesting
like "ditch" the time or complain if there is a non-zero time passed... is it a future proofing thing that doesn't do anything yet, or is there some purpose to it?
[DataType(DataType.Date)]
public System.DateTime PlannedPickupDate { get; set; }
Opinions expressed are mine alone...
Unless I cut and pasted them from somewhere...or my wife told me to have them...
Because, while (I think) they are saying pretty much the same thing as you are (maybe!?), I grok'd it better... they basically outlined more that I was falling over the DRY stuff rather than the "different" models theory (which perhaps in your mind are the
same thing, but to me I 'got' the different models thing, but I was falling over the DataAnnotations bit... essentially I was thinking I was doing something wrong by not being able to get the "DataAnnotations" to ONLY live in one place (DRY to my way of thinking)...
I appreciated your input tho, but it didn't help me 'grok' it specifically, I do think you are right so will mark as answer (along with this for future readers).
Opinions expressed are mine alone...
Unless I cut and pasted them from somewhere...or my wife told me to have them...
Marked as answer by smerlon on Feb 02, 2013 12:29 PM
smerlon
Member
13 Points
38 Posts
MVC and DataAnnotations
Jan 23, 2013 01:38 AM|LINK
Hi all,
I *would like* to use things like DataAnnotaitons for the reasons that they solve duplicaiton of validation (eg at DB when using EF and UI with (some parts of) MVC) but I'm having issues with some of the databinding/modelbinding stuff.
eg: qty and value are settable by user but when the model binder creates the model it does it in such an order that the value is always 0...
(a possible/probable answer to this is "custom model binder"... which I'm avoiding like the plague, but maybe you can convince me this isn't as bad an idea as I think it sounds...)
The code is along these lines:
get "Value": return _value;
get "Quantity": return _value / _packageType.unitvalue;
set "Value": _value = Value;
set "Quantity": _value = Value * _packageType.unitvalue;
With hte complex heirachies of the modesl you create if you are using POCO and EF then often something that is dependant on something else, like _packageType in above code example, is often "null" when (or while) the model binding is done, and so can fail when "setting quantity" because the "value of that quantity" is not able to be determined yet...
Just want to know how "we are supposed to be working with this stuff"?
Is the idea to make your POCOs 100% stupid and litterally just datastructures with decorations?
Should I NOT be including helpful things like "quantity" that are self determining on the POCOs? (ie NO logic at all in data/model classes?) Should I perhaps have extensions or helper classes that can do "quantity to value" conversions and use them to set the "dumb" POCOs?
This must be a common "thing" so how are you supposed to go from things like "value, package type, quantity" in a line item thing into something versatile that you can use around your MVC app without having to create 14 different models for each unique way you want to display a given data/model?
OR... are the use of POCOs across all layers still a bit of a pipe dream and we should still be creating DATA classes with validation separate to the UI validation and not be shooting for the reuse that tools like MVC and EF promise with their reuse of DataAnnotations to define both the model and the validation rules?!
Unless I cut and pasted them from somewhere...or my wife told me to have them...
bruce (sqlwo...
All-Star
37626 Points
5574 Posts
Re: MVC and DataAnnotations
Jan 23, 2013 02:11 AM|LINK
you are confusing view models with data models.
view models should hold the data that passes between the controller and view and back to the controller. all data from the view to the controller must be in a form field element as a simple string. on postback the data is sent as a collection of name/value strings (if its a json post, the json is converted to name/value string collection before being sent to the binder).
the view models should be simple POCO objects that the binder can create and update. as all the data in the view can be manipated by the user, it should not contains keys or data the user is not allowed to change (becuase a hacker can change the data before post). if you need to send keys to the view, they should be encrypted first.
on postback the binder fills in the view model. you can then use the view model to update the data model. in applications where the database is just session data to support it (ROR model), like say a shopping cart (but not the the purchase/inventory system), POCO entity objects can be used as the view model.
smerlon
Member
13 Points
38 Posts
Re: MVC and DataAnnotations
Jan 23, 2013 03:46 AM|LINK
Hi Bruce,
Not "confusing" them as such, I understand the "concept", but was under the impression you could use them for both when taking advantage of tools such as EF4 "CodeFirst" approach, however, you final paragraph indicates that this is "only for use in its simplest form"...
So, just to clarify, am I to take it that in essence the "[Required, StringLength(3,MinimumLength=3)]" integration between validation and entity definition (where the preceding decoration will allow EF to define a database field that is "char(3)" but also for MVC framework to tell the user "<fieldname> must be 3 characters in length" (or whatever it says) is pretty much a pipe dream for all but the most basic of scenarios?
And as an extension of this that putting this kind of thing (System.ComponentModel/System.ComponentModel.DataAnnotations):
[Display(Name = "Requested Delivery Date"), DataType(DataType.Date)]
on your DATA models is useless - since EF4 (afaik) doesn't support it and if you aren't using the POCO (ie I will have to create a VIEW model to do the "display" stuff) in the UI then it will not have any formatting effect...?
Is there a blog or something that outlines what's worthwhile using in the "Data/View" models/layers (in terms of annotations)?
Because, its not like they are in distinct namespaces or anything - the implication that I drew from namespaces was that they were trying to unify them so that they will be the same across all "layers" (and further inferred that they were intended to be used to reduce the amount of duplication).
*A lot of the (EF) doco/tutorials talk about DRY and how this is achievable via data annotations (when used with MVC) - sounds like this is marketing BS if it doesn't really work in "real world" scenarios... are they just doing this for "simplicity" in the examples? If so I wish they would mention it... eg: "This sounds great, but you can't really take advantage of it in a properly architectured scenario"... :)
Unless I cut and pasted them from somewhere...or my wife told me to have them...
smerlon
Member
13 Points
38 Posts
Re: MVC and DataAnnotations
Jan 24, 2013 03:52 AM|LINK
Okay the pros and cons aside, it looks like there is no really sensible way to start a project with any level of complexity and have the entities be DRY across all layers...
So what I'm thinking is to do this:
split the existing "many annotated" POCOs into
Data layer => bunch of classes that will be the Entities. and will have things like [Required, String(3,3)]
service layer => bunch of classes that are almost identical to the above, but may have annotations like [Required, String(3,3)] if they will be the Domain models and used as (simple?) DTOs in the ViewModels.
UI layer => bunch of classes that are view specific, sometimes containing the service layer objs as elements as they are returned by the service. and these will all have things like [Required, String(3,3)] as well as [DisplayFormatString()] type of annotations as requried for display and validation.
Probably gonna need to share some kind of "vlaidation class" to add custom validaitons to both the viewmodels and entity classes... that'll probably get messy tho...
Write lots of code that copies fields and properties back and forth between objects at the different layers.
Is that how you are supposed to do it?
Along these lines, I have the follow up (related? need new thread?) question does the [DataType(DataType.Date)] in the below code actually do anything?! I can't see/know which "layer" it applies to... it doesn't appear to do anything interesting like "ditch" the time or complain if there is a non-zero time passed... is it a future proofing thing that doesn't do anything yet, or is there some purpose to it?
[DataType(DataType.Date)]
public System.DateTime PlannedPickupDate { get; set; }
Unless I cut and pasted them from somewhere...or my wife told me to have them...
smerlon
Member
13 Points
38 Posts
Re: MVC and DataAnnotations
Feb 02, 2013 12:29 PM|LINK
While I think your answer is right, I think that really the "true answer" is more over here:
http://forums.asp.net/t/1879462.aspx/1?EntityModel+DomainModels+ViewModels+DRY+vs+Separation+of+Concerns+Where+is+the+line+in+the+sand+
Because, while (I think) they are saying pretty much the same thing as you are (maybe!?), I grok'd it better... they basically outlined more that I was falling over the DRY stuff rather than the "different" models theory (which perhaps in your mind are the same thing, but to me I 'got' the different models thing, but I was falling over the DataAnnotations bit... essentially I was thinking I was doing something wrong by not being able to get the "DataAnnotations" to ONLY live in one place (DRY to my way of thinking)...
I appreciated your input tho, but it didn't help me 'grok' it specifically, I do think you are right so will mark as answer (along with this for future readers).
Unless I cut and pasted them from somewhere...or my wife told me to have them...