Rockford Lhotka's Blog

Home | Lhotka.net | CSLA .NET

 Saturday, June 11, 2016

RDSPK20Now is the time to register for Visual Studio Live! Redmond 2016. Sure, the conference isn’t until early August, but now is the time to get early discounts and all that stuff.

This link gets you one of those discounts: RDSPK20_Reg

This is a great event, right there on the Microsoft campus – often the best of our events in terms of spontaneous opportunities to interact with your favorite Microsoft engineers – and as is the case with all the VS Live events this is the best opportunity to learn about current and future technologies around Microsoft, the web, and mobile app development.

After all my recent health issues, I’m finally back to doing a workshop. Jason Bock and I will be giving a pre-con on distributed computing, including the use of various Azure features, microservices, and of course a little bit of CSLA .NET Smile

I hope to see you there!

Saturday, June 11, 2016 3:38:10 PM (Central Standard Time, UTC-06:00)  #    Disclaimer

Tomorrow I fly to Boston for Visual Studio Live! Boston 2016. If you are attending I look forward to seeing you during the week, it should be a great event!BOSPK17

Saturday, June 11, 2016 3:30:23 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Tuesday, June 07, 2016

A very common scenario for line of business apps is to edit a collthIDVUDFR8ection of items. Often this isn’t a bit collection, just a variable number of rows with a few columns to edit per row.

The MVC scaffolding supports this scenario by making it easy to create a set of pages – display the list, create a new item, edit an existing item, confirm removal of an item. And this scaffolding is quite useful, especially for scenarios where each row of data has a lot of properties to edit.

Where it isn’t so useful is in another common case, where each row of data has a small number of properties to edit (and where there are a relatively small number of rows). In this case most users would prefer to just edit all the values on a single screen, not having to navigate to the create/edit/delete pages for each row, as that is quite awkward.

What I’ve found is that there are some (ok, lots) of blog posts and code snippets showing ways to solve this problem. Much of this content dates back many years, often to MVC 2, and shows what (in my view) are some pretty hacky solutions involving client-side JavaScript that manually creates html strings that replicate (often outdated) html comparable to that generated by MVC in Razor. Other solutions use WebGrid, a seemingly little-used feature of MVC that also needs some (less hacky) JavaScript to support editing.

For my purposes, I wanted something simpler, more direct. I don’t mind some postbacks – you’d get those with the standard MVC scaffolding – I just want the user to feel like they are just editing the list of items without a lot of page navigation. Something like this:

snip_20160607190309

I also don’t mind using Session in this case, because I’m building something that will, at most, be used by 0.3% of our employee base, which is currently around 600 people. If we grow enough that scaling is an issue we’ll obviously have

To that end I created a new ASP.NET MVC 5 project in Visual Studio 2015 and added the files in this gist that contain the implementation.

The ProjectListController serves up the initial page, and accepts POST operations from the browser.

The Index method displays the page with the collection data. If Session is empty the data is loaded from the database, otherwise the cached Session data is used to populate the page. Typically this means that the first time the user arrives at the page they’ll get fresh data from the database, and on postback operations the data will come from Session. Basically I’m using Session as an in-memory scratch location for the data until all edits are complete and the user clicks the button to save the data.

The POST method works differently depending on the button clicked by the user, handling add, remove, cancel, and submit operations. The operation is indicated by the value of the button, which flows into the controller through a method parameter. In every case the POST method has the full contents of the collection from the UI that flows from the browser into the method.

The add operation adds a new/empty item to the collection, updates the state in Session and allows the page to be redisplayed. This means the newly added item appears to the user, but hasn’t been saved to the database.

The remove operation removes the selected item or items from the collection, updates the state in Session and allows the page to be redisplayed. This means the removed items are no longer displayed, but haven’t been removed from the database.

The cancel/refresh operation clears Session and redisplays the page, causing the page to display fresh data from the database.

The submit operation saves the data into the database, then clears Session to ensure that when the page is redisplayed that the user gets fresh data from the database (including the newly saved changes).

The Index.cshtml view implements the page, relying on the Person.cshtml view to display each row of data from the collection. The Index view has all the buttons the user can click to trigger the postback operations to the controller as I just described.

