Page 19 - MSDN Magazine, March 2019
P. 19

attributes on the Speaker object are displayed in alphabetical order, which doesn’t make a ton of sense. It would be far more realistic (and useful) if the first value displayed was the full name, followed by the individual fields for first name, last name and age (as well as any other demographic information you need to capture and use).
While this could certainly become the “Welp, that was fun, time to break down and build our own UI” moment, it doesn’t need to—this is a common requirement, and NOF has it covered, via the MemberOrder attribute. Using this attribute, I can establish an “order” in which attributes should appear in the UI. So, for exam- ple, if I want the FullName attribute to appear first in the UI, I use MemberOrderandpassintherelativeordinalposition“1,”likeso:
[Title]
[MemberOrder(1)]
public string FullName { get { return FirstName + " " + LastName; } }
Next, I’d like to display first name, last name and age, but here I can begin to run into a problem. As I add new fields to this class over time (say, “middle name” or “email”), trying to keep all the ordinal positions in order can be tricky—if I move LastName to position 5, I have to go find everything 5 (and after) and bump each one to get the right positions. That’s a pain.
Fortunately, MemberOrder has a nifty little trick to it: The position itself can be a floating-point value, which allows fields to be “grouped,” so that now I can mark “FirstName,” “LastName,” and “Age” as ordinal positions “2.1,” “2.2,” and “2.3,” respectively, which essentially means that group “2” can be demographic information, and any new demo- graphic information about the Speaker only requires reshuffling of the members in that particular group, as Figure 1 shows.
Note that there’s nothing really special about the values them- selves—they’re used relative to one another and don’t represent any particular location on the screen. In fact, I could’ve used 10, 21, 22 and 23, if I wanted to. NOF is careful to point out that these values are compared lexicographically—string-based comparisons—and not numerically, so use whichever scheme makes sense to you.
What if users aren’t sure whether Age is in years or in days? It may seem completely obvious to you, but remember, not every- body looks at the world the same way. While it’s probably not a piece of information that needs to be present on the UI overtly, it should be something that you can signal to the user somehow. In NOF, you use the “DescribedAs” attribute to signal how the prop- erty should be described, which typically takes the form of a tooltip over the input area. (Remember, though, a given NOF client might choose to use a different way to signal that; for example, if a NOF
Figure 1 Grouping Fields
client emerges for phones, which are touch-centric, tooltips don’t work well for that format. In that situation, that hypothetical NOF client would use a different mechanism, one more appropriate for that platform, to describe the property.)
And Speakers need a bio! Oh, my, how could I forget that—that’s like the one time speakers get to write exclusively about themselves and all the amazing things they do! (That’s a joke—if it’s one thing speakers hate most of all, it’s writing their own bio.) Bio is an easy attribute to add to the class, but most bios need to be more than just a word or two, and looking at the UI generated by NOF so far, all of the other strings are currently single-line affairs. It’s for this reason that NOF provides the “MultiLine” attribute, to indicate that this field should be displayed in a larger area of text entry than the typical string.
In and of themselves, these attributes act essentially as data model validations, with a small amount of UI to support them.
But I need to be careful about, in this case, a speaker’s biog- raphy, because free-form input offers the possibility for abuse: I might want/need to screen out certain words from appearing lest people get the wrong impression about the conference. I simply can’t have speakers at my show if their biographies include words like COBOL! Fortunately, NOF will allow for validation of input by looking for, and invoking, methods on the Speaker class that match a Validate[Property] convention, like so:
[MemberOrder(4)]
[StringLength(400, ErrorMessage = "Keep bios to under 400 characters, please")] public virtual string Bio { get; set; }
public string ValidateBio(string bio)
{
if (bio.IndexOf("COBOL") > -1)
return "We are terribly sorry; nobody wants to hear that";
else
return "";
Wrapping Up
NOF has a pretty wide variety of options available to describe a domain object in terms that make it easier to automatically render the appropriate UI to enforce domain limitations, but thus far the model here is pretty simple. In the next piece, I’ll examine how NOF can handle a more complicated topic, that of relationships between objects. (Speakers need to be able to specify Topics they speak on, for example, and most of all, the Talks they propose.) But I’m out of space for the month, so in the meantime ... Happy coding! n
Ted Neward is a Seattle-based polytechnology consultant, speaker and mentor. He has written a ton of articles, authored and co-authored a dozen books, and speaks all over the world. Reach him at ted@tedneward.com or read his blog at blogs.tedneward.com.
ThaNks to the following technical expert who reviewed this article: Richard Pawson
}
[MemberOrder(2.1)] [StringLength(100,
ErrorMessage = "First name must be between 1 and 100 characters",
MinimumLength = 1)]
public virtual string FirstName { get; set; }
[MemberOrder(2.2)] [StringLength(100,
ErrorMessage = "Last name must be between 1 and 100 characters",
MinimumLength = 1)]
public virtual string LastName { get; set; }
[Range(13, 90, ErrorMessage = "Age must be between 13 and 90")] [MemberOrder(2.3)]
public virtual int Age { get; set; }
msdnmagazine.com
March 2019 13


































































































   17   18   19   20   21