Sunday, March 12, 2017

WPF/MVVM - Validating ViewModels with IDataErrorInfo and models with annotations

I'm working on a personal WPF/MVVM project where I need validations at both the View Model and Model level.  For business rule validation I decided to implement the IDataErrorInfo interface in my view models.  It works pretty well and it is easy to find examples of how to do it.  However in my case I also have basic validations (like required fields, string length limits, etc.) in Annotations at the model level.  This is necessary because I'm using Entity Framework 6- Code First to generate my database.  The hard part was combining both levels of validation.  Here's how I ended up doing it:

All my model classes inherit from a base class that implements INotifyPropertyChanged and IDataErrorInfo.  OnValidate returns validation errors from the annotations.  Plenty of examples how to do this- just google IDataErrorInfo Annotations.

    public class ModelBase : INotifyPropertyChanged, IDataErrorInfo
    {
        #region " INotifyPropertyChanged "
        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        #region " IDataErrorInfo "
        public string this[string propertyName]
        {
            get
            {
                return OnValidate(propertyName);
            }
        }

        /// <summary>
        /// Validates current instance properties using Data Annotations.
        /// </summary>
        /// <param name=“propertyName”>This instance property to validate.</param>
        /// <returns>Relevant error string on validation failure or <see cref=“System.String.Empty”/> on validation success.</returns>
        private string OnValidate(string propertyName)
        {
            if (string.IsNullOrEmpty(propertyName))
                throw new ArgumentException("Property may not be null or empty", propertyName);

            string error = string.Empty;

            var value = this.GetType().GetProperty(propertyName).GetValue(this, null);
            var results = new List<ValidationResult>();

            var context = new ValidationContext(this, null, null) { MemberName = propertyName };

            var result = Validator.TryValidateProperty(value, context, results);

            if (!result)
            {
                var validationResult = results.First();
                error = validationResult.ErrorMessage;
            }
            return error;
        }

        public string Error
        {
            get
            {
                throw new NotSupportedException("IDataErrorInfo.Error is not supported, use IDataErrorInfo.this[propertyName] instead.");
            }
        }
        #endregion
    }

The implementation in my model classes looks more or less like this:

    public class MyClass: ModelBase
    {
        private string someProperty;
       
        [Required]
        [StringLength(255, ErrorMessage = "Some Property maximum length is 255 characters")]
        public string SomeProperty
        {
            get { return someProperty; }
            set
            {
                if (value == someProperty) return;
                someProperty= value;
                RaisePropertyChanged("SomeProperty");
            }
        }
    }

And then in my view models I also implement IDataErrorInfo.  I first perform the view model validations, then if there are no errors I go to the model's IDataErrorInfo's implementations and check for errors there.  The basic idea came from http://stackoverflow.com/questions/13113779/implementing-idataerrorinfo-in-a-view-model

    public class MyViewModel: IDataErrorInfo
    {
        private MyClass _myClass { get; set; }

        public string SomeProperty
        {
            get { return _myClass.SomeProperty; }
            set
            {
                _myClass.SomeProperty= value;
                RaisePropertyChanged("SomeProperty");
            }
        }

        #region " Implementation of IDataErrorInfo "

        public string Error
        {
            get { throw new NotSupportedException("Not supported"); }
        }

        // Put business rule validation here
        public string this[string propertyName]
        {
            get
            {
                if (propertyName.Equals("SomeProperty"))
                {
                    if (SomeProperty == "FooBar")
                        return "SomeProperty cannot be FooBar.";
                }

                // If we get to here, ViewModel validation passed.  So do the Model validations- 
                return _selectedRacer[propertyName];
            }
        }
    #endregion
    }

And finally, the binding in the view looks like this:

<TextBox Text="{Binding SomeProperty, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}">

Monday, December 19, 2016

Generic List - Inserting item in the proper order

Happy Whatever Holiday You Are Or Soon Will Be Celebrating!  Christmas for me!