The Person.cshtml view creates the edit controls for the properties the user should view/edit for each row.

The Person.cs file implements the model – really the viewmodel. Notice that it has a Removed property which is very UI specific, so this clearly isn’t the actual model you’d ever get/save in a database.

The controller has TODO comments indicating where code should go to invoke the data access layer to retrieve and update the database based on the in-memory collection of Person objects.

Tuesday, June 07, 2016 6:03:58 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Wednesday, June 01, 2016

csla win8_fullThis release of CSLA .NET is focused primarily on enhancing the existing Xamarin support. There is now a Csla.dll targeting PCL Profile111, which is the current profile for Xamarin.Forms projects and .NET Core.

There is also now a CSLA-Xamarin NuGet package that includes a Csla.Xaml.dll with support for Xamarin.Forms. This includes the same viewmodel base classes as the other XAML platforms, and an implementation of the PropertyInfo control tailored for use in Xamarin.Forms.

@JasonBock added even more analyzers for Visual Studio 2015 to help developers avoid common coding mistakes when building CSLA .NET business classes.

We now have support for the prerelease of Entity Framework 7.

The pt and pt-BR resources for Csla.dll have been updated. Other languages need updates as well - please contribute if you are a native speaker!

There is a new way to customize the server-side data portal by implementing an interceptor that is invoked via the new DataPortalBroker. (#564)

Full details: https://github.com/MarimerLLC/csla/releases/tag/v4.6.400

The assemblies and packages are all available via NuGet.

Wednesday, June 01, 2016 9:33:18 AM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Thursday, May 26, 2016

th7JTBT6D7There is now a Csla.Xaml.PropertyInfo control for Xamarin Forms as well as WPF/UWP, so you can use the same technique to access all metastate about each property from your XAML.

This means that (now on Xamarin too) you can bind to the property value, as well as CanRead, CanWrite, IsValid, IsBusy, and various other metastate values.

Using this capability your XAML UI can provide the user with immediate and rich visual cues as to whether the user is allowed to read or write the property value, and whether the current property value is valid (and if not, why), as well as whether the property has any outstanding async business rules currently executing.

In short, all the goodness that WPF/Silverlight/UWP developers have enjoyed over the past many years is now available on Xamarin!

(or will be once CSLA .NET 4.6.400 releases in about a week – though you can try it now with the 4.6.400 prerelease available via NuGet)

Thursday, May 26, 2016 3:57:07 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Wednesday, May 25, 2016

The CSLA PCL that supports Xamarin includes an implementation of System.ComponentModel.DataAnnotations, and that includes numerous types, one of which is DisplayAttribute.

The PCL uses type forwarding so at runtime the platform's DataAnnotations implementation is used (if available), and the CSLA implementation is only used at runtime for platforms where there's not already an implementation (WinRT Phone is the only remaining platform afaik).

There is a problem with Xamarin however, where all types seem to forward and work fine except for DisplayAttribute. The problem in this case is that at runtime it seems that mono is unable to locate the correct ctor for the type:

"System.MissingMethodException: Method 'DisplayAttribute..ctor' not found.\n  at (wrapper managed-to-native) System.MonoCustomAttrs:GetCustomAttributesInternal (System.Reflection.ICustomAttributeProvider,System.Type,bool)\n  at System.MonoCustomAttrs.GetCustomAttributesBase (ICustomAttributeProvider obj, System.Type attributeType, Boolean inheritedOnly) [0x00019] in /Users/builder/data/lanes/3236/ee215fc9/source/mono/mcs/class/corlib/System/MonoCustomAttrs.cs:128 \n  at System.MonoCustomAttrs.GetCustomAttributes (ICustomAttributeProvider obj, System.Type attributeType, Boolean inherit) [0x00040] in /Users/builder/data/lanes/3236/ee215fc9/source/mono/mcs/class/corlib/System/MonoCustomAttrs.cs:158 \n  at System.Reflection.MonoProperty.GetCustomAttributes (System.Type attributeType, Boolean inherit) [0x00000] in /Users/builder/data/lanes/3236/ee215fc9/source/mono/mcs/class/corlib/System.Reflection/MonoProperty.cs:317 \n  at Csla.Core.FieldManager.DefaultPropertyInfoFactory.GetFriendlyNameFromAttributes (System.Ty
pe type, System.String name) [0x00011] in <filename unknown>:0 \n  at Csla.Core.FieldManager.DefaultPropertyInfoFactory.Create[T] (System.Type containingType, System.String name) [0x00000] in <filename unknown>:0 \n  at Csla.ReadOnlyBase`1[T].RegisterProperty[P] (System.Linq.Expressions.Expression`1 propertyLambdaExpression) [0x0001c] in <filename unknown>:0 \n  at ProjectTracker.Library.ProjectInfo..cctor () [0x00000] in G:\\src\\rdl\\csla\\Samples\\ProjectTracker\\ProjectTracker.BusinessLibrary.Shared\\ProjectInfo.cs:10 "

