Asp.net Developer: Why we didn’t hire you.

Photo by striatic (Creative Commons)

In the last year, I’ve interviewed around 30 candidates. These were for mid to senior level asp.net positions at three different companies. Sadly, I’ve only recommended hiring two. Each case is unique, but here are some common reasons for a thumbs-down vote.

You don’t know JavaScript:

Depressingly, none of the candidates had a strong background in JavaScript.

You want a web development job, but can’t code in the only language web browsers can run? Tell me more!

Ten years ago we mostly avoided JavaScript, and just did everything on the server. You could scrape by without knowing much JavaScript. Five years ago, I would have been worried about your lack of commitment amid the rising popularity of *.js frameworks, but if you were otherwise qualified I would still risk it –hoping you could learn enough javascript on the job to keep up.

Today, JavaScript is everywhere. It’s in the browser. It’s on the server. Some of your developer tools and utilities use JavaScript. JavaScript is the native language in many enterprise-grade database systems. JavaScript has become a basic requirement for just about any kind of development, and it isn’t an easy language to work with. Mastering the techniques, patterns, and frameworks needed for production quality code takes a lot of time and practice.

So, if you walk into my interview without a solid grasp of JavaScript, you aren’t going to get the job. You simply aren’t qualified to code for the web.

Never used distributed source control:

I get that your skills with DVCS are thin. Most business employers aren’t using a DVCS yet. Some don’t use formal source control at all (which is terrifying). Most candidates had a little experience with SVN or TFS, but a full third had no source control experience at all. Only a handful had used Mercurial or Git, and several hadn’t even heard of either.

I can teach the basics of DVCS to any competent user, even a non-developer, in just few hours. I’m not worried about the lack of the skill itself –a PluralSight video and a copy of SourceTree and you’ll be good to go. But the fact that you don’t already have significant experience with at least one popular DVCS is a major red-flag.

The entire asp.net stack, most of the popular 3rd party libraries, and even most of the developer tools are open source projects, hosted on the web in public Git or Mercurial repositories. Most build systems, package managers, and continuous integration systems rely on DVCS technologies. The fact that you aren’t comfortable with at least one such system tells me that you aren’t keeping up with your profession, and aren’t participating in the general developer community.

You don’t know anything about design patterns.

When you list Asp.net MVC on your resume, I absolutely will ask about design patterns. My expectations are low, but I will still be disappointed if you have no clue what I’m talking about.

I’m fine that you don’t know Martin Fowler’s name, or about the Gang of Four. If I ask you to name an example of an abstract singleton factory in asp.net, I won’t be surprised when you to look at me like I just broke out in interpretive dance. But I do expect you to know what the term “design pattern” means. You should know that “MVC” is the name a design pattern — even better if you can explain a little about the pattern itself.

I’m not an academic design pattern guru myself, but some patterns are so common that it is difficult to discuss code with someone who doesn’t know the basic terminology –singleton, factory, repository, observer, etc.

Asp.net development in particular revolves around a very specific set of design patterns; IoC, MVC, Repository, and Unit of Work being the most relevant. If you aren’t at least vaguely aware of these patterns, then you can’t possibly be proficient with the asp.net MVC framework.

You don’t have to be able to debate the merits of domain driven design vs. onion architecture. You don’t have to be able to tell me the distinction between transaction script and unit of work. But if I ask you if a C# static class is a singleton, you should at least understand the words coming out of my mouth… even if you can’t give me a good answer to the question itself.

Day laborer:

You only know technologies your former employers used, but nothing else. Your last company still used ADO.NET Datasets, but you haven’t even bothered to read up on LINQ to SQL, Entity Framework, or NHibernate?

Congratulations, you did the bare minimum necessary to earn a paycheck!

I want candidates that take responsibility for developing their own professional skills beyond just the minimum. It’s great that you can meet today’s challenges, but I need people who will be ready for tomorrow’s projects too.

Needs training wheels:

You’ve only coded modules for existing applications, and maybe a few stand-alone tools or utilities for the server room. What you’ve done sounds impressive, but it doesn’t seem like you’ve ever built an application from the ground up. I’m not expecting that you’ve architected your own custom enterprise, multi-tenant ERP solution. But nowhere in the interview did you give me the impression that you’d ever even clicked “file –> new project” either.

So you can follow someone else’s patterns and conventions, and you can plug code into someone else’s framework. But I can’t trust you to code for problems beyond those that some pre-built framework anticipated.

If I give you a blank Visual Studio solution and a list of requirements, can you deliver a complete and high-quality product? Will it be coded to standards? Will the code be organized and maintainable?

Closed shop:

You’ve never build software for users outside your employer’s firewall, much less for the general public. The quality, reliability and usability needs of software for non-technical end-users is different. It requires a more disciplined approach, and involves skills that aren’t heavily used with purely internal projects.

If you can code for the public end-user, I am confident that you can easily code for my company’s internal users. The reverse is not true.

Line of business developers are particularly prone to this problem, since most LOBS are internal only. Internal users are more tolerant to errors, poor design can be offset by specialized user training, and reliability is bolstered by your control of both the server and client environments.

I need to know that you can code to higher standards when it is necessary.

Doesn’t know why:

You have a firm grasp of the tools and technologies your employers have used in the past, but when I ask, “why did your company choose to use X instead of Y?” I get nothing. You told me about that amazing widget you wrote — I liked that story — but when I ask you why you didn’t use a 3rd party widget instead, you can’t give me a valid business justification for the extra time and effort you spent on a custom solution.

You don’t have to be an expert in cost analysis or anything, but I need to know that you can make sound decisions about the technologies, platforms, and coding techniques that you’ll use to solve the challenges my company is facing. Choosing a technology just because it’s cool or popular isn’t always the best bet for business applications.

Entity Framework: It’s not a stack of pancakes!

I’ve been talking to a lot of line-of-business developers lately. Most have adopted newer technologies like Entity Framework, but many are still working with strictly layered application designs. They’ll have POCO entities, DbContexts, DbSets, and all the modern goodness EF brings. Then they smash it all down into a data access layer, hiding EF behind several layers of abstraction. As a result, these applications can’t leverage EF’s best features, and the entire design becomes very cumbersome.

