Just published our web app onto our customer's new web server for the first time and received an invalid NHibernate configuration error. Discovered it was due to the database connection string in the app.config file - it was still holding the value for the database server here in the office.
Discovered reference to SlowCheetah from Hanselman and went straight to NuGet to install the package. After checking out the proj file from our source control to allow SlowCheetah to do its thing and restarting Visual Studio, there was still no Add Transform menu option when right clicking the app.config file.
Managed to get it to show by downloading the extension from the msdn visualstudiogallery website and installing.
NeverDunCoding
Monday, 11 March 2013
Monday, 24 September 2012
SQL BCP outputting ÿ instead of spaces
Came across this today - a stored procedure of ours that bcp's out some data to a csv file started generating ÿ characters instead of spaces (the two dots being a German umlaut). Firing off the stored procedure manually did not show this character in the results window.
I could not find anything about it on the internet and it took a wee while of trial and error, but I eventually hit it lucky by changing following bcp statement from:
to:
The fixer is the change from -c to -w, using Unicode characters instead of a character data type. More on the tech of BCP here.
I could not find anything about it on the internet and it took a wee while of trial and error, but I eventually hit it lucky by changing following bcp statement from:
to:
The fixer is the change from -c to -w, using Unicode characters instead of a character data type. More on the tech of BCP here.
Thursday, 10 May 2012
Stand-up Meetings - so simple, so rewarding, so why aren't you doing it?
I first came across mention of stand-up meetings after my manager lent me The Art of Agile Development.
From the word go it felt right to me.
Too often in our office, we can go the whole day without talking to each other. This has negative implications on both a performance and a social level.
We were guilty of not really knowing what each other was doing, whether anybody was stuck in a rut or if we possibly had a solution to a problem somebody else was experiencing.
Also, there were days we resembled ships in the night, with a spoken word count of two - hello and goodbye! Not great for building relationships with people you spend approximately 40 hours a week with.
I let stand-ups brew for a few days in my head - the more it fermented, the more convinced I became that I was onto a winner. I informed my manager that I was planning to introduce stand-ups (giving him due credit for lending me the book whence the idea came from). He was thrilled and very encouraging - nice to have that kind of management buy-in.
I took the plunge and informed the troops of my intentions, receiving araptourous muted response of participation. There was no going back now - I had to follow through. And yes, the first one was nervous - for us all.
But after six months of hosting them, I can safely say that it has been one of the best things to happen to our development team since I have been there (nigh on 12 years and counting). And I highlight the term because that has been the number one outcome of this - we are no longer a group of developers but a team. Informing, discussing, joking, moaning, empathising - INTERACTING for at least 2 minutes every day!
If you are in a team leader/senior developer position and are not doing consistently regular stand up meetings, then I definitely recommend that you start. There is minimal overhead and the ROI is invaluable. There have been plenty of instances of somebody describing an issue they are investigating only to have another developer serve up a solution at the same meeting.
A few pointers from my own experience:
Do your fellow developers and your company/employer a massive favour and - stand up.
From the word go it felt right to me.
Too often in our office, we can go the whole day without talking to each other. This has negative implications on both a performance and a social level.
We were guilty of not really knowing what each other was doing, whether anybody was stuck in a rut or if we possibly had a solution to a problem somebody else was experiencing.
Also, there were days we resembled ships in the night, with a spoken word count of two - hello and goodbye! Not great for building relationships with people you spend approximately 40 hours a week with.
I let stand-ups brew for a few days in my head - the more it fermented, the more convinced I became that I was onto a winner. I informed my manager that I was planning to introduce stand-ups (giving him due credit for lending me the book whence the idea came from). He was thrilled and very encouraging - nice to have that kind of management buy-in.
I took the plunge and informed the troops of my intentions, receiving a
But after six months of hosting them, I can safely say that it has been one of the best things to happen to our development team since I have been there (nigh on 12 years and counting). And I highlight the term because that has been the number one outcome of this - we are no longer a group of developers but a team. Informing, discussing, joking, moaning, empathising - INTERACTING for at least 2 minutes every day!
If you are in a team leader/senior developer position and are not doing consistently regular stand up meetings, then I definitely recommend that you start. There is minimal overhead and the ROI is invaluable. There have been plenty of instances of somebody describing an issue they are investigating only to have another developer serve up a solution at the same meeting.
A few pointers from my own experience:
- Be committed, be consistent - if you go down this path (and as the blog title asks, why would you not), YOU drive these meetings. That is, you call the meetings every day without fail. It doesn't matter if you're not in the mood for whatever reason (ahem, previous night's alcohol comsumption), the meet still happens. Do not assume for one moment that any of the other developers will initiate them - why would they, it takes them away from coding.
- Do it in the morning. What time does your last developer walk in the door at? Add ten minutes to this and that's the time your morning meetings take place at. If you leave it to later in the day, then Murphy's Law dictates that something will happen to scupper the meeting. Also, there's less chance that you will be dragging somebody away while they are in the middle of the search for the unpaired bracket in a 20 line SQL statement.
- Follow the format as per the user manual at first, say a few weeks, and then tailor as you see fit. Let the other developers know this and that you would appreciate their feedback over this settling-in period.
Do your fellow developers and your company/employer a massive favour and - stand up.
Thursday, 23 February 2012
Table Valued Parameters, Custom Iterators and Stored Procedures in VB.Net
Ever since first reading about Table Valued Parameters introduced in SQL 2008, I have been longing to use them in my web development. A feeling not too unlike elation filled me at the thought of dustbin'ing the workarounds I had used in the past to store multiple records at once to the database (mainly SQL string building in a loop).
That feeling was short lived, however, when I realised that to use this new piece of kit, I would need to pump my VB.Net domain objects into DataTables before sending them on their way as TVPs. This definitely took the shine of the new kid on the block in my eyes - I connect with the ethos of domain driven design, even if I don't practice it perfectly, and having to mutate my creations into DataTables is the complete antithesis to this. I know DataTables have their place, but I decided that Business/Domain Objects were the best choice for the ever evolving enterprise application that I work on.
I came across one glimmer of hope here. More of a teaser I should say, in that Leonard specifically mentions that this is not possible in VB.Net. I toyed about with some of his suggested possible workarounds to no avail and left it back on the shelf.
It popped back into my head last week while working on my SQL stored procedure for generating domain object/repository/test VB.Net code. Looked through it again and done some fresh googling on the subject which lead me to the Asynch CTP extension for Visual Studio. Haven't even looked at any of the asynch stuff in it yet - what caught my eye was the inclusion of iterators for VB.Net.
Dusted off my test code and implemented the new VB.Net iterators. Some initial trial and error coding to get it just right, but I soon had multiple records storing over one SQL connection.
Start off with your table definition, create a type that mirrors it and a stored procedure that does the storing/updating. The SQL code I provide here is basic and not best practice, but it should be enough for you to get my drift. For better sample SQL code, look at Leonard's.
The VB.Net iterator goodness (note, it's worth a few minutes of your time acquainting yourself with the SqlDataRecord type and its members , which are used below in the conversion/mapping code below):
Obviously, this is a very basic example. Again, follow the link to Leonards post where he uses an order header with multiple order detail lines example.
That feeling was short lived, however, when I realised that to use this new piece of kit, I would need to pump my VB.Net domain objects into DataTables before sending them on their way as TVPs. This definitely took the shine of the new kid on the block in my eyes - I connect with the ethos of domain driven design, even if I don't practice it perfectly, and having to mutate my creations into DataTables is the complete antithesis to this. I know DataTables have their place, but I decided that Business/Domain Objects were the best choice for the ever evolving enterprise application that I work on.
I came across one glimmer of hope here. More of a teaser I should say, in that Leonard specifically mentions that this is not possible in VB.Net. I toyed about with some of his suggested possible workarounds to no avail and left it back on the shelf.
It popped back into my head last week while working on my SQL stored procedure for generating domain object/repository/test VB.Net code. Looked through it again and done some fresh googling on the subject which lead me to the Asynch CTP extension for Visual Studio. Haven't even looked at any of the asynch stuff in it yet - what caught my eye was the inclusion of iterators for VB.Net.
Dusted off my test code and implemented the new VB.Net iterators. Some initial trial and error coding to get it just right, but I soon had multiple records storing over one SQL connection.
Start off with your table definition, create a type that mirrors it and a stored procedure that does the storing/updating. The SQL code I provide here is basic and not best practice, but it should be enough for you to get my drift. For better sample SQL code, look at Leonard's.
The VB.Net iterator goodness (note, it's worth a few minutes of your time acquainting yourself with the SqlDataRecord type and its members , which are used below in the conversion/mapping code below):
Obviously, this is a very basic example. Again, follow the link to Leonards post where he uses an order header with multiple order detail lines example.
Saturday, 21 January 2012
Generate class code based on SQL table definition
I was looking for a quick way to generate the boilerplate code for a class based on the definition of a table in my SQL database. I recently started researching the various ORM offerings, but it's still quite early days and I'm looking for something simple that I can use in the meantime to help speed things up.
It dawned on me that I should be able to generate the code within SQL itself using the INFORMATION_SCHEMA.COLUMNS data of the table.
Below is a stored procedure that generates the VB code for a class based on a database table specified in the first parameter. Use the second parameter to specify the name of the class, or leave it as NULL for the Stored Procedure to assume that your table name is pluralised with an "s", therefore naming the class the same less the "s".
I'm using the wonderful little AutoMapper library in the generated code to automatically map the columns from the SQL query to the fields of the class. When I think of it, I'm trying to do for our class code what AutoMapper is doing for object-object mapping code - both of which are "rather dreary and boring to write".
As I got going with this, I realised that I needn't stop at the domain object class code. I'm also outputting the code for a backing repository class that does the database interaction and the code for a default unit test to check that the database retrieve works. I'm not claiming to be properly using the Repository Pattern here, I just think the term repository is appropriate. And it's more of an integration test than a unit test.
The SQL Stored Procedure code:
Execute the Stored Procedure and perform a bit of Copy-Paste Driven Development. If I get the team using this, then it also has the nice side affect of applying a standard coding pattern to our classes.
A quick and simple solution - no installation required!
It dawned on me that I should be able to generate the code within SQL itself using the INFORMATION_SCHEMA.COLUMNS data of the table.
Below is a stored procedure that generates the VB code for a class based on a database table specified in the first parameter. Use the second parameter to specify the name of the class, or leave it as NULL for the Stored Procedure to assume that your table name is pluralised with an "s", therefore naming the class the same less the "s".
I'm using the wonderful little AutoMapper library in the generated code to automatically map the columns from the SQL query to the fields of the class. When I think of it, I'm trying to do for our class code what AutoMapper is doing for object-object mapping code - both of which are "rather dreary and boring to write".
As I got going with this, I realised that I needn't stop at the domain object class code. I'm also outputting the code for a backing repository class that does the database interaction and the code for a default unit test to check that the database retrieve works. I'm not claiming to be properly using the Repository Pattern here, I just think the term repository is appropriate. And it's more of an integration test than a unit test.
The SQL Stored Procedure code:
Execute the Stored Procedure and perform a bit of Copy-Paste Driven Development. If I get the team using this, then it also has the nice side affect of applying a standard coding pattern to our classes.
A quick and simple solution - no installation required!
Monday, 2 January 2012
Localized jQueryUI dialog titles in ASP.net webforms
Following on from the localization process described in my earlier post, here's how it rolls when I'm using the brilliant jQueryUI modal dialogs.
A lot of the application's web pages use the same modal dialog, for example to choose a customer. I have used ASP.net usercontrols to wrap up the HTML/ASP.net markup and then re-use them throughout the application.
The usercontrol contains a jTemplates template to build a table based on the result of a jQuery ajax call.
Datatables.js is used to enable paging and searching.
Excuse the endscript tag included in the below snippet, but SyntaxHighlighter was interpreting the closing script tag as the end of the code snippet.
I am able to use the same ExpressionBuilder based localisation technique within the user control to provide translations for the labels of the buttons and column headers. Even within the jTemplates script, the ASP.Net engine recognises the ExpressionBuilder tags and evaluates them accordingly.
The one item that I was not able to translate directly was the dialog title supplied in the call to the jQueryUI dialog function. Instead of a direct attack, a flanking maneuver was required.
Inside each usercontrol's declaration, I include a hidden input form whose value is set using my ExpressionBuilder Translate function. A CSS class of "title" is assigned to it. When instantiating the dialog, I pass reference to this hidden field for assigning the dialog title.
A lot of the application's web pages use the same modal dialog, for example to choose a customer. I have used ASP.net usercontrols to wrap up the HTML/ASP.net markup and then re-use them throughout the application.
The usercontrol contains a jTemplates template to build a table based on the result of a jQuery ajax call.
Datatables.js is used to enable paging and searching.
Excuse the endscript tag included in the below snippet, but SyntaxHighlighter was interpreting the closing script tag as the end of the code snippet.
I am able to use the same ExpressionBuilder based localisation technique within the user control to provide translations for the labels of the buttons and column headers. Even within the jTemplates script, the ASP.Net engine recognises the ExpressionBuilder tags and evaluates them accordingly.
The one item that I was not able to translate directly was the dialog title supplied in the call to the jQueryUI dialog function. Instead of a direct attack, a flanking maneuver was required.
Inside each usercontrol's declaration, I include a hidden input form whose value is set using my ExpressionBuilder Translate function. A CSS class of "title" is assigned to it. When instantiating the dialog, I pass reference to this hidden field for assigning the dialog title.
Thursday, 15 December 2011
Localisation in an ASP.Net WebForms Application - A Lightweight, Dynamic and Database-driven solution
Not so long ago, a new customer presented my team with the opportunity to deliver our .Net webforms application to a non-English speaking user base for the first time.
What a challenge - retrofitting globalisation into our behemoth enterprise application.
Wunderbar, merveilleux, замечательный!!!
Ahem - yes, I was excited.
Most likely due to my database intensive upbringing, I was biased towards the translations being in a database table instead of .Net resource files, so that's the way it rolled.
My implementation is basic for now, catering for just one language per country at the moment. To date, we have 5 languages set up, one of them being Ukrainian - I still get a buzz when I log onto our site and see it inKlingon Cyrillic.
I'm happy with what I've got and the best indicator of its success is that the other developers were using it from day 1 with no need for any guidance. They know nothing of the internals - it just works.
And the results are visible immediately on the webpage.
A nice side-effect of this approach is that new translations can be added through the website by the customers instead of passing them to us for updating a resx file and the subsequent recompilation of the web app this would entail. This is very beneficial to us as we are effectively outsourcing our localisation. And in an application that uses very domain-specific terminology/jargon, a simple Google translate would not work.
The solution described below makes use of Expression Builders to dynamically set the text for HTML or ASP.Net Controls (they need to be runat="server"). For example:
Any attempted translations that do not have an entry in the database are returned to the webpage as the id code pre-fixed with an x.
Any attempted translations that have an English but no corresponding foreign translation are prefixed with an _ underscore - this is carried out in the SQL statement.
Our aim is that the foreign language administrators will never see an x, otherwise they should inform us. When they come across an underscored term, they know they must add a translation in the maintenance screen.
To prevent database connection overload and prevent performance issues, the translations are stored in cache. They are an ideal candidate for caching - relatively static content that rarely changes and used quite extensively.
Upon each update to the Translations table from within the class, the translations cache is refreshed. May seem a bit heavy handed, but additions/changes to the translations are very infrequent. Each request for a translation calls a function (PopulateTranslationCache) to ensure that the cache is populated.
The elements required are:
Expression Builder
Web.config:
TranslationExpressionBuilder.vb:
Translation.vb: Web Form:
References:
http://stackoverflow.com/questions/699911/application-variable-in-sqldatasource-control-parameter
http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx
http://weblogs.asp.net/ricardoperes/archive/2009/03/04/useful-expression-builders.aspx
http://www.4guysfromrolla.com/articles/030409-1.aspx
What a challenge - retrofitting globalisation into our behemoth enterprise application.
Wunderbar, merveilleux, замечательный!!!
Ahem - yes, I was excited.
Most likely due to my database intensive upbringing, I was biased towards the translations being in a database table instead of .Net resource files, so that's the way it rolled.
My implementation is basic for now, catering for just one language per country at the moment. To date, we have 5 languages set up, one of them being Ukrainian - I still get a buzz when I log onto our site and see it in
I'm happy with what I've got and the best indicator of its success is that the other developers were using it from day 1 with no need for any guidance. They know nothing of the internals - it just works.
And the results are visible immediately on the webpage.
A nice side-effect of this approach is that new translations can be added through the website by the customers instead of passing them to us for updating a resx file and the subsequent recompilation of the web app this would entail. This is very beneficial to us as we are effectively outsourcing our localisation. And in an application that uses very domain-specific terminology/jargon, a simple Google translate would not work.
The solution described below makes use of Expression Builders to dynamically set the text for HTML or ASP.Net Controls (they need to be runat="server"). For example:
Any attempted translations that do not have an entry in the database are returned to the webpage as the id code pre-fixed with an x.
Any attempted translations that have an English but no corresponding foreign translation are prefixed with an _ underscore - this is carried out in the SQL statement.
Our aim is that the foreign language administrators will never see an x, otherwise they should inform us. When they come across an underscored term, they know they must add a translation in the maintenance screen.
To prevent database connection overload and prevent performance issues, the translations are stored in cache. They are an ideal candidate for caching - relatively static content that rarely changes and used quite extensively.
Upon each update to the Translations table from within the class, the translations cache is refreshed. May seem a bit heavy handed, but additions/changes to the translations are very infrequent. Each request for a translation calls a function (PopulateTranslationCache) to ensure that the cache is populated.
The elements required are:
- Inclusion of the expression signature in the Web.config file.
- TranslationExpressionBuilder.vb - A class that declares the expression to be used and returns the value of the function (the translated text) referenced by the expression.
- Translation.vb - A class that represents the translation object and maps the object fields to the corresponding columns in the database. This will also include the functions required to return the translation to the expression class. A delegate was used as lambdas were not hanging out on the VB scene at the time. (I need to come back to this class and apply the Single Responsibility Principle.)
- The database table to store text and their translations.
- And, of course, an ASP .Net web form that uses the translation expression to evaluate text for controls on the page.
Expression Builder
Web.config:
TranslationExpressionBuilder.vb:
Translation.vb: Web Form:
References:
http://stackoverflow.com/questions/699911/application-variable-in-sqldatasource-control-parameter
http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx
http://weblogs.asp.net/ricardoperes/archive/2009/03/04/useful-expression-builders.aspx
http://www.4guysfromrolla.com/articles/030409-1.aspx
Subscribe to:
Posts (Atom)