Recently I had a requirement to insert a new item in a generic list in the proper order according to two properties in the collection object.  The solution I came up with, with the help of some Googling, is:
  1. From the item to be inserted, combine its values for the two properties into a single string.
  2. Sort the list of generic list of objects in descending order by the the first property, and then the second.
  3. Find the index of the first item whose combined property values are less than the combined values of the item to be inserted.  Add 1 to the index to insert the new item in the next "slot".
  4. If there are no items with a lesser combined value return 0.  I.E. insert the new item first in the list.
Below is a C# method that uses the steps above to return an integer representing the index to insert a new item in to a list according to two property values:
 public static int CalculateInsertIndex(List<ObjectName> listOfObjects, string propertyValue1, string propertyValue2)  
     {  
       var combinedValue = propertyValue1.Trim() + "." + propertyValue2;  
       // Find the row just below where the new item will be inserted  
       var timesheetItemToIndex = listOfObjects  
         .OrderByDescending(t => t.Property1)  
         .ThenByDescending(t => t.Property2)  
         .FirstOrDefault(  
           t => string.Compare((t.Property1.Trim() + "." + t.Property2), combinedValue ,  
                StringComparison.CurrentCultureIgnoreCase) < 0);  
       // Return the index of the next item  
       if (timesheetItemToIndex == null) return 0;  
       return listOfObjects.IndexOf(timesheetItemToIndex ) + 1;  
     }  

Wednesday, September 7, 2016

SharePoint Foundation 2010 - Access denied for users that have full control

We just hired a new web content editor and while setting her up with access to our intranet website I ran into a bizarre permissions problem.  She was granted full control of the site but kept getting access denied on one specific page.

The resolution on this page worked for me- http://underthehood.ironworks.com/2011/05/sharepoint-2010-access-denied-for-users-that-have-full-control-on-the-site.html   However in my case I only granted Full Read to the one user instead of all authenticated users.

Perhaps the two people besides me still using SharePoint Foundation 2010 might find this helpful.  ;)

Monday, May 30, 2016

Visual Studio Live! Austin - Day 4 (Wednesday 5/19/2016)

Finally, a quick rundown of the sessions I attended on the fourth and final day (as best as I can remember):

Role-Based Security Stinks: How to Implement Better Authorization in ASP.NET WebAPI

Great introduction to claims-based authorization, which is apparently going to be the norm in the future.  Is a lot more granular than traditional role-based authorization   Roles are binary- a user is either in the role (and has its inherent rights) or they're not.  With claims a user can be in a role, but only in certain circumstances.  For example, a manager can see personnel information only for her employees, but not everyone in the organization.  Need to learn about Windows Identity Foundation.

DI Why? Getting a Grip on Dependency Injection

Jeremy Clark is a great speaker and I highly recommend attending his sessions if you ever have the chance.  This was a good into to Dependency Injection, which is a design pattern that lets you assign dependency objects at runtime.  I don't really have my head around it, but I realize that I need to because it is very closely related to unit testing.  Jeremy has a Pluralsight course on the subject that I plan on taking as soon as possible.  

User Experience Case Studies - Good and Bad

In the past year or so Billy Hollis has really changed my attitude about UX.  It had never really been my interest or forte- I've been a middleware and database guy most of my career.   But reading/hearing Billy in blogs and podcasts, seeing the WPF applications he has built, and now seeing him live has been very inspirational.  He gave a great overview of US design laws and principles where were new to me, like:

  • Hicks Law- Increasing the number of choices will increase decision time
  • Fits Law- The closer and bigger something is, the easier & faster it is to get to it.

Exceptional Development: Dealing with Exceptions in .NET

There were three great sessions in this time slot: this one, a Billy Hollis talk on building Windows 10 apps, and a Jeremy Clark talk on clean code.  Unfortunately there's only one of me and I chose this one.
Very enlightening- the presenter's recommendations flew in the face of the way I've been handling exceptions most of my career.  Basically, don't bother handling exceptions unless you can recover from them.  For example, if the app needs to send an email but can't connect to the email server, put the email in a queue and try again later.  Otherwise if the exception is bad enough for the app to die, let it die.   However, when exceptions occur a much information about them needs to be captured and logged.  The presenter discussed various ways to do this in WPF (Windows/UWP apps) and web apps.