I blame n-tier architectural thinking!

Pancakes:

Most senior .Net developers cut their teeth on .net during a time when n-tier was a pervasive discussion across the industry. Every book, article and classroom lecture about web application design included a long discussion on n-tier fundamentals. The n-tier hype faded years ago, replaced by more realistic lego-block approaches, but n-tier inspired conceptualizations still exert a strong influence over modern designs.

I call it pancake thinking — conceptualizing the logical arrangement of an application as a series of horizontal layers, each with distinct, non-overlapping areas of responsibility. Pancake thinking pins Entity Framework as a DAL technology –just another means to get data in and out of a database –a fundamental misunderstanding of EF’s intended role.

Here is a diagram of a full blown n-tier approach applied to an ASP.NET MVC application using Entity Framework:

EF N-Tier Diagram

Note that all of entity framework is buried at the bottom. An object mapper is probably transforming EF’s entities into business objects. So, by the time information leaves the DAL, EF has been beaten completely out of it. EF acts only as a modernized version of traditional ADO.NET objects. EF is a better experience for DAL developers, but it doesn’t add value for those writing code further up the stack.

I don’t see as many strictly layered designs like this in the wild, though I have come across a few recently. Most of the current literature around EF advocates a somewhat hybrid approach, like this:

EF n-Tier Alternate Design

In this design, EF’s POCOs roam around the business and presentation layers like free-range chickens, but DbContext and DbSets are still being tortured in the basement.

What I dislike about this design is that EF has been turned on its head. The DbContext should be at the top of the stack, acting as the entry point through which you interact with entities.

So, how should a modern EF driven application be designed?

EF’s POCO entities, along with DbContext and DbSets, work best with a behavior driven approach to application design. You design around the business-behaviors of your application, largely without concern for what the database looks like. Instead of a horizontally segmented architecture, EF becomes a pervasive framework used throughout the entire application at all levels. If you are worried about mixing “data-logic” with “business-logic”, then you are still thinking about pancakes. Stop it!

Here is another diagram, this time letting Entity Framework do it’s thing, without any unnecessary abstractions:

EF Domain Model

Notice first, how much simpler the design becomes. We’ve elevated EF to a true business framework, and we’ve eliminated tons of abstractions in the process. We still have n-tier going on, so relax! We just didn’t logically split data and business code like you might be used to.

This is a domain-model architecture, and borrows some of the general ideas of “domain driven design” (DDD). If you are a DDD purist, please do not write me hate mail. What I’m proposing here is not intended to be a true DDD design. If you are interested in DDD in depth, check out Vaughn Vernon’s site. For discussions on practical DDD with .Net and EF, Vaughn’s TechEd presentations are a must watch. 

To understand how this design works, let’s explore the three main concepts behind Entity Framework.

EF Entity Model:

The heart of EF is the entity model. At its simplest, the model is just a bunch of data transfer objects (DTOs) –together they form an in-memory model mirroring the database’s structure. If you generate a model from an existing database, you get this shape. This is also what happens if you design a code-first model using the same thinking you’d use to design a relational database. This “in-memory database” viewpoint is how most n-tier applications tend to use EF models.

That simplistic approach doesn’t leverage EF’s power and flexibility. It should be a true business domain model, or something close. Your entities contain whatever code is appropriate for their business function, and they are organized to best fit the business requirements.

The nice thing about a business-oriented model is that code operating against the entities feels very natural to object oriented programmers. You don’t concern yourself with how the actual persistence is done; EF takes care it for you. This is exactly the level of abstraction n-tier designs strive for, but EF gives you the same result without the rigid, horizontal layering.

Persistence mapping:

The logical entity design should be based on business behavior, but the actual code implementation does require you to understand how EF handles persistence.

Persistence details do place some constraints on the kinds of OOP acrobatics you can employ in your model, so you need to be aware of how it works. Overall though, the constraints are mild, and shouldn’t keep you from an implementation that remains true to the intent of the business-centric design.

Many properties on your entities will need to be persisted to the database. Others may exist only to support runtime behaviors, but aren’t persisted. To figure out how, or if, properties map to the database, EF uses a combination of conventions and attribute annotations. EF doesn’t care about your entity’s other methods, fields, events, delegates, etc. so you are free to implement whatever business code you need.

EF does a good job of automatically inferring much of a model’s mapping from code conventions alone. If you use the conventions appropriately you can get a head-start on your persistence mappings –no code needed. For properties that need more explicit definitions, you use attributes to tell EF how to interpreted them.

For really advanced cases, you can hook into the model builder’s fluent API. This powerful tool lets you define tricky mappings that attributes and conventions alone can’t describe fully. If your model is significantly dissimilar from your database’s structure, you may spend a lot of time getting to know the model builder –but it’s easy to use, and amazingly powerful.

While you will need to understand EF persistence issues, you only need to concern yourself with them when you implement the entity model. For code using that model, these details are highly transparent –as they should be.

Repositories and Business Services:

The final piece of EF is the part so many people insist on hiding –the DbContext and DbSets. If you are thinking in pancakes, the DbContext seems like a hub for accessing the database. N-tier principals have trained you to hide data access from other code, at all costs!

Typically, n-tier type abstractions take the form of custom repositories layered on top of entity framework’s objects. Only the repositories may instantiate and use a DbContext, while everything at higher layers must go through the repositories.

A service or unit-of-work pattern is usually layered on top of the custom repositories too. The service manages the repositories, while the repositories manage EF’s DbContext and DbSets.

If you’ve ever tried to layer an n-tier application on EF like this, you probably found yourself fighting EF all over the place. This abstraction is the source of your pain.

An EF DbContext is already an implementation of a unit-of-work design pattern. The DbSet is a generic repository pattern. So you’ve just been layering custom unit-of-work and repositories over top of EF’s unit-of-work and repositories. That extra abstraction doesn’t add much value, but it sure adds a lot of complexity.