This exception occurs when the consume app attempts to access the DisplayAttribute associated with a property to retrieve values from the attribute. It appears that mono is unable to create an instance of the attribute object because it can't find the ctor. The DisplayAttribute class has only a default ctor, but is typically initialized using named parameters, such as:

[Display(Name = "foo")]

I don't know what kind of ctor mono is looking for when it fails, but it obviously isn't finding the default ctor and then setting the property value, which is what would be the expected behavior.

I’m tracking this issue in the CSLA GitHub repo: https://github.com/MarimerLLC/csla/issues/579

Steps to reproduce issue

The CSLA ProjectTracker reference app in my fork includes a repro of this issue. To see the issue, do the following:

  1. Clone my fork of CSLA from https://github.com/rockfordlhotka/csla.git
  2. Checkout the 505-xamarin branch: https://github.com/rockfordlhotka/csla/tree/505-xamarin
  3. Open the \Samples\ProjectTracker\ProjectTracker.sln solution
  4. Build the solution – it’ll pull down the CSLA .NET framework from NuGet
  5. Set a breakpoint in the XamarinFormsUi.ViewModels.ProjectList class as shown here
    snip_20160525134558
  6. Set the startup app to ProjectTracker.Ui.Xamarin.Droid
  7. Run the app in debug mode (on an emulator or device)
  8. On the first screen click the All Projects button
    snip_20160525134836

That’ll attempt to load the ProjectList page and ProjectList viewmodel. At this point the exception will occur and you’ll end up on the breakpoint because of the failure to create an instance of ProjectInfo, but that fails because mono can’t create an instance of DisplayAttribute (used on some properties in the ProjectInfo class).

Wednesday, May 25, 2016 12:51:26 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Friday, May 20, 2016

I might have found a bug in mono, but want to see if anyone thinks I'm missing something.

The CSLA .NET framework has long included an implementation of the System.ComponentModel.DataAnnotations namespace for platforms where Microsoft/Xamarin didn’t provide that functionality. These days I think that is only Windows Phone 8.1, but that includes PCL Profile111 (which is what Xamarin currently targets as well).

Of course the CSLA implementation includes the DisplayAttribute class, which is used to decorate properties in consuming classes like this:

[Display(Name = "blah")]

That "blah" value is a human readable name/label for a property.

Because mono actually provides a System.ComponentModel.DataAnnotations implementation, my PCL uses type forwarding so at runtime the PCL implementation is ignored in favor of the platform-specific implementation provided by mono. For example:

[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute))]

This works great on all platforms - except Xamarin Android/iOS where mono throws an exception because it can't find a matching constructor.

The thing is that the DisplayAttribute class has only the default constructor. The syntax being used to set the Name property of the attribute is supposed to use the default ctor, and then the Name property is explicitly set. This is a relatively old feature of C# - but I kind of suspect mono has a bug around this area, as it seems to be looking for a ctor that accepts a parameter when it should use the default ctor.

Friday, May 20, 2016 3:40:28 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Tuesday, April 26, 2016

thHU21A440There’s a lot of speculation at the moment, mostly I think from the tech press, that there’s no future for Windows 10 Mobile (aka Windows Phone). To the point that Terry Myerson apparently released a statement to clarify that Microsoft is committed to mobile for many years.