Windows 10 Design Guideline Essentials

Another case of multiple sessions I really wanted to attended in the same time slot.  I wish some of these would have been Wednesday afternoon where there wouldn't have been as much of a conflict for me.
Most of what was discussed was probably common sense to anyone with a design background, but it as new and interesting to me-

  • group related things to gather visually
  • rounded things look more pleasant
  • larger buttons draw attention
  • less clutter is calming, try to make layouts open and not as crowded


Overall thought about the conference

A massive amount of great information to take in in a short amount of time.  I highly recommend attending if you're in the .NET space. 

Saturday, May 21, 2016

Visual Studio Live! Austin - Day 3 (Wednesday 5/18/2016)

If I ever attend another conference like this I'll blog about it the same day.  It was a lot of information to take in over 4 days and some details are getting lost in the fog.

Angular 2 101

Deborah Kurata, Ms. Angular herself, led off today to a packed house.   Again it was really cool to see in person someone I have been reading about in blogs and hearing about in podcasts for a while.  Angular 2 is meant to be smaller, lighter and faster than Angular 1, and appeared to be in the demos (hopefully in real life as well).  Works with a variety of languages- ES5 and 6 (of interest to me because they are similar to C#), TypeScript, and Dart (which I had never heard of).

Hack Proofing Your Modern Web Applications

Another great session that will be useful immediately.  Not going to say too much until after we, uh, check on some things at work  ;)   The presenter, Adam Tuliper, went over the common attacks, SQL Injection, Cross-Site Scripting, etc. and how the bad guys are using them in today's mobile-enabled world.

General Session: Coding, Composition, and Combinatorics

Billy Hollis is another speaker I was familiar with through podcast interviews, Channel 9, and PluralSight.  He's another fantastic presenter that was a real treat to see in person.He basically challenged all the coders in the room (basically everyone) to think more about design and solving problems in a logical way rather than "throwing code" at problems.  IE. Compose screens that "just work" (from user's job point of view).  Easier said than done for folks like me.  ;)

AngularJS & ASP.NET MVC Playing Nice

Another excellent presentation by Miguel Castro- how to use Angular 1 and MVC in the same app.  Essentially each MVC "page" contains an Angular "s.p.a.".  I can't think of any business cases where we would need to do this at work, but it's nice to know it's possible, albeit messy- especially the routing.  If I remember correctly, by default MVC routing will take precedence over Angular routing.

Angular 2 Forms and Validation

Deborah Kurata presented.  She along with John Papa seem to be the foremost authorities in Angular 2.  The templating story looks really cool, but she made it pretty clear that it's not written in stone yet.    Unfortunately I won't have time to dig into this anytime soon.  Too many other things I need to focus on- XAML, WPF, MVVM, EF6, unit testing, modern design, Dependency Injection...

Acceptance Testing in Visual Studio 2015

Unfortunately this day last session of the day was a disappointment.  Should have gone to ES6 session instead.  About five minutes of the talk was devoted to unit testing, which was useful.  But the rest was very Agile/Scrum-oriented which is not how we do development at work, and tools and services that we don't have with our version of Visual Studio and MS Enterprise License.  I spent most of the session catching up on work and email.

Thursday, May 19, 2016

Visual Studio Live! Austin - Day 2 (Tuesday 5/17/2016)



Another long day crammed with useful and exciting stuff-

Keynote: Visual Studio - Looking Into the Future

Pretty exciting preview of the next version of Visual Studio "15" (different than Visual Studio 2015) and Xamarin.  Very exciting mobile story!  And most amazing that a big muckety muck at Microsoft did his presentation on a MacBook!  Times are a changing.

Developer Productivity in Visual Studio 2015 