Ideally, the DbContext should be a root business service. The most important thing to understand is that this belongs at the top of the business layer, not buried under it.

Your entities directly contain the internal business logic appropriate to enforce their behaviors. Similarly, a DbSet is where you put business logic that operates against the set of an entity type. Anything that you’d normally put in custom repositories can be added to the real DbSet instead through extension methods.

Extension methods let you extend a DbSet on the fly. They are fantastic for dealing with business context specific concerns, and you can have a different set of extension methods for each of your business contexts. The extension methods can be arranged by namespace, and can also be defined in assemblies higher in the stack –in the latter case, the extension may have access to dependencies within the higher layer assembly that would not be appropriate to couple directly to your business layer. For example, an extension method in an asp.net web application can depend on HttpContext, but you would never want to create a dependency like that directly in the business domain.  Calling code can just chose which extensions are appropriate, and import/use those namespaces, while ignoring extension methods from other contexts.

For cross-cutting concerns that span multiple entity types, you can extend the DbContext itself. A common approach is to have multiple concrete roots for each of your business contexts. The business specific roots will inherits a common DbContext base class. The base class contains EF specific stuff. Factory and adapter patterns often appear in relation to these roots as well, but the key concept is that each top-level service derives from a real DbContext… your calling code has all the LINQ and EF goodness at its disposal.

If you embrace EF’s DbContext as a top-level business service, either directly or through inheritance, then you will find EF can be a very pleasant experience. You are able to leverage its full power at all layers of your application, and friction with EF’s internals disappear. Using custom abstractions of your own, it is hard to reach this level of fluidity.

The Domain Model you’ve read about online:

If you go online and read recent articles about ASP.NET application designs, you’ll find many advocates of domain model designs. This would be great, except that most of them still argue for custom unit-of-work and repository patterns.

The only difference between these designs, and the hybrid n-tier layering design I described before, is that the abstractions here are a true part of the business layer, and are placed at, or near, the top of the stack.

EF Testable Domain Model

While these designs are superior to pancake models, I find the additional custom abstraction is largely unnecessary, adds little value, and usually creates the same kinds of friction you see in the n-tier approaches.

The reason for the extra layer of abstraction seems to have two sources. Partially it comes from that legacy n-tier thinking being applied, incorrectly, to a domain model. Even though it avoids full layering, the desire for more abstraction still comes from the designer’s inner-pancake.

The bigger force advocating for extra abstractions comes from the Test Driven Development crowd. Early versions of EF were completely hostile to testing. It took insane OOP acrobatics and deep abstractions even to get something vaguely testable.

In EF 4.1, code-first was introduced. It brought us the first versions of DbContext and DbSets, which were fairly friendly towards unit testing. Still though, dependency injection issues usually made an extra layer of abstraction appealing. These middle-versions of EF are where the design I’ve just diagrammed came from.

In current EF versions (6 or higher), DbContext and DbSets are now pervasive throughout all of EF. You can use them with model-first, database-first, and code-first approaches. You can also use them with POCOs, or with diagram generated entities (which are still POCOs in the end). On the testability front, EF has added numerous features to make native EF objects easily testable without requiring these layers of custom abstraction.

You can, through a bit of experimentation, learn how to write great unit tests directly against concrete instances of DbContext and DbSet –without any runtime dependency on the physical database.

How to achieve that level of testability in your model is a topic for another post, but trust me… you don’t need custom repositories for testing EF anymore. All you need is to be smart about how you compose your code, and maybe a little help from a mocking framework here and there.

I’ve kept most of this discussion pretty high-level. Hopefully it will help expand how you view EF based application designs. With some additional research, you should be able to take these ideas and turn them into real code that’s relevant to your own business domain.

 

TicketDesk 3 Dev Diary – MEF, IoC, and Architectural Design

TicketDesk 2 and TicketDesk 3 have some key architectural differences. Both enforce a strict separation of concern between businesses and presentation layers, but there are major architectural differences within each layer. In this installment, I’d like to talk about how the back-end architecture will evolve and change.

TicketDesk 2 – Decoupled design:

The most significant technology that shaped TicketDesk 2’s class library design was the use of the Managed Extensibility Framework (MEF). The use of MEF in TicketDesk 2 was not about modularity, at least not in a way that is relevant to business requirements. TicketDesk 2 was never intended to support plug-ins or dynamic external module loading. I used MEF for two reasons; I was giving test driven development (TDD) another shot, and I had planned to write a Silverlight client for TicketDesk 2.

MEF was originally built by the Silverlight team. It had a lot of potential for other environments, but didn’t play well with MVC back then. It took some dark magic and hacking to just make it work there. MEF is an extensibility framework first, but an IoC container only by accident. While MEF can do the job of an IoC container, it wasn’t particularly good in that role.

As an extensibility framework, MEF actually has more in common with require.js than traditional server-side IoC frameworks. As a Silverlight technology, the primary purpose was to enable clients to download executable modules from the server on demand when needed. This is exactly what require.js does for JavaScript in HTML applications. The truly interesting thing is that TicketDesk 2 did not use MEF in this way at all. Asp.Net MVC is a server-side environment following a request-response-done type execution flow. Deferred module loading isn’t relevant in that kind of environment. TicketDesk used MEF only for its secondary IoC features — runtime composition and dependency injection.

Considering the difficulty in getting MEF working, and the fact that there are better IoC frameworks for MVC, I should have scrapped MEF in favor of Ninject –which has made me very happy in dozens of other projects. I stuck with MEF partly because it would pay off when I got to the Silverlight client, and partly because I liked the challenge that MEF presented.

Sadly, I was only three weeks into development on TicketDesk Silver, the Silverlight client, when Microsoft released Silverlight’s obituary. I had two other projects under development with Silverlight at the time, so that was a very bad summer for me.