Over the past couple years I’ve been increasingly critical of Microsoft’s mobile strategy as well – it is hard not to be when the platform has such low market share, there’s been a lack of flagship devices released, and there’s still a major issue with apps (that don’t exist or that are quite poor compared to iPhone/Android versions).

So at the beginning of this year I “threw in the towel” and switched to the iPhone. This was after talking to a lot of people in person and via twitter about whether to go iPhone or Android. The overwhelming advice was that if you live in the US you should go iPhone, so I did exactly that.

After a couple weeks with the iPhone I wrote a comparison between Windows 10 Mobile and the iPhone – from my perspective. I’m selfish – I’m looking for a good answer for me, so my blog post was about me and my personal experience. After a couple more months I realized that this is a real tradeoff, because Windows 10 Mobile the operating system is more consistent and polished than iOS, but the apps on the iPhone are almost universally superior.

At that point I thought I’d try Android. This was right after Microsoft Build 2016, where it seemed like there was a lot of love for Android, and where I encountered a whole lot of my peers who were incredulous that I had an iPhone instead of an Android (where they were last fall when I was soliciting input I have no idea – I begin to suspect that people only advocate for their platform when you have “the other platform” in your pocket). Basically, some of the iOS frustrations and inconsistencies were bugging me enough I wanted to look elsewhere.

I didn’t even last a couple weeks on Android though. I bought a OnePlus 2 – a high-end device with very generic Android. It turns out that generic Android pretty much sucks – much like generic Linux. You need to spend (in my experience) hours and hours and hours researching and trying different launchers, lock screen apps, email apps, calendar apps, contact apps, etc. Just to get basic functionality that works out of the box in the iPhone and Windows 10. O.M.G. I don’t understand how people can waste that much time just getting the basics to work on their phones!?!

Now I’m back to Windows 10 with a Lumia 950xl. And I’m happy.

I keep hearing how Windows “lacks polish”. Clearly this statement is being made by people who have not actually used Windows 10, iOS, and Android back to back like I just did. In some ways iOS might have more polish, but it is far, far less consistent than Windows, so I give the OS polish nod to Windows 10. Android isn’t even in the running – it has no polish or consistency – though maybe with another many hours of research and testing I could have found a launcher that I liked? That’s not how I want to spend my life.

I also keep hearing about the Windows “app gap”. That is obviously a real problem. It is absolutely the case that the iPhone has a lot more apps, and almost all the apps are superior. It is also the case that the Android apps are plentiful, but they generally look like crap compared to their iOS counterparts. But I’ll give it to Android that, though its apps are inconsistent and often cartoonish, they are full featured, unlike Windows apps.

One other note on apps: Android is clearly designed to work well if you are a Google user (mail/calendar/contacts) and it is pretty half-baked for people not on Google. I can’t say I support the EU going after Google any more than I did when they went after Microsoft so long ago – I think that’s just dumb – but at the same time, I understand their consistent view here, because Google is using Android to drive usage and lock-in around their cloud service offerings, not unlike what Microsoft did 20 years ago with Windows.

Finally, I keep hearing how Windows phone hardware is inferior. I even heard that from someone at Microsoft. I’m skeptical. It is true that the iPhone 6s is a really nice device, and I love the fingerprint unlock feature. Android device quality varies a lot, but the OnePlus 2 is pretty nice (if a bit heavy) and has a fingerprint reader (if you can find a lock screen app that supports it). The Lumia 950 is nicer and lighter than the Android devices I’ve seen and used (including the Samsung ones). But I’ll grant that it isn’t as nice as the iPhone. At the end of the day though, I think all three platforms have hardware that are basically in the same ballpark: reasonably stylish, light, fast, with decent battery life, and great cameras. If it was just down to hardware my ranking would be iPhone 6s, Lumia 950, Samsung Android, other Android – in that order.

At this point though I’ll remind you that I’m selfish here – I’m after a solution for me.

That means it comes down to iPhone vs Windows 10 Mobile – the Android OS is too unpolished, clumsy, and inefficient; and its apps are too ugly, inconsistent, and cartoonish. It is clearly the cheapest platform, and you get what you pay for. I’m willing to pay to get a more productive experience.