Unfortunately, the first breakout session of the day was a bit of a disappointment.  In hindsight I wish I attended the session on ASP.NET Core 1.0 in this time slot.  Not a total loss though.  There are some things about VS2015 that are very compelling, like Diagnostic Tools.  Pretty cool to have real-time information about CPU and memory utilization while in debug mode.  Conditional break points and auto-generated unit test (Intellitest) look very interesting as well.  Really looking forward to upgrading- my current project uses VS2013.

End-to-End Dependency Injection & Writing Testable Software

Lots of great sessions in this time slot and I chose this one.  Great choice!  Miguel Castro is a fantastic presenter!  Highly recommend hearing him speak if you ever get the chance.   In spite of his gruff New Jersey demeanor he's actually very friendly and I've had a few enjoyable chats with him between sessions.  And of course the topic is of great relevance to me and I took away a lot!

My current project at work is the first one that has embraced unit testing in a big way.  I won't say we're going it wrong, but we're definitely doing it the hard way! Using Dependency Injection is way easier than manually creating mock model objects for every model object for every testing scenario as we have been doing it.  DI is a much better way to go and I have some work to do when I get back to the office.  Fortunately there is another session today (Thursday) that focuses on DI.

General Session: JavaScript and the Rise of the New Virtual Machine

Scott Hanselman was the second general session presenter of the day.  As a long time listener of his Hanselminutes podcast it was a real treat to see him speak in person.  Really inspired to learn ES6!  Unfortunately too many other things to learn first. 

Big Data and Hadoop with Azure HDInsight

My motivation for attending this session is an application I inherited at work.  It's simply a tool that aggregates massive amounts of financial data and makes it available for queries and reports.  There are no transactions.  The data is only updated once every quarter.  And the system is slow as molasses.  So it's would be an ideal candidate for conversion to some sort of big data/data warehouse solution.
Hadoop is a big data processing tool and it was neat to learn how it worked.  Unfortunately it has a pretty steep learning curve and the solution presented (HDInsight) appears to be a cloud-only solution.  We're a completely on-prem shop and will be for the foreseeable future.  So I probably won't be able to play in this space anytime soon. 
 

Go Mobile with C#, Visual Studio, and Xamarin

Fantastic session!  James Montemagno was another fantastic inspirational speaker and gave a great presentation about using Xamarin Forms in VS2015 to develop mobile apps.  Live on stage he wrote an app in XAML and C# using the Xamarin Plugin for Visual Studio 2015 and built/deployed it to both a Android and iOS simulators, and ran it successfully.  It was even able to access native resources like the camera and GPS.  He was even able to set break points in his code and debug on the simulators.  Very exciting and inspiring to me that I can build mobile apps with my existing skill set.  Totally want to download VS2015 and get my code on!

Wednesday, May 18, 2016

Visual Studio Live! Austin - Day 1 (Monday 5/16/2016)

Haven't blogged in a while because most of the issues and problems we've solved at work lately are already well documented at StackOverflow and elsewhere on the web.  And then there's this week.  I have lots to talk about because work has been very kind to send me and a coworker to Visual Studio Live! here in Austin! 


Monday was all day workshops.  We chose Building Modern Mobile Apps with Brent Edwards and Kevin Ford.  Fantastic session with a massive amount of great information, but it was a long exhausting day.  The workshop format involved taking an example app and building/testing/deploying it in a variety of ways, explaining the details and pros/cons of each:
  • Responsive web app
  • Native Android - Java, Android SDK, emulator, ADB deploy tool, Gradle, etc.
  • Native iOS - XCode, Swift / Objective C, provisioning profiles, etc.
  • Apache Cordova
  • Xamarin native
  • Xamarin Forms
My takeaway for the day was that for my organization and our current infrastructure and skill set, Responsive Web App or Xamarin Forms will be the best ways for us to go forward into the mobile space.  Really made me feel good about my current WPF project too.  XAML appears to be a resume-friendly skill.