The modular design of TicketDesk’s business layer is mostly about testability. EF 4 was quite hostile to unit testing, so I did what everyone else was doing… I wrapped the business logic in unit-of-work and repository patterns, and made sure the dependencies targeted abstract classes and interfaces. If you want to get all gang-of-four about it, the service classes in TD2 are more transaction script than unit-of-work, but it gets the same job done either way. This gave me the level of testability I needed to follow a (mostly) TDD workflow.

One thing I have never liked about heavy unit testing, and TDD in particular, is having to implement complex architectures purely for the sake of making the code testable. I’ll make some design concessions for testability, but I have a very low tolerance for design acrobatics that have nothing to do with an application’s real business requirements.

TicketDesk 2 walks all over that line. I dislike that there are a dozen or more interfaces that would only ever have one (real) concrete implementation. Why have an interface that only gets inherited by one thing? I also dislike having attributes scattered all over the code just to describe things to an IoC container. Neither of those things make TicketDesk work better. It just makes it more complex, harder to understand, and harder to maintain.

On the flip-side, I was able to achieve decent testability without going too far towards an extreme architecture. The unit tests did add value, especially early in the development process –They caught a few bugs, helped validate the design, and gave me some extra confidence.

If you noticed that the current source lacks unit tests, bonus points to you! My TDD experiment was never added to the public repository. I was pretty new to TDD, and my tests were amateurish (to be polite). They worked pretty well, and let me experience real TDD, but I didn’t feel that the tests themselves made a good public example of TDD in action.

TicketDesk 3 – Modularity where it matters:

A lot has changed for the better since I worked on TicketDesk 2.

Some developers still write their biz code in a custom unit-of-work and repository layer that abstracts away all the entity framework stuff; which is fine. But when EF code-first introduced the DbContext, it became much friendlier towards unit testing. The DbContext itself follows a unit-of work pattern, while its DbSets are a generic repository pattern. You don’t necessarily need to wrap an additional layer of custom repository and unit-of-work on top of EF just to do unit testing anymore.

I plan to move most of the business logic directly into the code-first (POCO) model classes. Extension methods allow me to add functionality to any DbSet<T> without having to write a custom implementation of the IDbSet interface for each one. And the unit-of-work nature of the DbContext allows me to put cross cutting business logic in the context itself. Basically, TD 3 will use something close to a true domain model pattern.

As for dependency injection, the need to target only interfaces and abstract types has been reduced. An instance of a real DbContext type can be stubbed, shimmed, or otherwise mocked most of the time. In theory, I should be able to target stubbed/shimmed instances of my concrete types. If I find the need to target abstracts, I can still refactor the DbSets and/or DbContext to inherit custom interfaces. There still isn’t a compelling need to wrap the business logic in higher layers of abstraction.

In TicketDesk 3, I will not be using a TDD workflow. I love unit testing, but am traditionally very selective about what code I choose to test. I write tests for code that will significantly benefit from them –complex and tricky code. I don’t try to test everything. Using TDD as a design tool is a neat thought process, but I find that design-by-test runs counter to my personal style of design. I can easily see how TDD helps people improve their designs, but I personally tend to achieve better designs when I’m coding first and testing later.

When I do get to the need for dependency injection, I plan to run an experimental branch in TicketDesk 3 to explore MEF 2 a bit further. I think they have fixed the major issues that made MEF 1 hard to use in web environments, but it is almost impossible to find good information online about MEF 2. The documentation, when you can find it, is outdated, contradictory, and just plan confusing. What I have found suggests that MEF 2 does work with MVC 4, but still requires some custom infrastructure. What I don’t know is how well it works.

With the need for dependency injection reduced, few compelling extensibility requirements on the back-end, and no plans to do heavy unit testing, I am more inclined to go with Ninject. They care enough to write top-notch documentation, and it was designed explicitly for the purpose of acting as an IoC container… which is the feature set TicketDesk actually needs.

TicketDesk 3 Dev Diary – Localization and Internationalization

worldOne of the most frequently requested features for TicketDesk 2 was support for localization. TicketDesk is a stringy application; lots of system generated text that will end up in the user’s face at some point. Localizing TD2 required combing through the source code, line-by-line, translating magic strings by hand.

Clearly, this is not an acceptable approach with TicketDesk 3.

Since localization is thorny, and a weak spot in my own skill-set, I consider it essential to designed for localization as early in the process as possible… and now that the code has gotten to the point where it draws a useful UI, it is time to get started.

In the typical Asp.Net application, localization is mostly just a matter of creating resource files that contain the text translations, then making sure the code only gets text from those resources. There is a lot of support in .Net around localization, cultures, and resource files, so this is pretty easy to do. The only difficult part, for the mono-lingual developer, is getting the text translated into those other languages in the first place.

TicketDesk 3 is a SPA application, which presents a different problem. The UI is mostly HTML and JavaScript, so all that nice .Net localization stuff is unavailable when generating the screens that users will actually see. So the first step was to find a JavaScript library for localization; something that does the same job as .Net resource files. The second challenge was connecting that JavaScript library to the server-side .Net resource files.

Fortunately, there is a fantastic JavaScript library called i18next that fits the bill.

Translations in TicketDesk 3:

i18next follows a pattern similar to server-side .Net resource files. You supply it with json files that contain translated text. Once i18next has the text, it takes care of binding it to the UI via an HTML data-* attributes, or through javascript functions directly. As a bonus, i18next is easy to use in conjunction with knockout’s own UI binding.

TicketDesk performs text functions on the server too, so it still needs resource files, so I wanted to be able to pipe the contents of the resource files to i18next directly, rather than maintaining separate translation files for the server and client. For this, I leveraged Asp.Net Web Api. Configuring i18next to get its json translations from Web Api is simple –just map the URLs it uses to Web Api endpoints.

The Web Api controller itself was a bit more complex. It has to detect the specific language that i18next is requesting, then build an appropriate response in a format i18next can consume. The controller loads a ResourceSet for the requested culture, then loops through the properties to build a dynamic key/value object with all the translated text. Once that’s done, it outputs the dynamic collection as a json response.