And at the end of the day there are only 3 apps that don’t exist or don’t work on Windows that I actually need: Swarm, Waze, and the Parrott Bebop app for my drone.

My bank does have an app on iPhone/Android, but it sucks and so not having it isn’t really a loss. To solve my bank app issue I need to switch to a better bank, not a different phone.

I weighed the value of those 3 apps against Windows 10’s more polished and consistent OS experience; and I considered that Siri is like Cortana’s dullard older sister (yes, Siri is really an idiot compared to Cortana, and Cortana on the iPhone is crippled compared to Windows or Android).

Ultimately I’ve decided that I’d rather go with the best OS on a regular basis. In my case I’m fortunate enough that I can carry a second phone (sans SIM) so I can still fly my drone – it just needs the app and wifi after all. That also gets me Waze and Swarm, because they also work over wifi, and my Lumia works great as a wifi hotspot when I’m out and about.

At the end of the day, until Foursquare, Google, and Parrot (and my bank) get their heads out of their @$$’s I am working around them via a two phone solution.

But most importantly, I’m happy using Windows 10 and Cortana for my 99% use case of email/calendar/phone/text/messaging/Office/etc.

And fwiw, I think the continued rapid adoption of Windows 10 itself (on my Surface and Desktop for example) will drive more and more companies to create UWP apps – perhaps not initially for the phone, but at least for the 300 million (and climbing) people running Windows 10. The thing is, once your app runs in UWP, getting to the phone is a pretty small step – and one companies would be foolish not to do for such little effort.

Tuesday, April 26, 2016 3:46:05 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Thursday, April 14, 2016

Earlier this year I embarked on an “adventure”. I was frustrated with the lack of apps on Windows Phone (Windows 10) and I keep hearing how magical the iPhone is for people. After a couple weeks with the iPhone I wrote a comparison blog post: Windows Phone vs iPhone comparison

More recently I wrote about my ongoing frustrating with the iPhone, justifying why I was going to try an Android device: iPhone frustration

I’m trying to give each platform a fair try, but after a few short days with Android (I have a OnePlus 2 – so very “vanilla” Android) I’m already finding that of the three operating systems Android is the worst. It is kind of like desktop Linux – cobbled together by a lot of people who don’t share a common vision, so everything sort of works, but nothing feels consistent and most things don’t seem professional or polished. Kind of the diametric opposite of the iPhone.

I’ve always thought that you get what you pay for, and I think Android reinforces that worldview. It is cheap, the devices are cheap, the apps are free or cheap. And they all feel cheap when compared to Windows 10 or iOS. But if your phone isn’t a budgetary priority in your life, yet you need a smartphone, then Android is probably the right choice – which explains why it is the most popular OS globally. Clearly the majority of the world’s population either can’t afford a professional phone/experience (which is largely true of course), or they don’t value their own time as much as money, so they are willing to invest that time dealing with Android instead of spending the extra money up front to get an iPhone or Windows Phone.

Notice that I’m still putting Windows Phone in this discussion, even though it has a low US market share, and only a slightly better global market share. In my experience with the three platforms thus far, my conclusion is that the operating systems rank like this:

  1. Windows 10
  2. iOS
  3. Android

The physical devices I’ve been using rank like this:

  1. iPhone 6s
  2. Lumia 950xl
  3. OnePlus 2

The availability and quality of apps rank like this:

  1. iOS
  2. Android
  3. Windows 10

If you assign numeric scores to each category, you end up with the following overall ratings:

  • iPhone (8)
  • Windows 10 (6)
  • Android (4)

So at least in my opinion – based on how I use my phone and what I expect out of it – I probably should keep using my iPhone, and keep grumbling about how dumb Siri is compared to Cortana. Or I should go back to Windows 10 and deal with the sad reality that it doesn’t have workable Waze, Swarm, or banking apps.

