If you ever had an enumerable list but wanted to include 'friendly names' with the list, this is how you can do it using Extension methods.
Create an extension Method
public static string Description(this Enum enumValue)
{
var enumType = enumValue.GetType();
var field = enumType.GetField(enumValue.ToString());
var attributes = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length == 0 ? enumValue.ToString() : ((DescriptionAttribute)attributes[0]).Description;
}
Define an Enum
public enum AnEnum
{
[Description("First")]Val1,
[Description("Second")]Val2
}
Use the enum
var displayName = AnEnum.Val1.Description();
Friday, April 20, 2012
Quick Tip: C# Strongly Typed Property Name
A quick and easy way to use a type safe (compiler-aware) lambda expresssion
public string GetPropertyName<TSource, TResult>(Expression<Func<TSource, TResult>> propertyExpression)
{
var memberExpression = propertyExpression.Body as MemberExpression;
return memberExpression != null ? memberExpression.Member.Name : null;
}
Then call
GetPropertyName<LocalGovernment, string>(x => x.LocalGovernmentName)
Originally found here:
http://stackoverflow.com/questions/1417383/how-to-get-properties-names-from-object-parameter
public string GetPropertyName<TSource, TResult>(Expression<Func<TSource, TResult>> propertyExpression)
{
var memberExpression = propertyExpression.Body as MemberExpression;
return memberExpression != null ? memberExpression.Member.Name : null;
}
Then call
GetPropertyName<LocalGovernment, string>(x => x.LocalGovernmentName)
Originally found here:
http://stackoverflow.com/questions/1417383/how-to-get-properties-names-from-object-parameter
Labels:
C#,
Lamda,
Property Name,
Strongly Typed,
type safe
Thursday, April 19, 2012
Developer Collaboration / Knowledge Sharing
As a consultant for a large company you are often segregated from your peers, often by physical location, for what can be extended periods of time.
For me this poses a very important problem, and that is the sharing of knowledge within the company. When a developer goes out to a client, they can build a vast range of knowledge that is never then shared back to the broader development team. Sometimes even knowledge within a team at a client site is not shared effectively, leading to a lack of growth within the team, and lack of understanding and standardisation within the delivered products.
Formal training can be used to bring everyone to a certain level of knowledge, but training rarely imparts the knowledge of best practice or the results of experience.
Developer-led workshops are often better at imparting specialised knowledge but they are dependent on attendence, prerequisite knowledge and can suffer from a lack of follow-up material. It can also require significant time investment on the team, where physical segregation and time management has significant issues.
Wiki's and blogs can provide as much information as developer-led workshops, but suffer from lack of accessibility and relevance, and the lack of immediacy of queries and responses, so while it is a useful way to store information, it is not always useful for sharing information.
For me, the above scenarios seem to be the most commonly used way to share information, and do help to at least some degree. However it is also lacking in so many ways to really bridge the gap of knowledge within a large group of developers.
I think the popularity of social media shows how easy it can be to share information between peers if it is easy to share, and easy to search. Stack Overflow is an outstanding example, where the community is answering the questions of other developers and in the process sharing their own knowledge and experience. I would like to see something that is almost the opposite of this as well, where developers can share snippets of code that they have used to solve a particular issue, or that can be extremely useful in a variety of situations. CodeProject is a bit like this, but the 'gamification' and 'accessiblity' of stack overflow makes it a significantly more relevant tool.
So for those of you working in the industry, how do you ensure everyone has access to the knowledge and experience of your most effective developers.
For me this poses a very important problem, and that is the sharing of knowledge within the company. When a developer goes out to a client, they can build a vast range of knowledge that is never then shared back to the broader development team. Sometimes even knowledge within a team at a client site is not shared effectively, leading to a lack of growth within the team, and lack of understanding and standardisation within the delivered products.
Formal training can be used to bring everyone to a certain level of knowledge, but training rarely imparts the knowledge of best practice or the results of experience.
Developer-led workshops are often better at imparting specialised knowledge but they are dependent on attendence, prerequisite knowledge and can suffer from a lack of follow-up material. It can also require significant time investment on the team, where physical segregation and time management has significant issues.
Wiki's and blogs can provide as much information as developer-led workshops, but suffer from lack of accessibility and relevance, and the lack of immediacy of queries and responses, so while it is a useful way to store information, it is not always useful for sharing information.
For me, the above scenarios seem to be the most commonly used way to share information, and do help to at least some degree. However it is also lacking in so many ways to really bridge the gap of knowledge within a large group of developers.
I think the popularity of social media shows how easy it can be to share information between peers if it is easy to share, and easy to search. Stack Overflow is an outstanding example, where the community is answering the questions of other developers and in the process sharing their own knowledge and experience. I would like to see something that is almost the opposite of this as well, where developers can share snippets of code that they have used to solve a particular issue, or that can be extremely useful in a variety of situations. CodeProject is a bit like this, but the 'gamification' and 'accessiblity' of stack overflow makes it a significantly more relevant tool.
So for those of you working in the industry, how do you ensure everyone has access to the knowledge and experience of your most effective developers.
Monday, April 16, 2012
Incomplete HTML5 is Incomplete
Or why HTML5 is not close to being ready for LOB.
I have always given JavaScript a bit of a bad rap, and to be honest a lot of it comes down to not being as proficient with it as I am at my meat and potatoes c# development. That and the lack of toolset support to rival C# development in Visual Studio.
However I have been using it more recently, both in my at work projects and personal projects. This is largely due to my pushing the adoption of ASP.NET MVC at work, which is really helping leverage Javascript rather than the kludges and hacks of the old WebForms way.
While we are currently still targetting HTML4 for our LOB systems, I have been working on various HTML5 personal projects to get a feel for how we can leverage the new features of HTML5 going forward. And it is not as pretty as I had been led to believe.
By "HTML5" I mean the buzzword that it entails, so in reality HTML5, CSS3, JavaScript etc, it is just easier to go with HTML5. And in fact the Actual issue I want to raise here is with the HTML5 specification. While most of the buzz about HTML5 is about fancy CSS3 animations, gradients, or html canvas and media tags, when it comes to LOB data/forms is king.
HTML5 Forms
So HTML5 has a large number of new fieds (email, tel, number, etc) and utilities (autofocus, placeholder). These range from very useful (autofocus, placeholder, range) to simply handy (with validation being pretty standard now, fields for email, telephone, etc are fairly uninspiring).
However trying to get these working consistently across browser version is an excercise in futility for the conceivable future.
For example, I attempted to have a page with a Range element, which is unsupported in most browsers at this stage. OK, I'll use a JQuery Range control then, which worked fine. Except that I was using the same scripting (KnockoutJS) to bind to my form for a JQuery Mobile targeted page too, which requires the use of the HTML5 range element. There was no way I could provide a solution that would work without a fully separate page renderer and script, or a bunch of browser/compatibility checks. I actually needed 3 different browsers to do the testing, a Local IE, Firefox (with User Agent Switching to iOS) and my Android device (which led to further issues of having to host in IIS instead of the Visual Studio IIS Express to allow for external access).
Isn't HTML5 supposed to be the great consolidator?
HTML5 Data
Local Data has even been removed from the HTML5 specification, so while basic 'DOM Storage' is available (basic key-value store) in prettymuch all browsers, the much hyped "webdb" support is completely non-standard and generally browser specific, which in essence means you either write a library for each browser, or you don't use it.
The final word
In even just a basic usage scenario I came across a severe lack of cross-compatibility issues when attemtping to build an HTML5 application that can work across browsers and in the mobile space. Until HTML5 becomes standardised, or at least the features become supported in mainstream browsers at least to some level of consistency, HTML5 is not going to be the be-all and end-all for LOB solutions.
If you have to rewrite your UI and scripts for each browser / mobile platform, then HTML5 offers little compelling benefit over current methods where you implement rich web technologies via Silverlight using vastly superior (YMMV) tools and service the mobile space with custom/expensive native apps, or basic html interfaces.
This is a little bit exaggerated, but it is at least a small counter to the 'silverlight is dead' brigade. I am currently very happy developing well designed MVC4 applications over Silverlight at the moment however, I just think the 'HTML5 will save us all' attitude is a little premature in the LOB space when it is still so hard to get something simple done consistently in HTML5.
I have always given JavaScript a bit of a bad rap, and to be honest a lot of it comes down to not being as proficient with it as I am at my meat and potatoes c# development. That and the lack of toolset support to rival C# development in Visual Studio.
However I have been using it more recently, both in my at work projects and personal projects. This is largely due to my pushing the adoption of ASP.NET MVC at work, which is really helping leverage Javascript rather than the kludges and hacks of the old WebForms way.
While we are currently still targetting HTML4 for our LOB systems, I have been working on various HTML5 personal projects to get a feel for how we can leverage the new features of HTML5 going forward. And it is not as pretty as I had been led to believe.
By "HTML5" I mean the buzzword that it entails, so in reality HTML5, CSS3, JavaScript etc, it is just easier to go with HTML5. And in fact the Actual issue I want to raise here is with the HTML5 specification. While most of the buzz about HTML5 is about fancy CSS3 animations, gradients, or html canvas and media tags, when it comes to LOB data/forms is king.
HTML5 Forms
So HTML5 has a large number of new fieds (email, tel, number, etc) and utilities (autofocus, placeholder). These range from very useful (autofocus, placeholder, range) to simply handy (with validation being pretty standard now, fields for email, telephone, etc are fairly uninspiring).
However trying to get these working consistently across browser version is an excercise in futility for the conceivable future.
For example, I attempted to have a page with a Range element, which is unsupported in most browsers at this stage. OK, I'll use a JQuery Range control then, which worked fine. Except that I was using the same scripting (KnockoutJS) to bind to my form for a JQuery Mobile targeted page too, which requires the use of the HTML5 range element. There was no way I could provide a solution that would work without a fully separate page renderer and script, or a bunch of browser/compatibility checks. I actually needed 3 different browsers to do the testing, a Local IE, Firefox (with User Agent Switching to iOS) and my Android device (which led to further issues of having to host in IIS instead of the Visual Studio IIS Express to allow for external access).
Isn't HTML5 supposed to be the great consolidator?
HTML5 Data
Local Data has even been removed from the HTML5 specification, so while basic 'DOM Storage' is available (basic key-value store) in prettymuch all browsers, the much hyped "webdb" support is completely non-standard and generally browser specific, which in essence means you either write a library for each browser, or you don't use it.
The final word
In even just a basic usage scenario I came across a severe lack of cross-compatibility issues when attemtping to build an HTML5 application that can work across browsers and in the mobile space. Until HTML5 becomes standardised, or at least the features become supported in mainstream browsers at least to some level of consistency, HTML5 is not going to be the be-all and end-all for LOB solutions.
If you have to rewrite your UI and scripts for each browser / mobile platform, then HTML5 offers little compelling benefit over current methods where you implement rich web technologies via Silverlight using vastly superior (YMMV) tools and service the mobile space with custom/expensive native apps, or basic html interfaces.
This is a little bit exaggerated, but it is at least a small counter to the 'silverlight is dead' brigade. I am currently very happy developing well designed MVC4 applications over Silverlight at the moment however, I just think the 'HTML5 will save us all' attitude is a little premature in the LOB space when it is still so hard to get something simple done consistently in HTML5.
Labels:
HTML5,
Jquery,
JQuery Mobile,
KnockoutJS,
LOB,
MVC,
not ready,
Silverlight
Tuesday, March 13, 2012
MVC4 Mobile and Desktop Web
As LoB applicatons are what I do on a daily basis, I have been looking at how we can use our existing expertise to build mobile applications.
This is the third component of my analysis (but only the second to be blogged), my android analysis can be found here.
As MVC4 has some improved web applications development features, such as Single Page Application templates, Mobile Application Templates, and the Web API, I decided to use this. I already blogged how the initial project templates were slightly confusing, so this time I decided to start with a standard template, and build from there.
Steps I took to getting up and running
Once this was done, I had a functional website that I wanted to convert to a mobile friendly solution.
We now have a mobile styled page and a desktop styled page using a single codebase. The next step would be to update the View to provide better mobile styling features, but I won't go into that here.
This is the third component of my analysis (but only the second to be blogged), my android analysis can be found here.
As MVC4 has some improved web applications development features, such as Single Page Application templates, Mobile Application Templates, and the Web API, I decided to use this. I already blogged how the initial project templates were slightly confusing, so this time I decided to start with a standard template, and build from there.
Steps I took to getting up and running
- Set up the Framework and Business Logic - this is becoming second nature
- Set up a plain MVC Project
- Create my page Controller and default view
- Create my ApiController for the get/post operations
- I recommend firefox for testing this, IE doesn't do JSON very well and firefox made debugging much easier.
- Firefox (with the user agent spoofing plugin) also makes it easy to test the mobile enhancements.
- Create a script for the KnockoutJS ViewModel
- This included the ajax calls to the ApiController to load and update data. I was unpleasantly surprised to see that while firefox worked immediately, IE10 (win8) required a lot of tweaking and in the end I had to switch from $.getJSON() to $.ajax() jquery calls.
- As I am creating a multi-page application I defined this at the View level.
- At this point I also had to modify the 'bundle' in global.js to include KnockoutJS - the default bundle definition did not include this. As a side note, I completely removed the default bundling later on, and created the bundles explicitly. This was necessary to ensure the mobile and desktop script bundles were used correctly.
- Update my View to use the KnockoutJS bindings
Once this was done, I had a functional website that I wanted to convert to a mobile friendly solution.
- Install (Nuget) JQuery Mobile
- Create a new script bundle to include JQuery Mobile js and css files
- Create a new _Layout.cshtml called _Layout.mobile.cshtml - this should use the mobile script bundle in the script header.
- This is a cool feature in MVC4, when a mobile agent is detected, the ".mobile" content is rendered, not the standard view
- Update _Layout.mobile.cshtml to use the JQuery mobile data-role attributes for layout
We now have a mobile styled page and a desktop styled page using a single codebase. The next step would be to update the View to provide better mobile styling features, but I won't go into that here.
Thursday, March 8, 2012
MVC4 Single Page Basics
I recently highlighted that I had a bit of an issue with the MVC4 tutorials that are available here as I do not believe the standard application structure for the default apps is adequately documented.
I also note that there are some unnecessary differences between the base templates that can further confuse the issue, predominantly in the View definitions, that make it difficult to discern the important differences between the template types e.g. Single Page Applications / Mobile applications / Web API.
For example, the Login.cshtml Header in the mobile template is defined as
@section Header {
@Html.ActionLink("Cancel", "Index", "Home", null, new { data_icon = "arrow-l", data_rel = "back" })
<h1>@ViewBag.Title</h1>
}
while in the SPA application it is defined as
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
<h2>Enter your user name and password below.</h2>
</hgroup>
Now there is a realistic need for the actions to be defined in the mobile header and not in the SPA header, BUT I think the differing use of hgroup and @section Header should have been standardised.
As for a lack of basic plumbing documentation, I think the SPA application is very lacking in this area. The tutorials are very good at showing how the data access and data binding works, but one thing that really stood out for me was the lack of information on how the login page was loaded in a popup and how the actions were resolved as Ajax actions instead of standard actions.
Looking into the code it wasn't actually that difficult to identify where things were happening, for example the line
<script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script>
in the _layout file loads all the javascript code in the scripts folder, which in turn loaded the AjaxLogin script file.
The code below then overrides the onclick of the login links to render the link content in a popup instead of a new page.
// List of link ids to have an ajax dialog
var links = ['#loginLink', '#registerLink'];
$.each(links, function (i, id) {
$(id).click(function (e) {
var link = $(this),
url = link.attr('href');
if (!dialogs[id]) {
loadAndShowDialog(id, link, url);
} else {
dialogs[id].dialog('open');
}
// Prevent the normal behavior since we use a dialog
e.preventDefault();
});
});
The loadDialog function sets an additional query parameter (content=1) which the Controller accepts and renders a PartialView instead of a View (in ContextDependentView(), and prefixes "Json" to the action property in the ViewBag. The View itself uses this 'action property' as the post action, which ensures that the correct Action is called (either JsonAction or just Action) is called on the HttpPost for the View.
Yes once you know what is going on it is easy to follow, but all this detail is very important to the way Single Page Applications work, as much if not moreso than how to use upshot and knockout, and it is just left to developer to figure it out.
Anyway, this is Beta, but I just thought that for something so central to the development experience with Mvc4 there should be more emphasis on the basics to ensure that people understand what is happening rather than just guiding them directly to loading data.
I also note that there are some unnecessary differences between the base templates that can further confuse the issue, predominantly in the View definitions, that make it difficult to discern the important differences between the template types e.g. Single Page Applications / Mobile applications / Web API.
For example, the Login.cshtml Header in the mobile template is defined as
@section Header {
@Html.ActionLink("Cancel", "Index", "Home", null, new { data_icon = "arrow-l", data_rel = "back" })
<h1>@ViewBag.Title</h1>
}
while in the SPA application it is defined as
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
<h2>Enter your user name and password below.</h2>
</hgroup>
Now there is a realistic need for the actions to be defined in the mobile header and not in the SPA header, BUT I think the differing use of hgroup and @section Header should have been standardised.
As for a lack of basic plumbing documentation, I think the SPA application is very lacking in this area. The tutorials are very good at showing how the data access and data binding works, but one thing that really stood out for me was the lack of information on how the login page was loaded in a popup and how the actions were resolved as Ajax actions instead of standard actions.
Looking into the code it wasn't actually that difficult to identify where things were happening, for example the line
<script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script>
in the _layout file loads all the javascript code in the scripts folder, which in turn loaded the AjaxLogin script file.
The code below then overrides the onclick of the login links to render the link content in a popup instead of a new page.
// List of link ids to have an ajax dialog
var links = ['#loginLink', '#registerLink'];
$.each(links, function (i, id) {
$(id).click(function (e) {
var link = $(this),
url = link.attr('href');
if (!dialogs[id]) {
loadAndShowDialog(id, link, url);
} else {
dialogs[id].dialog('open');
}
// Prevent the normal behavior since we use a dialog
e.preventDefault();
});
});
The loadDialog function sets an additional query parameter (content=1) which the Controller accepts and renders a PartialView instead of a View (in ContextDependentView(), and prefixes "Json" to the action property in the ViewBag. The View itself uses this 'action property' as the post action, which ensures that the correct Action is called (either JsonAction or just Action) is called on the HttpPost for the View.
Yes once you know what is going on it is easy to follow, but all this detail is very important to the way Single Page Applications work, as much if not moreso than how to use upshot and knockout, and it is just left to developer to figure it out.
Anyway, this is Beta, but I just thought that for something so central to the development experience with Mvc4 there should be more emphasis on the basics to ensure that people understand what is happening rather than just guiding them directly to loading data.
MVC4
I have avoided really learning JavaScript for web development for a little while now. Or at least I have always had other things come up that has taken precedence. Despite one fairly large ExtJS project, and a smattering of JQuery controls, I have not spent much time learning JavaScript, HTML5, or CSS3.
With the release of MVC4 beta I decided to really try and get stuck into JavaScript and at the same time work on Mobile application development for rich internet apps.
One thing that I think is really lacking in the MVC javascript demos however is an explanation of the basic components of the projects. All the demos highlight how easy it is to load and manipulate data through the web api, and bind to elements on the page, but there is very little on the application plumbing, how pages are rendered, how navigation works, how the partial views are rendered to popups, etc. All of this requires diving into the code to work it out.
So hopefully in the coming weeks I'll post a few guides on these 'basics' as I start to build up my own knowledge.
With the release of MVC4 beta I decided to really try and get stuck into JavaScript and at the same time work on Mobile application development for rich internet apps.
One thing that I think is really lacking in the MVC javascript demos however is an explanation of the basic components of the projects. All the demos highlight how easy it is to load and manipulate data through the web api, and bind to elements on the page, but there is very little on the application plumbing, how pages are rendered, how navigation works, how the partial views are rendered to popups, etc. All of this requires diving into the code to work it out.
So hopefully in the coming weeks I'll post a few guides on these 'basics' as I start to build up my own knowledge.
Subscribe to:
Posts (Atom)