i18next has a richer set of capabilities than straight .Net resource files. Resource files are just simple name/value lookups. With i18next, the translation files can have nested properties, replacement variables, and there are features for interpolation (plural forms, gender forms, etc.). These features are available in .Net with some advanced language frameworks, but the basic resource files don’t go that far. Fortunately, TicketDesk only needs the basic set of features, so a flat name/value lookup should be sufficient to get the job done; though it doesn’t leverage some of i18next’s more advanced features.

Localization is more than text translations. TicketDesk also deals with numbers occasionally, and there are some dates too. Fortunately, it isn’t a number heavy application, nor are are there user editable dates or numbers.  The moment.js library easily handles local date display formatting, and numeral.js can handle the couple of numbers.

The main weak point in TicketDesk 3’s localization will be an absence of structural language transformations. Once you get into right-to-left languages and other exotic forms, the physical layout of the entire UI has to change. Sadly, I do not have the expertise to correctly design for such languages.  HTML 5 and CSS 3 do have decent support for this kind of cultural formatting though, so my hope is that anyone needing to localize for these languages can do so themselves without difficulty.

Internationalization:

My intention for TicketDesk 3 was simple localization; the admin would tell the server what language to use, and the system would just generate the UI in that language for all users. I did not initially expect to support dynamic internationalization — the ability to support multiple languages based on individual user preference.

When I got into the details of the i18next implementation though, it quickly became apparent that TicketDesk 3 could easily achieve real internationalization… in fact, internationalization would be about as easy as static localization.

The result is that TicketDesk 3 will be internationalized, not just localized. It will detect the user’s language and dynamically serve up a translated UI for them –as long as resource files exist for their language. If translations for their specific language and culture aren’t available, it will fall back to the best-matching language, or to the the default if no better match exists.

State of the Code:

I have the plumbing for internationalization in place in the alpha already. It auto-detect’s the browser’s language, or you can override it via the query string (e.g. ?setLng=es-MX). Since I don’t speak any other languages, I can’t provide any real translations myself. For the short term, I have created a generic Spanish resource file, into which I copied the English text surrounded by question marks. This isn’t real localization, but it serves to validate that the localization support works correctly.

For dates, I’m using moment.js, so it should adapt to the browser’s language settings automatically, but I haven’t setup moment to use the querystring override yet… I’ll get to that soon though. I’m not doing any number formatting yet, but when I do I’ll implement numeral.js or a similar library.

When TicketDesk 3 gets into beta, and I have the full list of English text strings in resource files, then I will get a native Spanish speaker to help generate a real set of translations. Hopefully, the community will pitch-in to provide other languages too.

If you want to take a look at the early alpha version, I have published a TicketDesk 3 demo on Azure. I can’t promise that it will be stable, and it certainly isn’t a complete end-to-end implementation. But feel free to play around with it. To play with localization, either change your browser’s language to something spanish (es, or es-MX, or similar), or use the querystring override: ?setLng=es

TicketDesk 3 Dev Diary – SignalR

One of the overall design goals of TicketDesk since version 1 has been to facilitate near-frictionless, bi-directional communication between help desk staff and end-users. Tickets should evolve as a natural conversation, and the entire history of those conversations should be right there in the ticket’s activity log. TicketDesk has done a reasonably good job in this area, but SignalR presents an opportunity to take this idea to a whole different level.

The goal behind the SignalR library is to give the server a live, real-time channel to code running on the client. The server can push notifications whenever things change, and that information is available to the user immediately. The techniques that SignalR use to achieve this are not entirely new, but have historically been difficult to implement.

TicketDesk 3 uses breeze on the client, and breeze tracks all the entities it has retrieved from the server. Knockout is used to bind those entities to the UI for display. The beauty of this combination is that Knockout automatically updates the UI anytime the entities in breeze change.

With SignalR, the browser can listen in the background for updates from the TicketDesk server. When the server notifies the client that a ticket has changed, the client can then choose to fetch the new data in the background, and update the local copy being tracked by Breeze… and Knockout will automatically refresh the display to show that updated data to the user.

The best thing about SignalR is that it is trivially easy to setup, and with the combination of Breeze and Knockout it is super simple for the UI to respond intelligently.

As a proof of concept, I have coded up a simple SignalR hub that will tell all connected clients when a ticket changes (and what the ID of the changed ticket is). The client will check to see if it is tracking a ticket with that ID, and if so it will automatically fetch a new copy of the ticket from the server. Anything on the screen that is bound to that ticket will automatically update to show the changes. This was not only very easy to implement, but it seems to work very well.

I then took it a step further, and coded up several special routines for the ticket list view. Not only does it update the tickets displayed on screen, but it also responds intelligently to changes in the number of open tickets, or changes of the order of the tickets within the list.

This list view, as currently implemented in the alpha, is a paged list showing 5 items on screen at a time. Because the list is sorted by the last updated date, anytime a ticket is updated the order of items in the list changes too. If a ticket is closed or re-opened, the number of items will grow or shrink change. Pager buttons may need to be disabled or enabled, items on the current page may change as tickets are shuffled around, and the current page might not even be valid anymore if the number of open tickets shrinks enough.

With very little effort, I was able to code up the list view that dynamically responds to real-time changes on the server, and keeps itself current without the user ever needing to explicitly refresh the screen.

I plan to use the set of capabilities around SignalR to make the entire application behave in near real-time. The Ticket activity log will behave like a real-time chat conversations, lists will automatically adjust as things change, and notifications will appear to keep the user informed.

If you want to take a look at the early alpha version, I have published a TicketDesk 3 demo on Azure. I can’t promise that it will be stable, and it certainly isn’t a complete end-to-end implementation. But feel free to play around with it.

To see the SignalR behavior in action, just open the site in two browsers at the same time. Make changes to a ticket in one, and watch the other browser update itself.

TicketDesk 3 Dev Diary – Hot Towel

toweliconFor TicketDesk 3, what I most hope to achieve is an improvement in the overall user experience. Since I wrote TicketDesk 2, much has happened in the JavaScript world. New JavaScript frameworks have matured, and enable deeper user experiences with much less development effort than ever before. TicketDesk is a perfect candidate for Single Page Application (SPA) frameworks, so all I had to do was pick a technology stack and learn to use it.