A lot of people I know do carry two phones (personal and work). I’m sort of considering carrying 2 devices – a Windows phone with a SIM as my primary (so I have Cortana and all the other stuff I love about Win10) and an iPhone without a SIM to run the apps that don’t exist on Win10, because they all run over WiFi. Just a little twist on the work/personal dual phone scenario – but in my case I’ll have one phone that’s fun to use (Win10), and one phone that runs apps that are fun to use (iPhone).

Thursday, April 14, 2016 8:53:23 AM (Central Standard Time, UTC-06:00)  #    Disclaimer
On this page....
Search
Archives
Feed your aggregator (RSS 2.0)
June, 2016 (4)
May, 2016 (3)
April, 2016 (4)
March, 2016 (1)
February, 2016 (7)
January, 2016 (4)
December, 2015 (4)
November, 2015 (2)
October, 2015 (2)
September, 2015 (3)
August, 2015 (3)
July, 2015 (2)
June, 2015 (2)
May, 2015 (1)
February, 2015 (1)
January, 2015 (1)
October, 2014 (1)
August, 2014 (2)
July, 2014 (3)
June, 2014 (4)
May, 2014 (2)
April, 2014 (6)
March, 2014 (4)
February, 2014 (4)
January, 2014 (2)
December, 2013 (3)
October, 2013 (3)
August, 2013 (5)
July, 2013 (2)
May, 2013 (3)
April, 2013 (2)
March, 2013 (3)
February, 2013 (7)
January, 2013 (4)
December, 2012 (3)
November, 2012 (3)
October, 2012 (7)
September, 2012 (1)
August, 2012 (4)
July, 2012 (3)
June, 2012 (5)
May, 2012 (4)
April, 2012 (6)
March, 2012 (10)
February, 2012 (2)
January, 2012 (2)
December, 2011 (4)
November, 2011 (6)
October, 2011 (14)
September, 2011 (5)
August, 2011 (3)
June, 2011 (2)
May, 2011 (1)
April, 2011 (3)
March, 2011 (6)
February, 2011 (3)
January, 2011 (6)
December, 2010 (3)
November, 2010 (8)
October, 2010 (6)
September, 2010 (6)
August, 2010 (7)
July, 2010 (8)
June, 2010 (6)
May, 2010 (8)
April, 2010 (13)
March, 2010 (7)
February, 2010 (5)
January, 2010 (9)
December, 2009 (6)
November, 2009 (8)
October, 2009 (11)
September, 2009 (5)
August, 2009 (5)
July, 2009 (10)
June, 2009 (5)
May, 2009 (7)
April, 2009 (7)
March, 2009 (11)
February, 2009 (6)
January, 2009 (9)
December, 2008 (5)
November, 2008 (4)
October, 2008 (7)
September, 2008 (8)
August, 2008 (11)
July, 2008 (11)
June, 2008 (10)
May, 2008 (6)
April, 2008 (8)
March, 2008 (9)
February, 2008 (6)
January, 2008 (6)
December, 2007 (6)
November, 2007 (9)
October, 2007 (7)
September, 2007 (5)
August, 2007 (8)
July, 2007 (6)
June, 2007 (8)
May, 2007 (7)
April, 2007 (9)
March, 2007 (8)
February, 2007 (5)
January, 2007 (9)
December, 2006 (4)
November, 2006 (3)
October, 2006 (4)
September, 2006 (9)
August, 2006 (4)
July, 2006 (9)
June, 2006 (4)
May, 2006 (10)
April, 2006 (4)
March, 2006 (11)
February, 2006 (3)
January, 2006 (13)
December, 2005 (6)
November, 2005 (7)
October, 2005 (4)
September, 2005 (9)
August, 2005 (6)
July, 2005 (7)
June, 2005 (5)
May, 2005 (4)
April, 2005 (7)
March, 2005 (16)
February, 2005 (17)
January, 2005 (17)
December, 2004 (13)
November, 2004 (7)
October, 2004 (14)
September, 2004 (11)
August, 2004 (7)
July, 2004 (3)
June, 2004 (6)
May, 2004 (3)
April, 2004 (2)
March, 2004 (1)
February, 2004 (5)
Categories
About

Powered by: newtelligence dasBlog 2.0.7226.0

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2016, Marimer LLC

Send mail to the author(s) E-mail



Sign In