
Back to Blog index.
As the end of the year is really close, it's time for a friendly reminder: next year, the RSS URL of this blog will be:
http://www.saunalahti.fi/janij/blog/2012.xml
At this writing, this URL does not work just yet, but will very soon. :-)
Windows 8, Visual Studio 11 and .NET 4.5 are all the buzzwords for the next year. Of course, learning about the new features has already started, and there's already tons of material available. Just lately, one more such resource came available, as Microsoft published the Visual Studio 11 Developer Preview Training Kit.
I had the change to briefly look at the training kit, and it looks very nice. I'm looking forward to investigate it further, as there are tons of exciting things to learn with the coming-up technologies!
This blog post is about an older but still highly useful Visual Studio feature: pinning a watch value's tooltip to the screen so that is always visible. This feature was introduced in Visual Studio 2010, so it's something that is already about two years old, but since I do get questions about this command from time to time, I thought it proper to share.
Firstly, the command name is officially Pin to Source. This command can be found in the code editor when right-clicking a variable name while debugging your application (and the application is stopped on a breakpoint, for instance).
When you move your mouse cursor over a variable, Visual Studio will display the variable's value in a DataTip. However, the problem with this feature is that as soon as you move your mouse out from the variable name, the tooltip disappears.
This is where the Pin to Source command comes to the rescue. Right-click the variable in your code editor, choose the command, and there you have it: a sticky DataTip that stays on the screen even if you move your mouse. What's more, the tip of updated whenever the monitored value changes, and you can even write quick comments next to the tip to records small amounts of information.
Hope this feature helps you in your debugging sessions!
Merry Christmas to everybody! Windows Forms developers might be "out" according to some .NET developers, but rest assured, the trusted technology is easy to master. Still, there are certain points where newcoming developers seem to struggle. One of them is the process of creating multi-threaded applications and updating the user interface from a thread.
Yes, this is an age-old problem, but still when trying to point developers asking the question to good and easy resource with a clean code sample, I only find solutions that are either complex or not up-to-date with current C#.
Firstly, let's assume your WinForms application has a second thread, from which you want to update a control on the user interface. Say, a log memo or a progress bar, for instance. If you try to say for example:
queryLogTextBox.Text = DateTime.Now.ToString() + ": " + message + ".\r\n" + queryLogTextBox.Text;
...in a thread, you will get an InvalidOperationException with the message "Cross-thread operation not valid: Control 'queryLogTextBox' accessed from a thread other than the thread it was created on."
Okay, good. So you know about Control.Invoke, and you know that it takes a delegate. Given this knowledge, you might be temped to think that you could simply use an anonymous method:
this.Invoke(delegate()
{
queryLogTextBox.Text = DateTime.Now.ToString() +
": " + message + ".\r\n" + queryLogTextBox.Text;
});
Unfortunately, this doesn't work in C#, because the method excepts a delegate type, not directly an anonymous method (compare this to for example Thread class' constructor). If you try this, you will get an compiler error with the message "Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type."
Okay, fair enough. But what then would be the easiest solution to this, when still using anonymous methods?
Enter the Action type, which is a delegate type for a method that doesn't return anything (void). By passing in a new Action object to Control.Invoke, the compiler is happy again. For example like this:
this.Invoke(new Action(() => queryLogTextBox.Text = DateTime.Now.ToString() + ": " + message + ".\r\n" + queryLogTextBox.Text));
Hope this helps!
If you are developing ASP.NET web application for public use, chances are you are using Forms authentication to authenticate your users. By default, the ASP.NET template implementation will redirect the user back to the page where s/he was before the authentication, if the user tried to directly access a page requiring authentication.
How ever, by default, the redirection URL is not checked, and it could be a full, absolute URL pointing anywhere, event to a malicious site. This is called an Open Redirection Attack, but luckily, it can easily be remedied.
There's a nice post on the ASP.NET MVC tutorials about this. Notice that even though the article talks about ASP.NET MVC, this same issue applies to regular Web Forms applications as well.
Promise yourself a little more secure year 2012, and take a quick peek on your web application(s). Implementing this fix really doesn't take that long.
Safe hacking!
The December issue of Tietokone contains my latest technical article, this time about cloud computing risks and the management of these risks. The article is titled "Pilvipalveluiden riskit" and starts on page 61.
Products/services features include Google Apps, Microsoft Azure and Amazon EC2.
Happy reading!
Sooner or later, the database application you have developed requires a backup plan. Nobody is going to cheer if you force your customers to take manual backups. Automation is the key here, so this is what you should strive for.
Automatically creating an SQL Server database backup can be done using the BACKUP DATABASE command, which can be executed either manually from SQL Server Management Studio (SSMS), or from the command-line with the help of the SQLCMD utility.
To take a backup, you need to know the SQL Server name (host or IP address), possible instance name and the database name. Furthermore, you need suitable credentials. Windows authentication can be a big help here, and also improves security as you don't need to include the username and password as plaintext strings in a Windows batch file (.cmd file).
The BACKUP DATABASE command also requires a destination filename. This filename often the biggest pain point, because you need to figure out a unique filename for each backup file so that the latest backup does not overwrite the previous one.
In Windows batch files, there are limited ways in which you can manipulate strings (and dates), but luckily, this can be done using environment variables. The SET command contains special support for taking substrings out of variable values, and this in turn can be used to retrieve the current year, month and day of the current date and time. This allows you to create unique filenames assuming that you take a backup only once per day.
Let's take a look at a script that parses the current date and time to its parts: the year, the month and the day:
@echo off rem ** Create a string with format "yyyy-mm-dd" set backup_day=%date:~3,2% set backup_month=%date:~6,2% set backup_year=%date:~-4% set backup_datestring=%backup_year%-%backup_month%-%backup_day%
The main thing here is the special batch file variable called %date% which returns the current date and time in the format local to the current user's regional settings. For example here in Finland, it returns a string like: "la 31.12.2011" ("la" stands for the acronym of Saturday in Finnish, notice the format dd.mm.yyyy).
The parsing commands with the set command allow you to use the :~ operator to retrieve parts of this string based on zero-based character indexes. The specification "3,2" would take two characters starting from the index three (fourth character), i.e. in this case, "31". Similarly, "6,2" would take the numbers "12", i.e. December. The specification "-4" would take four last characters from the string, in this case the year "2011".
Of course, this requires adjustment for each Windows locale, but with some tweaking, you could make it rather universal. I have hard time finding the official documentation for this on the Technet libraries, but if you run "set /?" on the command line, the second page talks about substring expansion. This seems to be the official name for the feature. You can also find tips on this here, here and here.
Now that we have the date and time parsed (as to make sure our filenames are unique), we can run the actual backup. This could be done as follows:
... cd /d "C:\Program Files\Microsoft SQL Server\90\Tools\Binn" echo Creating a backup for the date %backup_datestring%... echo Backing up the database... sqlcmd -s MYSERVER\MYINSTANCE -e -Q "BACKUP DATABASE MyDatabaseName TO DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Backup\ MyDatabaseName %backup_datestring%.bak' WITH INIT, NOSKIP, NOFORMAT"
Here, we first go to the correct folder location to find the command-line utility SQLCMD.EXE. This command allows us to execute the BACKUP DATABASE command with the current Windows user account. The -s parameter gives the server hostname and possible instance name (if you want to use the default instance, just give the server name without the backslash). Then, the "TO DISK" parameter gives the destination folder and filename for the backup file. Note how we use the %backup_datestring% environment variable set earlier.
Here is a complete script you can use to tune to your own purposes:
@echo off rem ** Create a string with format "yyyy-mm-dd" from the Finnish settings, adjust for your own Windows locale! set backup_day=%date:~3,2% set backup_month=%date:~6,2% set backup_year=%date:~-4% set backup_datestring=%backup_year%-%backup_month%-%backup_day% cd /d "C:\Program Files\Microsoft SQL Server\90\Tools\Binn" echo Creating a backup for the date %backup_datestring%... echo Backing up the database... sqlcmd -s MYSERVER\MYINSTANCE -e -Q "BACKUP DATABASE MyDatabaseName TO DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Backup\ MyDatabaseName %backup_datestring%.bak' WITH INIT, NOSKIP, NOFORMAT" echo Done!
Note that if you wish to back up multiple databases, simply repeat the SQLCMD command shown on the last three lines, and adjust the database names and/or server names. As a final step, you could clear our all the backup_* environment variables just created.
Once the complete script is in place, you can simply create a regular Windows scheduled task with the appropriate credentials, and then make the script run for example every night. This would create a nice, full backup of your database every day without you having to worry much (of course, you need to monitor the process is working).
One final question related to this kind of scripts is that the backup files accumulate in the destination folder, and one day or another, you run out of disk space. Most often, such events happen only when you are either very busy, or on vacation somewhere warm.
What would be an easy remedy for this? Try the new Windows script command FORFILES. This command supports the "/d" parameter, which allows you to list only files that are older than the given number of days. For example, "forfiles /d-7" would list files that are older than seven days. Then, you could simply delete all such files to make the backup file rotation clean and simple.
Sidenote: The latest Windows command-line reference is somewhat difficult to find, but if you browse the Technet library enough, you will find the correct location. The link provides and A-Z list of all available commands, including for instance the SET command. Note however, that the last update to this documentation (at this writing) is from 2007, so not all the latest tricks are there.
When talking about backups, there's always a need for the final reminder: do test your restores regularly. Nothing is worse than *thinking* that you have a valid backup. If your database for example becomes suitably corrupted, a full backup may run, but you cannot restore from it.
Good luck!
Microsoft has been busy updating its web sites this month, it seems. Now the MSDN Subscriber portal has got an overhaul with an improved search and a cleaner look and feel. Not that the previous version would have been somehow broken, but I guess it is a refreshment they want to make from time to time.
The new portal can be seen here.
Microsoft has last Friday announced the RTW (Release To Web) version of Silverlight 5. This means that the technology is now available for production use, and can be downloaded here.
Again, there are plenty of new features in this release, including the following:
All this sounds very good to me. But I think the most pressing question is, where is the show around this launch? I haven't seen any big announcements, Silverlight 5 is just a small note on Silverlight.net web pages, and is a big contrast to the usual fanfare that Silverlight versions have come to the world.
If you are using Visual Studio 2010 Premium or Ultimate, you might be aware that your edition of Visual Studio contains modeling features. There are plenty of different model types available, starting from overall architecture and classic UML models, but this time I wanted to point out layer diagrams.
To add a layer diagram to your project, use the New Diagram command from the Architecture menu in Visual Studio, or press Ctrl+§,N. This opens a dialog box where you can create a new layer diagram. Note that you cannot find these diagram types from the regular Project/Add New Item command.
What, then, is a layer diagram? Shortly put, it is a logical drawing of the architectural parts of your solution. The drawing usually contains a box for each project in your solution, and lines between them. The main idea is to let the lines between boxes represent the valid references between the projects. You can then validate your whole solution against the diagram to see if it still complies with the original architecture.
For instance, if your data access layer (DAL) provides a class that your business logic layer (BLL) uses, you can draw a line between the DAL and BLL in your diagram. But if in your code your user interface (UI) layer accidentally directly references something in the DAL layer, the layer diagram validation can notice this and report an error.
There's a nice post about these layer diagrams in the MSDN Blogs. Be sure to check it out.
A portal often visited by ASP.NET developers is the main Microsoft web development web site at www.asp.net. Aptly named, the site hosts a healthy amount of technical content, including tutorials, videos, sample code, and of course forum to help you share your thoughts or ask questions.
Just recently, Microsoft recreated the looks of the site, and now for example the main page highlights the community even more than before. It's also now trivial to find the necessary downloads (for instance, at this writing, the ASP.NET MVC 4 developer preview).
PowerShell, the nifty .NET based object-oriented command prompt for Windows has matured during the years that the technology has been available. PowerShell is also a technology that is in active development, and the next version is already in horizon.
In the new PowerShell version, we are going to see an improved ISE (Integrated Scripting Environment), new commands and of course, a bit more power. The first CTP version has already been available since around September, but just a couple of days ago, Microsoft posted the CTP2 version for everyone to download.
I recently needed to migrate parts of a graphical WinForms application to the web, and in the progress I needed to integrate the code with an existing ASP.NET web site. Note that I'm saying "web site" instead of a "web application", the latter of which I more commonly use myself.
Since web applications and web sites are different, the regular tips do not fully apply to entity models in web sites. During this migration project, I ran to the following error message:
System.Data.MetadataException: Unable to load the specified metadata resource.
This error is most often related to erroneous connection strings, which in Entity Framework take a format similar to this (lines shortened):
metadata=res://*/Models.MyModel.csdl|res://*/Models.MyModel.ssdl| res://*/Models.MyModel.msl;provider=System.Data.SqlClient; provider connection string="data source=myserver; initial catalog=mydatabase;integrated security=True;multipleactiveresultsets=True; App=EntityFramework"
To solve this issue, you need to make sure that the "res://*/" specifications are correct. However, what most blog posts about this error fail to mention is that the name after the "res://*/" specification must match the of folder location of the .edmx file in the project. Usually, this in turn maps one-to-one to the code namespace of your application in the said .edmx class (you can see the namespace for example from the MyModel.Designer.cs file).
This is the key to solve the issue in an ASP.NET web site. Since all C# code in a web site must reside by default in the App_Code folder, then the metadata locations must reflect this. For instance, if the model .edmx filename is directly inside the App_Code folder, then the correct setting is:
metadata=res://*/App_Code.Models.MyModel.csdl ...
Remember to make the change to all the three res: specifications.
Hope this helps!
Happy December! Microsoft just announced that a new platform preview is now available of the Internet Explorer 10 browser. The fourth preview contains more HTML5 features, including Cross-Origin Resource Sharing (CORS) support, File API Writer, and video subtitles with timed text.
For more information, see the announcement blog post. You can download the preview here – but remember that it requires the latest Windows 8 Developer Preview.
› Blog Archive