I have decided to start from the wonderful Hot Towel SPA by John Papa. Hot Towel is a visual studio project template that combines packages from several different client and server frameworks. It includes Knockout.js for UI data-binding, Durandal for routing and view management, and Breeze for talking to the ASP.NET Web Api backend.

My main reasons for choosing Hot Towel are:

  • It is a complete end-to-end SPA Template.
  • It is well documented.
  • The components it relies on are reasonably mature, and well maintained.
  • There are good sample applications built on Hot Towel.
  • John Papa published an excellent, and highly detailed, video course for Hot Towel at Pluralsight.
  • It is very easy to learn and use.

One of the disappointments when switching from server-side Asp.Net to a SPA framework is that the UI is pure JavaScript, HTML, and CSS. It makes almost no use of MVC controllers or views, which always makes me feel like I’m wasting valuable server capabilities. A SPA does make heavy use of Asp.Net Web Api for transferring data, but the UI leaves all that wonderful Asp.Net and Razor view engine stuff behind.

Once I learned by way around Hot Towel, I was surprised to find that working with Knockout, Durandal, and Breeze on the client is much easier than working with Asp.Net on the server. I’m no fan of JavaScript as a language, but the current crop of JavaScript frameworks are truly amazing.

Now that I’ve learned my way around Hot Towel’s various components, I’ve been able to develop a fairly advanced set of UI features very quickly. The current UI is very raw and only provides a primitive set of features, but it has already exceeded my initial expectations by several orders of magnitude.

If you want to take a look at the early alpha version, I have published a TicketDesk 3 demo on Azure . I can’t promise that it will be stable, and it certainly isn’t a complete end-to-end implementation. but feel free to play around with it.

Asp.net 4.5 mvc or webforms – model binding dropdownlist to an enum with description attributes

One of the more common problems people encounter when working with any .Net user application is the need to put a UI on top of some enumeration. Normally you need to present a friendly list of all the possible items in the enumerator list, then allow the user to pick one of them. This UI typically takes the form of a drop down list, combo box, list box, or similar.

Enums are wonderful in C#, but unlike some other languages, they are also a very thin type. Enums define a collection of named constants. By default, each enumerator in the list equates to an underlying integer value.

Here is an example Enum, and for clarity I’ve specified the value for each enumerator:

public enum CarMake
{
    Ford,     //0
    Chevy,    //1
    Toaster   //2
}

Enums are lightweight, highly efficient, and often very convenient –until you start trying to map them to a UI anyway.

Each of the items, enumerators, within the enum have a name, but the name cannot contain white space, special characters, or punctuation. For this reason, they are rarely user-friendly when converted to a string and slapped into your dropdown lists.

Enter the DescriptionAttribute (from the System.ComponentModel namespace). This attribute allows you to tag your enumerators with a nice descriptive text label, which will fit the UI pretty well if only you can dig the value up. Unfortunately, reading attributes is a cumbersome job involving reflection.

Here is the same enum decorated with descriptions:

public enum CarMake
{
	[Description("Ford Motor Company")]
	Ford,     //0

	[Description("Chevrolet")]
	Chevy,    //1

	[Description("Kia")]
	Toaster   //2
}

To bind up an enum to a drop down list, many developers tend to just manually hard-code the list with user-friendly text values and corresponding integer values, then map the selected integer to right enumerator on the back-end. This works fine until someone comes along later and changes the enum, after which your UI is horribly busted.

To get around this mess, I’ve put together a set of extensions that solves this problem for the common enum to drop down list cases.

Note: I’m using the SelectList class, which comes from Asp.net MVC, as an intermediary container. I then bind the SelectList to the appropriate UI control. You can use SelectList in Asp.net webforms, and most other UI frameworks as well, but you’ll need to implement the code for SelectList. The easiest way to do this is to include the source files for SelectList into your own projects.

The code for SelectList can be found on the AspNetWebStack project page over at CodePlex. Here are the three files needed for SelectList :

The first step in solving the problem is to have an extension method that takes care of reading the description from the enumerators in your enum.

public static string GetDescription(this Enum enumeration)
{
	Type type = enumeration.GetType();
	MemberInfo[] memberInfo = type.GetMember(enumeration.ToString());

	if (memberInfo != null && memberInfo.Length > 0)
	{
		var attributes = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

		if (attributes.Length > 0)
		{
			return ((DescriptionAttribute)attributes.First()).Description;
		}
	}
	return enumeration.ToString(); ;
}

To get an enumerator’s description using this extension method:

string text = CarMake.Ford.GetDescription();

The next challenge is to build a select list for the enum.

public static SelectList ToSelectList(this Enum enumeration, object selectedValue = null, bool includeDefaultItem = true)
{
	var list = (from Enum e in Enum.GetValues(enumeration.GetType())
				select new SelectListQueryItem<object> { 
				   ID = Enum.Parse(enumeration.GetType(), Enum.GetName(enumeration.GetType(), e)), 
				   Name = e.GetDescription() }).ToList();

	if (includeDefaultItem)
	{
		list.Insert(0, new SelectListQueryItem<object> { ID = null, Name = "-- select --"});
	}
	return new SelectList(list, "ID", "Name", selectedValue);
}
internal class SelectListQueryItem<T>
{
    public string Name { get; set; }
    public T ID { get; set; }
}

To get the select list using this extension, you just new-up the enum and call the method:

var carSelectList = new CarMake().ToSelectList();

This extension has an optional parameter to set which item in the list should be selected, and another optional parameter that will include a default item in the SelectList (you may want to adjust this extension to match your own convention for default items).

Here is an example that sets a selected value and includes a default item:

var carSelectList = new CarMake().ToSelectList(CarMake.Ford, true)

I’ve been working in C# for over ten years, and until just this week I had no idea that you could instantiate an enum with the new keyword. Of course I cannot think of reason why you’d normally want to new-up an enum either, but the capability is handy for this extension.

