Thursday, July 02, 2009
#
I’ve had this tendency to deploy CLR Functions manually by providing the dll and scripts to the data management team. This has generally worked out great, and I’ve always thought I’d have a dba available to perform the database duties. Imagine my surprise when I could not contact anyone today. Apparently database administrators take their holidays and vacations seriously (it’s Independence Day weekend for my non-American readers).
Another developer asked me why I couldn’t deploy my clr functions through the IDE. Having never done this, I asked him how. He showed me the deploy button in his project.
I went back to my desk, heartened that I could still get my work done. I opened the Solution, right-clicked the project… but there was no Deploy. Thinking back on it, I know that I tend to make class libraries rather than database projects. I looked at my coworker’s project and sure enough, he was using a database project.
It seemed rather heavy-handed to create a new database project and move files over, so I dug into the csproj file to figure out how to convert it.
There are two key things that need to be done to convert a class library to a database project. SqlServer.targets needs to be imported, and the ProjectTypeGuids property needs to be added.
<Import Project="$(MSBuildToolsPath)\SqlServer.targets" />
<PropertyGroup>
<ProjectTypeGuids>{c252feb5-a946-4202-b1d4-9916a0590387};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
It doesn’t matter where these entries are added, but I place the property in the top property group below the Platform property and paste the import near the CSharp.targets import. The first guid in ProjectTypeGuids specifies that this is a SqlClrProject. The second guid specifies this is a C# project. Visual Basic developers will need to replace the C# guid with F184B08F-C81C-45F6-A57F-5ABD9991F28F.
The deploy button now appears but doesn’t work. When clicked, it fails with no more information than “Deploy failed.” Deducing that it probably needs a database connection, I used MSDN to find out where that configuration is located. This is one place the MSDN documentation is misleading.
Select Deploy from the Build menu. The assembly will then be registered in the SQL Server instance and database specified when the SQL Server project was first created in Visual Studio.
This is true only if one has never changed that configuration for the Database project. Since this was a class library converted to a database project, the server and database wasn’t specified when creating the project. Luckily, this can be configured in the Properties window on the Database tab. Be sure to add the connection to Server Explorer (Ctrl+W, L) first.
At this point, the project has been converted and we’re almost ready to deploy. Before doing so, the assembly must be dropped from the database. Visual Studio is smart enough to drop it, but only if the assembly was deployed from Visual Studio in the first place. After the first deployment, it will work automatically in the future.
Note: Cross posted from
KodefuGuru.
Permalink
Tuesday, June 30, 2009
#
I’m trying to win the grand prize for June on Community Credit, and I get 5000 points for linking to there. Here’s what I’m trying to win!
Embrace the Dark Side
Embrace the dark side every day with this animated Darth Vader USB hub. His eyes light up red as he moves his head from side to side and performs his trademark heavy breathing. Push button activation or select random intervals throughout the day. Plug a peripheral in and Vader activates to the sound of a light saber
Remember, if you’re writing blog posts, presenting, or volunteering for the community in any form; you too can win stupid prizes for smart people!
Note: Cross posted from
KodefuGuru.
Permalink
I remember when I started working on this particular project a few months ago. When I looked over the code for the first time, I noticed something funny about the cs files. Each cs file contained multiple public types. In the extreme cases, there were dozens of public classes in one file.
I brought it up with my new teammates, and one person claimed that he liked to keep related classes in a single file. I mentioned that I find it more difficult to find what I’m looking for in the solution tree, but he shrugged it off by suggesting I use the search feature.
Having never seen this type of code structure before, and with the knowledge that you group related classes by namespace, I decided to research why I felt so strongly that public types deserve their own file. I referred to the Framework Design Guidelines book by Krysztof Kwalina and Brad Abrahams (which is a great reference, btw). The first rule under A.4 File Organization is “DO NOT have more than one public type in a source file.” It then lists a few exceptions (number of generic parameters, nested, etc.).
Today I received yet another reminder of why this type of file structure is bad. I pulled down the latest code, then I retrieved a shelveset I was working on last week. I knew I might have to merge a few files, but I didn’t expect this.
Ignoring the misspelled class name, someone had moved the type from a file I was working on to another. This kind of silliness wouldn’t happen if the class had its own file. I wasn’t even working on that particular class. As it turned out, the class in question was used by a few xaml pages, and a developer thought it fit better with a different xaml page than its original home.
My rule is one public type per file, using namespaces and project folders to group related types. This reduces the amount of potential editing conflicts and makes it easier to find the type in the Solution Explorer. If you have types with the same name but a different number of generic parameters, name the file by the class name with `(# generic parameters) at the end. For example, List<T> would be List`1.cs.
Note: Cross posted from
KodefuGuru.
Permalink
Monday, June 29, 2009
#
At ConvergeSC 2009, an attendee asked me to describe how to prevent crawlers from trolling your ADO.NET Data Service. I explained as best as I could, but I felt like a blog post might make it more clear.
To a bot, your data service looks like any other site on the web. Sure, it’s reading either Atom, POX, JSON, or some other bizarre format you’ve concocted, but it’s still data coming down through http and discoverable via links. There are ways to prevent a bot from crawling, but information available on the web that doesn’t require authentication can be crawled.
The first way to prevent your service from being crawled by a legitimate bot is to put a Robots.txt in the root of the site. Inside the file, put the following lines:
User-agent: *
Disallow: /
This locks down the entire site from being crawled by the bot. If your service coexists with a site you want to be crawled, you can change the Disallow option to /MyService.svc/. be sure to include the closing slash so other pages aren’t accidentally matched.
The conference attendee seemed to be concerned specifically about anchor tags and AJAX. If you’re using the OnClick event of the anchor tag, most spiders will not follow it. However, if the uri is in an href, a crawler will pick it up. Bing and Google will honor a rel attribute with the “nofollow” value to prevent indexing the page. However, Yahoo and Ask will still follow and index a link with that attribute.
If your service is publicly available, using the robots.txt is the way to go. If it’s not publicly available, the service should already be locked down through authentication techniques.
Note: Cross posted from
KodefuGuru.
Permalink
At ConvergeSC 2009, an attendee asked me to describe how to prevent crawlers from trolling your ADO.NET Data Service. I explained as best as I could, but I felt like a blog post might make it more clear.
To a bot, your data service looks like any other site on the web. Sure, it’s reading either Atom, POX, JSON, or some other bizarre format you’ve concocted, but it’s still data coming down through http and discoverable via links. There are ways to prevent a bot from crawling, but information available on the web that doesn’t require authentication can be crawled.
The first way to prevent your service from being crawled by a legitimate bot is to put a Robots.txt in the root of the site. Inside the file, put the following lines:
User-agent: *
Disallow: /
This locks down the entire site from being crawled by the bot. If your service coexists with a site you want to be crawled, you can change the Disallow option to /MyService.svc/. be sure to include the closing slash so other pages aren’t accidentally matched.
The conference attendee seemed to be concerned specifically about anchor tags and AJAX. If you’re using the OnClick event of the anchor tag, most spiders will not follow it. However, if the uri is in an href, a crawler will pick it up. Bing and Google will honor a rel attribute with the “nofollow” value to prevent indexing the page. However, Yahoo and Ask will still follow and index a link with that attribute.
If your service is publicly available, using the robots.txt is the way to go. If it’s not publicly available, the service should already be locked down through authentication techniques.
Note: Cross posted from
KodefuGuru.
Permalink
I am honored to have joined the Lounge Advertising Network!
Now, I know you’re thinking, “Why would someone be honored to join an ad network?” I would answer that with “look who else is in this network.” The Lounge picks only the top Microsoft technology blogs… blogs by influencers both online and off. To be counted among them is indeed a cool thing.
Note: Cross posted from
KodefuGuru.
Permalink
Friday, June 26, 2009
#
Have you ever debugged a large project you didn’t create? If so, you’ve probably gotten lost in the vast jungle of code that was once some poor programmer’s paradise. This vast jungle is full of cannibalistic tribes and wild animals waiting to tear you to pieces. Your only hope for survival is your ability to navigate the solution tree, relying on your wits to circumvent the illogical paths of code that “Go To Definiton” has guided you down.
Luckily, Visual Studio 2008 will provide you a guide if you ask for it. Open Tools | Options… | Projects and Solutions | General. Then, check the box for “Track Active Item in Solution Explorer.”
After you have pressed okay in this dialog, when you have a file opened in the editor, the Solution Tracker will automatically select it. The one catch I’ve found is that if the project is contained within a solution folder, the folder must be open.
Note: Cross posted from
KodefuGuru.
Permalink
Tuesday, June 23, 2009
#
If you’re a C# developer who has tried to do Microsoft Office programming, you know how much of a pain it can be. Most of the methods require tons of parameters, and you end up needing to pass tons of Missing.Value argument around.
If you haven’t done this before, it’s easy to get started writing Office programs. First, make sure you have Office installed. Second, add a reference in your project to the Office application you want to automate.
Now, add the appropriate using clause (using Microsoft.Office.Interop.Excel;) to your C# code. If you use multiple Office applications, you may wish to alias the namespace to prevent naming conflicts. Most of the Office interops use the same class: Application. Now, create your Excel application object for automation.
var excel = new Microsoft.Office.Interop.Excel.Application();
That was easy enough. Here’s the part where it gets nasty… nearly every method you call requires optional parameters and casting.
Worksheet sheet = (Worksheet)book.Sheets.Add(Missing.Value,
Missing.Value, Missing.Value, Missing.Value);
Sheets.Add isn’t so bad, but some methods have dozens of parameters. These only exist to junk up your code. Wouldn’t you much prefer to write the following instead?
Worksheet sheet = book.Sheets.Add();
So would I. In C# 4.0, we get optional parameters and the interop code returns dynamic types, so this is exactly how your code will look next year. But that doesn’t really help us today. Luckily, there is a C# 3.0 feature that will allow you to write readable interop code: extension methods.
public static Worksheet Add(this Sheets sheets)
{
return (Worksheet)sheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);
}
Just place that method in a static class and you’re good to go. Then, add methods as you need them. Since you can overload extension methods, you still have the flexibility of optional parameters. Here’s the full class I needed for the piece of Office automation I was working on.
internal static class ExcelExtensions
{
public static void Close(this Workbook workbook)
{
workbook.Close(null, null, null);
}
public static void SaveAs(this Workbook workbook, string fileName)
{
workbook.SaveAs(fileName, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, XlSaveAsAccessMode.xlShared, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value);
}
public static Workbook Add(this Workbooks workbooks)
{
return workbooks.Add(Missing.Value);
}
public static Workbook Open(this Workbooks workbooks, string fileName)
{
return workbooks.Open(fileName, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value);
}
public static Worksheet Add(this Sheets sheets)
{
return (Worksheet)sheets.Add(Missing.Value, Missing.Value, Missing.Value,
Missing.Value);
}
}Note: Cross posted from
KodefuGuru.
Permalink
Sunday, June 21, 2009
#
I was setting up a SQL Server instance on my co-located server, but a series of events led me to uninstall it and reinstall it a few times. The final time through, it detected the original reporting services database, so I cancelled the installation and deleted the SQL Server folders. At that point I spent the next hour or so trying to make SQL Server get past the setup bootstrap installation.
The setup program told me everything was okay before it began the installation. The problem was, the installer just disappeared in the middle (after entering the key, before requesting usernames/passwords): it threw no error, the installation logs said everything was okay, there was nothing in the event logs.
I tried rebooting, but that didn’t work. I tried deleting the registry entries, but that didn’t work either. I checked everywhere I could think of for remnants of SQL Server. I then thought that maybe I dirtied my key with all my install attempts, so I tried to install the developer edition: same problem.
Then it occurred to me to check Programs and Features.
Sure enough, the setup program was installed, and it was causing the installer to fail. Uninstalling this fixes the problem.
Note: Cross posted from
KodefuGuru.
Permalink
Friday, June 19, 2009
#
Here’s a refactoring I used to do some minor cleanup today. The programmer was iterating through a dictionary to add values to a list. No logic was contained within the iterator.
public void AddCodes(Dictionary<int, string> indexedCodes)
{
foreach (var code in indexedCodes.Values)
{
Codes.Add(code);
}
}
This can be simplified by using the list’s AddRange method.
public void AddCodes(Dictionary<int, string> indexedCodes)
{
Codes.AddRange(indexedCodes.Values);
}
If you’re reassigning, this is even more unnecessary; just use the ToList method provided by LINQ.
public void AssignCodes(Dictionary<int, string> indexedCodes)
{
Codes = indexedCodes.Values.ToList();
}
This isn’t much of a change, but it did simplify things. The real world example was surrounded by other blocks of code that made it difficult to read. This one, small change helped improve the readability of the method.
Note: Cross posted from
KodefuGuru.
Permalink
Wednesday, June 17, 2009
#
I happened to notice the SmallBasic 0.5 release announcement and decided to take a look at it. The question going through my mind was, “why do we need yet another Basic programming language?”
Note: Cross posted from
KodefuGuru.
Permalink
Tuesday, June 16, 2009
#
I was tasked today with fixing the reporting in Team Foundation Server. The Team System cube either does not exist or has not been processed.
Note: Cross posted from
KodefuGuru.
Permalink
I added an assembly and created clr functions on my SQL server only to receive the following error when I tried to excute them.
Msg 6263, Level 16, State 1, Line 1
Execution of user code in the .NET Framework is disabled. Enable "clr enabled" configuration option....
Note: Cross posted from
KodefuGuru.
Permalink
Monday, June 15, 2009
#
I sometimes hang out with Kevin at Code Camps in the Virginia area, so I thought I would post this video of his perspective on Windows 7, Silverlight, and being an MVP.
Note: Cross posted from
KodefuGuru.
Permalink
Four new “How Do I” videos on Azure have been added to MSDN. Check them out!
Leverage Concurrency in Windows Azure Table Storage?
Windows Azure table storage is designed to support many users at the same time. In this session, you’ll learn how Windows Azure table storage supports concurrency, and you’ll learn a few strategies to help you deal with any concurrency violations.
Use Paging in Windows Azure Tables?
To improve application usability, many applications need to support viewing data page-by-page. In this screencast, you'll learn how Windows Azure table storage provides a built-in mechanism that allows you to efficiently page through query results.
Sync Between Devices and the Cloud with FeedSync?
Syncing the cloud and a growing world of devices is a fundamental need in today’s world. In this video, you will learn how to use FeedSync feeds to synchronize Live Framework data between a device and the cloud.
Get Started with the Messenger Web Toolkit?
Making your application sociable is easy. In this screencast, Chris Parker uses simple code to add instant messaging to his Web site. In minutes he connects his Web site to 320 million Instant Messenger (IM) users on PCs, Macs, mobile devices and Xbox 360. These efforts can help bring new users to his application and retain them for a longer period of time through the use of cool features like chat, presence, contacts and profile information.