You can also use this extension by calling it on one of the specific enumerator items too. This example does exactly the same as the previous example:

var carSelectList = CarMake.Ford.ToSelectList(CarMake.Ford, true);

I personally prefer the new-up pattern in this case, since it isn’t intuitive that calling ToSelectList on a specifc item would return the list of ALL items from the containing enum.

Now that we have the SelectList, all we have to do is bind it up to a DropDownList.

In Asp.net WebForms 4.5, using model binding, this looks like this:

<asp:DropDownList ID="CarMakeDropDown" runat="server" 
	SelectMethod="GetCarMakeDropDownItems"
	ItemType="MyApp.SomeNameSpace.SelectListItem" 
	DataTextField="Text" 
	DataValueField="Value"
	SelectedValue="<%# BindItem.CarMakeValue %>" 
/>
protected SelectList GetCarMakeDropDownItems()
{   
	return new CarMake().ToSelectList();
}

For more in-depth examples of various techniques for binding SelectList to DropDownList in webforms, see my previous article titled “Asp.net 4.5 webforms – model binding selected value for dropdownlist and listbox“.

In Asp.net MVC model binding to a SelectList is a very common and routine pattern, so I’m not going to provide a detailed example here. Generally though, you make sure your model includes a property or method for getting the enum’s SelectList, then you use the Html.DropDownList or Html.DropDownListFor helper methods. This would look something like this:

@Html.DropDownListFor(model => model.CarMakeValue, Model.CarMakesSelectList)

 

 

Asp.net 4.5 webforms – model binding selected value for dropdownlist and listbox

With the Asp.net 4.5 release, webforms inherited several improvements from its Asp.net MVC cousin. I’ve been enjoying the new model binding support lately. Since none of the old datasource controls fully support Entity Framework’s DbContext anyway, model binding is quite handy when using code-first EF models.

For the most part, model binding is straight forward. The basic usage is covered in the tutorials on the asp.net web site, but other resources are rare and hard to find. In the case of DropDownList and similar controls, I found that model binding in webforms was not as straight-forward as I would have thought — especially when trying to set the selected value.

Before I begin, let me explain about the SelectList class.

These examples are valid no matter what data you bind to, but the ItemType that I’m showing in these examples use an implementation of the SelectList class, which I’ve borrowed from asp.net MVC. I don’t like to reference MVC assemblies in my webforms applications, so I just copy in source files to my webforms application. Using SelectList gives you a consistent and strongly typed collection, which tracks each item’s display text, value, and its selected state. SelectList acts as a sort of miniature view-model.

The code for SelectList can be found on the AspNetWebStack project page over at CodePlex. Here are the three files needed for SelectList :

How you bind your dropdownlist depends a lot on if it appears inside some other model bound control or not. To bind a dropdownlist inside of a model bound container (repeater, listview, formview, etc) looks something like this:

*.aspx.cs

<asp:DropDownList ID="MyDropDown" runat="server" 
	SelectMethod="GetMyDropDownItems"
	ItemType="MyApp.SomeNameSpace.SelectListItem" 
	DataTextField="Text" 
	DataValueField="Value"
	SelectedValue="<%# BindItem.EdCodeType %>" 
/>

*.aspx.cs

protected SelectList GetMyDropDownItems()
{
    var items = from t in someDbContext.AllThings
    select new { ID = t.ID, Name = t.Name };
    return new SelectList(items, "ID", "Name");
}

Note: SelectedValue property does NOT show up in intellisense. This appears to be a bug caused by the fact that this property was marked with the BrowsableAttribute set to false (for mysterious reasons). 

When working with a dropdownlist that is not conveniently nested within a model bound container control, binding the dropdown is still fairly simple. You have three options. You can explicitly declare a selected value, if you know what it is at design-time and it never changes. If that isn’t the case, then you can set the SelectedValue property to the results of some method call, or wire up an ondatabound event handler to set the selected item. Here are the examples:

Declarative example: Set SelectedValue to a known value (rarely helpful):

*.aspx.cs

<asp:DropDownList ID="MyDropDown" runat="server" 
	SelectMethod="GetMyDropDownItems"
	ItemType="MyApp.SomeNameSpace.SelectListItem" 
	DataTextField="Text" 
	DataValueField="Value"
	SelectedValue="1234" 
/>

Declarative example: Set SelectedValue to the result of a method call:

*.aspx

<asp:DropDownList ID="MyDropDown" runat="server" 
	SelectMethod="GetMyDropDownItems"
	ItemType="MyApp.SomeNameSpace.SelectListItem" 
	DataTextField="Text" 
	DataValueField="Value"
	SelectedValue="<%# GetSelectedItemForMyDropDown()%>"
/>

*.aspx.cs

private SelectList myDropDownItems;

protected SelectList GetMyDropDownItems()
{
	//store the selectlist in a private field for use by other events/methods later
	if(myDropDownItems == null)
	{
		var items = from t in someDbContext.AllThings
					select new { ID = t.ID, Name = t.Name };

		var selectedItems = from t in someDbContext.SelectedThings
					select new { ID = t.ID};

		myDropDownItems = new SelectList(items, "ID", "Name", selectedItems);
	}

	return myDropDownItems;
}

protected string GetSelectedItemForMyDropDown()
{
	var selected = GetMyDropDownItems().FirstOrDefault(i => i.Selected);
	return (selected != null) ? selected.Value : string.Empty;
}

Event example: Set Selected item from an event handler

*.aspx

<asp:DropDownList ID="MyDropDown" runat="server" 
	SelectMethod="GetMyDropDownItems"
	ItemType="MyApp.SomeNameSpace.SelectListItem" 
	DataTextField="Text" 
	DataValueField="Value"
	OnDataBound="MyDropDown_DataBound" 
/>

*.aspx.cs

private SelectList myDropDownItems;

protected SelectList GetMyDropDownItems()
{
	//store the selectlist in a private field for use by other events/methods later
	if(myDropDownItems == null)
	{
		var items = from t in someDbContext.AllThings
					select new { ID = t.ID, Name = t.Name };

		var selectedItems = from t in someDbContext.SelectedThings
					select new { ID = t.ID};

		myDropDownItems = new SelectList(items, "ID", "Name", selectedItems);
	}

	return myDropDownItems;
}

protected void MyDropDown_DataBound(object sender, EventArgs e)
{
	var ddl = (DropDownList)sender;
	var selectedValue = GetMyDropDownItems().FirstOrDefault(i => i.Selected);
	if(selectedValue != null)
	{
		ddl.Items.FindByValue(selectedValue.Value).Selected = true;
	}
}

With the ListBox control, and controls similar, you can employ the same techniques as long as you only allow single item selection. If you need to support multiple selection though, you can’t just set SelectedValue. Instead, you would use the DataBound event to loop each item to selecting the appropriate ones.

*.aspx

<asp:ListBox ID="MyListBox" runat="server"
	SelectionMode="Multiple"
	SelectMethod="GetMyListBoxItems"
	ItemType="Weber.Vfao.Inside.Web.SelectListItem"
	DataTextField="Text" 
	DataValueField="Value" 
	OnDataBound="MyListBox_DataBound"
/>

*.aspx.cs

private SelectList myListBoxItems;

protected SelectList GetMyListBoxItems()
{
	//store the selectlist in a private field for use by other events/methods later
	if(myListBoxItems == null)
	{
		var items = from t in someDbContext.AllThings
					select new { ID = t.ID, Name = t.Name };

		var selectedItems = from t in someDbContext.SelectedThings
					select new { ID = t.ID};

		myListBoxItems = new SelectList(items, "ID", "Name", selectedItems);
	}

	return myListBoxItems;
}

protected void MyListBox_DataBound(object sender, EventArgs e)
{
	var lb = (ListBox)sender;
	foreach (var item in GetMyListBoxItems())
	{
		if (item.Selected)
		{
			b.Items.FindByValue(item.Value).Selected = true;
		}
	}
}

ASP.NET MVC SimpleMembership – Initilization and New Project Template Issues

The ASP.NET MVC new project templates have been upgraded in Visual Studio 2012. Among the many improvements, was the change to using SimpleMembershipProvider. Simple they may be named, but I’ve found using it to be anything but simple. There are some deep design flaws in the provider, as well as how it is used in the stock MVC project templates.

The issues start with web.config. If you have worked with asp.net in the past, the most obvious difference in new web.config files will be the lack of configuration elements related to security providers.

Old templates had something like this:

<system.web>
       ... stuff ...
    <membership>
        <providers>
            <add name=".... />
        </providers>
    </membership>
    <profile>
        <providers>
            <add name=".... />
        </providers>
    </profile>
    <roleManager>
        <providers>
            <add name=".... />
        </providers>
    </roleManager>
    ... stuff ...
</system.web>

The new templates have none of these elements. There is a default connection in web.config, called DefaultConnection, and the templates use this connection for membership as well application data by default.

So far, so simple.

If you need to change the default behavior of SimpleMembership though, where do you make those changes? For example, I don’t like the default password length requirements, so I’ve always changed that in config. You can explicitly add the SimpleMembership provider to web.config, but doing so is useless. SimpleMembership just ignores settings in web.config. If you want to change the behavior, you have to track down the entity classes SimpleMembership is using (models/AccountModels.cs in the stock templates), and manually change the attributes in code.

While modifying settings in code isn’t hard, it is a truly horrible design. Your security configuration is scattered all over your model classes, and the runtime security policy is buried deep within compiled code, instead of a centralized configuration file where your server admin can get at it. This design also eliminates the option of using config transformations during build, publish, or deployment to customize the security policy for different target environments.

If you want to change the connection used by SimpleMembership, you no longer do this through web.config either. Instead, you have to track down the code that initializes the security system, which is inconveniently located in the /Filters/InitializeSimpleMembershipAttribute.cs file. Here, you need to update the call to WebSecurity.InitializeDatabaseConnection to pass in the correct name of your connection string. Not very intuitive, but that’s not the truly weird part either…

The weird part is that initialization for SimpleMembership, in the stock project templates, is done from an ActionFilterAttribute. This attribute decorates the AccountController class, and only that class. The result is that none of the SimpleMembership system will be initialized until a real user physically visits one of your account pages; login, register, or whatever.

If you write code in a page that allows anonymous access, or in a background or start-up routine, and it tries to do something related to membership, roles, or profiles you will get bizzare behavior. You would think that the code would just fail –the providers haven’t been initialized right?

The truth is much, much worse.

If code tries to do security stuff before SimpleMembership is explicitly initialized, asp.net will initialize the default security providers automatically. Instead of the SimpleMembership provider that you expected, it will initialize a SqlMembershipProvider using a connection named “LocalSqlServer”. This stuff is configured in the machine.config file, which includes the default configuration settings for SqlMembership, and points it at the local SQLExpress instance.

So, lets say you open up your new MVC project, which you created from the VS 2012 default template. You go to the HomeController, and edit the Index action to call Membership.GetAllUsers(). That’s all. You don’t need to do anything with the users, just ask for a list of them.

Then you run your application.

What do you think happens?

If your system is setup like most, you probably have SQL express installed. So, suddenly a mysterious aspnet.mdf file shows up in your app_data folder, and gets attached to your SQLExpress instance… and this all probably happens without you noticing it. If you don’t have a SQLExpress instance, your application will hang on startup for a long while, then timeout with “The system cannot find the file specified”.

I don’t know about anyone else, but I REALLY hate when an application starts making new databases on SQL servers that it shouldn’t even know exist.

Overall, I am not impressed with SimpleMembership, nor how the stock templates implement it. The providers are prone to unexpected and unintended behavior unless you have deep knowledge about their internal workings. Customizing SimpleMembership is the opposite of simple. And for configuration, it is confusing that it plugs into a standard asp.net feature, then ignores the traditional means of configuring that feature. And to top it off, requiring basic security configuration to be handled in code is a severely deranged design choice.