:::: MENU ::::

Wednesday, December 15, 2010

Anyone doing ASP.NET development probably admits, openly or not, to introducing or stumbling upon a security issue at some point during their career. Developers are often pressured to deliver code as quickly as possible, and the complexity of the platform and vast number of configuration options often leaves the application in a less than desirable security state. In addition, the configuration requirements for debugging and production are different, which can often introduce debugging settings in production, causing a variety of issues.

Over the years, the ASP.NET platform has matured and better documentation has been made available through MSDN and community blogs, but knowing which feature or configuration setting to use is often troublesome. Even with good knowledge of the security functionality, mistakes can happen that could result in security vulnerabilities in your application.

Peer code review is a useful process and a good way to catch issues early. Still, not everyone has the time or budget—or knowledgeable peers at hand—for such review.

Since the introduction of code analysis in Visual Studio 2005, developers have been able to automatically analyze their code to see if it complies with a series of best practices ranging from design, maintainability, performance and security. So far, code analysis has been a great tool, but it hasn't focused on providing best security practice guidance for ASP.NET—until now.

In this article I'll introduce you to the new ASP.NET code analysis rules that can be used with Visual Studio code analysis as well as with the standalone FxCop application to improve the security of your ASP.NET applications.

Overview

You can download the ASP.NET security code analysis rules package for Visual Studio 2010 and FxCop version 10.0 from go.microsoft.com/?linkid=9750555. The installation contains three new rules packages:

  • ASP.NET.Security: This category focuses on security best practices related to how System.Web.Ui.Page properties are initialized.
  • ASP.NET.MVC.Security: This category focuses on security best practices related to how ASP.NET MVC is used.
  • ASP.NET.Security.Configuration: This category focuses on security best practices related to configuration elements under the web.config files.

Once the rules package is installed, you can start reviewing the security of your Web application automatically by clicking on the Run Code Analysis on Web Site button under the Build menu (see Figure 1). The analysis will review each Page class and web.config file of your application against a series of security best practices for ASP.NET.

More

 

Monday, December 13, 2010

Today we are announcing the release of GhostDoc v3.0 - a new major release of the product. This version includes product usability and menu changes, adds many new features - menus, configuration rules, configuration options. It also features new error logging to improve troubleshooting of GhostDoc issues. The new version introduces GhostDoc Pro Edition - enhanced version of the product that gives users complete control over your XML Comment content and layout as well as automates XML Comment generation via batch actions.

For Edition comparison please see GhostDoc product page - http://submain.com/ghostdoc/

New in v3.0:

  • (Pro Only) New Document Type feature - generates XML comments for the entire type/class
  • (Pro Only) New Document File feature - generates XML comments for the entire file
  • (Pro Only) Introduced T4 template based rules that replace rule macros of the Free version
  • Improved support for VS2010
  • New Load/Unload menu items allow to disable GhostDoc temporary without uninstalling it
  • New Help menu item
  • New option to and menu to Re-assign Shortcut
  • Added Rule for read-only property to turn off generation of the tag line
  • Added Rule for private constructor
  • Added support for new tags - <inheritdoc>, <author> and <remarks>
  • Added support for enums, delegates and fields
  • Added option to modify Configuration Folder path
  • Added option to Keep Single Line when for long comments
  • Changed leading tabs to leading spaces for compatibility with other products
  • Changed "gets or sets" summary prefix to just "Gets" when setter is private
  • Fixed automatically implemented properties issue 

GhostDoc and GhostDoc Pro build 3.0.10340 are available for download right now at http://submain.com/download/ghostdoc/

Please note GhostDoc EULA was updated to reflect the introduction of GhostDoc Pro.

Download More

 

Thursday, November 18, 2010

As you may already know, it is easy to come up with a document - the key is in implementing these standards in your organization, through methods like internal trainings, Peer Reviews, Check in policies, Automated code review tools etc. You can have a look at FxCop and/or StyleCop for automating the review process to some extent, and can customize the rules based on your requirements.

Anyway, here is a list of some good Coding Standard Documents. They are useful not just from a review perspective - going through these documents can definitely help you and me to iron out few hidden glitches we might have in the programming portion of our brain.

So, here we go, the listing is not in any specific order.

1 – IDesign C# Coding Standards

IDesign C# coding standards is a pretty decent and compact (27 pages) Coding Standards Document. It covers a Naming conventions, Best practices and Framework specific guidelines. Example:

The document even has guidelines for project settings, build configuration, versioning etc. Good work by IDesign guys. You can download the document here

2 – Encodo C# Handbook

Encodo C# handbook is bit more recent, and has 72 pages of guidelines on Structure, Formatting, Naming. It also has a 'Patterns and Best Practices' section, which is a must read for any .NET/C# developer.

You can download the Handbook here.

3 – Microsoft Framework Design Guidelines

MSDN has a section on guidelines for Designing class libraries, which covers a set of best practices related to Type Design, Member Design etc. You can find it here.

4 – Denni's C# Coding Standards document

Dennis created an initial version of C# coding standards, which was published as Philips Health Care C# coding standards document (~70 pages). The document categorizes the guidelines to categories like Naming, Exception Handling, Control Flow etc.

  • Update: Dennis kindly pointed that the Initial Version I linked here earlier has now been superseded by the Coding Guidelines for C# 3.0 and C# 4.0. Paul Jansen of Tiobe will update his site soon regarding the new version - But in meantime, download the guidelines and some companion documents here: http://csharpguidelines.codeplex.com/

5 – Microsoft's All-In-One Code Framework Coding Guideline

Microsoft's All In One Code framework has a Coding Style Guideline document. The Microsoft All-In-One Code Framework is a free, centralized code sample library provided by the Microsoft Community team. It has typical code samples for all Microsoft development technologies, and a code style guideline document with that. Thanks to Kevin for pointing out this guideline document with All In One Code Framework (See the comments)

6 – Brad's Quick Post on Microsoft Internal Coding Guidelines

Brad had a post on Microsoft Internal coding standards (I'm not sure whether he still follow that in Google, if at all he uses C# there). It is a short post, and is mainly on Styling and Naming conventions.

7 – Mike's C# Coding Style Guide

Mike Kruger (Sharpdevelop) had published a 13 page C# Coding Style guide. Again, the focus is on Casing, Naming conventions, Declaration style etc. A short and simple Style Guide.

So, if you are still confused about which document to choose - my recommendation is here for you - Based on your landscape, organizational climate, project and domain, go through these documents and pick the relevant recommendations – to formulate your very own 10 page '.NET/C# Coding standards/guidelines' for your team.

Also, if you think I missed any prominent guideline document, list down the same in the comments section, and I'll include that in the main post if it is relevant – My initial post was about 6 documents, but I expanded/modified the list later based on some feedback I received. Happy Coding.

More

 

Monday, September 27, 2010

Most projects I work on need a list of countries at some point so I put together a snippet of SQL that I could reuse to create and populate a countries table in the database with all countries as given in ISO 3166-1. After recently writing a utility class to populate list controls with world currencies according to ISO 4217 it got me wondering if I could also do the same for countries using only the .Net Framework. And so I came up with the following utility class to do the job.

        /// <summary>
        /// Populates the list control with countries as given by ISO 4217.
        /// </summary>
        /// <param name="ctrl">The list control to populate.</param>
        public static void FillWithISOCountries(ListControl ctrl)
        {
            foreach (CultureInfo cultureInfo in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
            {
                RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
                if (ctrl.Items.FindByValue(regionInfo.TwoLetterISORegionName) == null)
                {
                    ctrl.Items.Add(new ListItem(regionInfo.EnglishName, regionInfo.TwoLetterISORegionName));
                }
            }
 
            RegionInfo currentRegionInfo = new RegionInfo(CultureInfo.CurrentCulture.LCID);
 
            //- Default the selection to the current cultures country
            if (ctrl.Items.FindByValue(currentRegionInfo.TwoLetterISORegionName) != null)
            {
                ctrl.Items.FindByValue(currentRegionInfo.TwoLetterISORegionName).Selected = true;
            }
        }

More Info

Working with SQL Server over the years has made me realize just how much learning I have to do before I can classify myself a database guru.  Along the way, I have learned a lot of cool things from various sources, but still have plenty more areas to study.  Most of the things that I've learned about SQL Server, as well as many other things, have come from a need for a solution to a particular situation.  What I will be discussing today came from one of those situations.

The problem I had to solve involved querying the database with several different parameter options.  The same data was to be retrieved with each query, but it was the filtering of the data that changed.  My initial reaction was to write a stored procedure for each of the different parameter permutations.  The problems with that approach are numerous, so let's just say it was too much of a waste of time.  I started looking for alternatives and found this blog post discussing the basics of just what I needed to do.  Since I'm using this blog as a way for me to archive some of the cool things I've learned, I'll put my own spin on the topic here.

The basics are this: make a single stored procedure that will take in all the possible parameters, giving each one a default value of NULL in case it is not needed, and return the necessary data filtered accordingly.  Sound simple?  Actually, it really is.  Here is an example of a stored proc that does just that:

CREATE PROCEDURE GetCrap
    @CategoryID int = NULL,
    @MinPrice decimal(4,2) = NULL,
    @MaxPrice decimal(4,2) = NULL
AS
BEGIN
    SELECT *
    FROM TableWithCrap T
    WHERE (@CategoryID IS NULL OR T.CategoryID = @CategoryID) AND
          (@MinPrice IS NULL OR T.Price >= @MinPrice) AND
          (@MaxPrice IS NULL OR T.Price <= @MaxPrice)
END 

See how simple it is?  Simply give the optional parameters a default NULL value (@CategoryID int = NULL).  Then, and here's the cool part, make each part of the WHERE clause a conditional that will either evaluate to true if the parameter is null or evaluate according to the requirement.

@CategoryID IS NULL

will return true if the parameter CategoryID has not been given, thus eliminating it from the filtering process.

@CategoryID IS NULL OR T.CategoryID = @CategoryID

basically says, "if I have a value, use me."

That's it!  AND those bad boys together and you've got a respectable dynamic query built right into a nice stored procedure!  Isn't that cool?

More Info

Tuesday, June 29, 2010

One of the really useful Visual Studio add-ins is Smart Paster. It adds a "Paste As." context menu that allows you to paste in the clipboard text as a comment, a correctly quoted string or a string builder.

There are versions for VS 2003, 2005 and 2008. But not 2010.

Sometimes you can just copy in the dll and addin file into the VS 2010 Addins folder (.\Documents\Visual Studio 2010\Addins) and edit the addin file (it's just xml) to say "10.0" instead of "9.0". But that doesn't work for SmartPaster - VS 2010 shows an error and insists on disabling the addin.

The VS 2008 download includes the source, so I tried to upgrade it.

It turns out the problem is when it creates the context menus it sets the CommandBarButton.FaceId property (to show an image next to the text). But in VS2010 that throws a DeprecatedException.

Ok, simple fix, but the original source is old code with a fairly high WTF-per-line ratio (well, it was written 2004, .Net 1.1). Before long I had ported it from VB.Net to C# (thanks Telerik) and rewritten large parts (mostly refactoring with Coderush). I simplified by dropping the "regionize" stuff (never use it), the VB support and the configuration form. Here's my code- you can create a new Extensibility Addin project, replace the Connect class and add the SmartPaster class- see below.

It's still a port, so certainly not as clean as something just written from scratch. And perhaps VS2010 has nicer ways of doing all these things now the code window is a WPF control - the EnvDTE objects are ugly and hard to use. Anyway, thanks to Alex Papadimoulis for the original code.

More

 

Thursday, June 17, 2010

Recently, I had a customer want to launch a webpage when the final installation dialog was presented. 

Obviously the original request was for a traditional web page link shown by the traditional underscored phrase.  No version of InstallShield supports this feature – although in the Release Notes for InstallShield 2010, there is a mention of being able to embed a hyperlink within a dialog.  For for all of you who are not up-to-date with the latest IS version, here are the steps that I took to handle this request.

I modified the existing link that enabled you to "Launch a program" that is built into the final dialog "SetupCompleteSuccess".  The important parts of the dialog are:

  • CheckLaunchProgram – this is the CheckBox field
  • LaunchProgramText – this is the text that accompanies the CheckBox field, relatively small
  • UpdateTextLine2 – this is another text field that I commandeered to provide more accomplanying text than what was available.

Step 1: 

Ensure all fields have the same launch conditions.  The one I grabbed had a different launch conditions – so ensure the conditions are the same - alter the SHOW Condition

"SHOWLAUNCHPROGRAM="-1″ And PROGRAMFILETOLAUNCHATEND <> "" And NOT Installed And NOT ISENABLEDWUSFINISHDIALOG

This allows all of the fields to show on the dialog that you are working with. 

Step 2:

Alter the wording on the Text fields to your requirements.  Then reshift the TOP and LEFT values so that it lines up on the screen.  The original locations tend to bunch up near the top screen.  Suggestion – if you have a massive installation project, you won't be able to view the changes easily – I used a "testbed" project with no files to get the look and feel of the dialog to my likeing before I injected the changes into the final project.

Step 3:

Add the properties that control the visibility of the new fields into the Property Manager.  These are:

IE_EXPLORER_PATH   (no value needed for this one)

LAUNCHPROGRAM="1″
SHOWLAUNCHPROGRAM="-1″
PROGRAMFILETOLAUNCHATEND="-1″

Note that the last two properties have "-1″ – this matches up with the Launch Conditions.

Step 4:

Now create the new InstallShield Custom Action that will be triggered by the checkbox.  I named my Custom Action "ISI_LaunchURL" and when using the Custom Action Wizard, it was a "New EXE" that had a "Path in Property Value".  Since its execution is from a DOACTION, there is no sequencing required.  Since you want the installation to finish while the URL is being launched, specify for the Return Processing property – Asynchronous (Don't wait for completion).  The property that holds the path is "IE_EXPLORER_PATH" and will be created next via a System Search function.  The command line will be something like this:

[WEB_ADDRESS]/Docs/Help.aspx#ServiceInstallation

Now, the [WEB_ADDRESS] is a MSI Property that comes across within one of the Dialogs - the customer had entered that value, so I know that the value contains Http://www.XXXX.com – if the format was not correct, then I would need to append/prepend the required values.  Warning:  Be aware that if the customer enters a space at the end of the  WEB_ADDRESS field, then that space would be incorrectly carried forward to this URL – so you may need to edit the field after the entry was made in the dialog.

Step 5:

Now create the new System Search entry.  Use the Wizard and choose "Registry – File Path as specified by a reg entry"  On the next screen, enter "HKEY_LOCAL_MACHINE" for the Registry Root entry and enter "SOFTWARE¥Microsoft¥Windows¥CurrentVersion¥App Paths¥IEXPLORE.EXE" and leave the remaining fields blank.  On the MSI Property, enter "IE_EXPLORER_PATH".  This System Search will kick off at the very beginning of the install and will retrieve the path entry of the Internet explorer and put the value in the MSI Property "IE_EXPLORER_PATH", which should be like this "C:¥Program Files¥Internet Explorer¥IEXPLORE.EXE"

Step 6:

Now we need to modify the dialog "SetupCompleteSuccess" and have it launch the web page URL when the button is checked.  Navigate to the dialog, and select the dialog's "Behavior" section.  Find the OK button and enter the following condition:  DOACTION as the Event, then select from the Argument dropdown  "ISI_LAUNCHURL" and finally put in the condition  LAUNCHPROGRAM="1″

Now you must move that Event up to be in front of the EndDialog EXIT event! 

Step 7:

Now Test / evaluate your finished work.  Note that when the final dialog is displayed, the checkbox will automatically be checked.  This is because the MSI Property was present within the Property Manager.  You had to put it there to be able to reference it within the above steps.  If you now remove it from the Property Manager, the default action is that the box is unchecked.  When testing, you can check the box, hit FINISH button and the URL should be launched.

More

One of the options that was available to you with installations prior to Windows Installer emergence was the ability to rerun an installation multiple times.  By this I mean running the setup again without entering Maintenance Mode – as if it had never been run before.

You can still use InstallShield to create an InstallScript using the  option and then select the Multi-Instance option which lets your end users rerun an installation multiple times as a first-time installation rather than as a maintenance installation. 

But as you know, I studiously avoid InstallScript projects – I use Basic MSI Projects, so how do you make a Basic MSI Project eligible to be rerun?

Note that there are four Standard MSI actions that are the primary method by which the MSI Application is registered under the Windows Installer that we need to be concerned with: 

  • RegisterUser
  • RegisterProduct
  • PublishFeatures
  • PublishProduct

Alter the condition on each of these Standard Actions to use zero – which means the condition will never be set true and the Standard Action will never run.  I recommend you alter the comment to reflect the change – as I have shown above.

Impact

The usage of this technique means the product will not be registered under Windows Installer – nor will it appear in the Add/Remove Programs Control Panel.   Use only if you have a specific requirement!

Usage Scenarios

I have encountered two separate situation where this technique served admirably.  

Once a vendor was creating unique sales video/slideshow presentations to sell to his customers.  After a few customers used his services, he encountered a situation where the same end-client was attempting to install the presentations from two of his customers.  The dreaded Maintenance mode was disrupting the end-client from installing the second presentation.   I was able to make the install rerunable – and used a scripted Custom Action to read a special file delivered with each presentation.  This information allowed me to install the unique files, create shortcuts to access the presentation and create a uninstall technique to allow the end-user to remove the files when no longer required.

Another vendor needed to be able to allow an unlimited amount of customers to be established on the server.  Each customer would have a unique IIS Virtual Directory with the same files installed.  XML documents that were specially configured during the install would maintain the customer data within the Virtual Directory.  A very complex Visual Studio .NET solution was involved to support the customer processes.  Each customer install used a rerunable Basic MSI Webproject to deliver the files and create the Virtual Directory.

Warning!

I don't recommend you do this to simply to avoid the Maintenance Mode!  A great technique if you have a specific requirement – but you will lose so much functionality that Windows Installer/MSI packages offer.

 

Tuesday, May 11, 2010

SolutionConverter will convert a complete Visual Studio solution from one version to another; it allows you to convert your solutions to both older and newer versions. Currently, Visual Studio 2005, 2008, and 2010 are supported, including Visual C# Express and Visual Basic Express editions. Visual C++ project conversion is not yet supported.

 

More

Wednesday, April 7, 2010

Too many people don’t realize that there are other options than <!-- --> comments to annotate HTML. These comments are harmful because they are sent to the client and thus make your page heavier than it needs to be.

When doing ASP.NET, a simple drop-in replacement is server comments, which are delimited by <%-- --%> instead of <!-- -->. Those server comments are visible in your source code, but will never be rendered to the client.

Here’s a simple way to sanitize a web site. From Visual Studio, hit CTRL+H to bring the search and replace dialog.

Choose “Replace in Files” from the second menu on top of the dialog. Open the find options, check “use” and make sure “Regular expressions” are selected. Use “*.aspx;*.ascx;” as the file types to examine. Choose “Entire Solution” under “Look in”.

Here’s the expression to search for comments:

\<!--{[^-]*}--\>

And here’s the replacement string:

<%--\1--%>

I usually use the “Find Next” and “Replace” buttons rather than the more brutal “Replace All” in order to not apply the fix blindingly. Once this is done, I do a second manual pass of finds with the same expression to make sure I didn’t miss anything.

More

 

Tuesday, March 2, 2010

enter code hereIn the SQL Server Full-Text Indexing scheme i want to know if a table is in

  • start_chage_tracking mode
  • update_index mode
  • start_change_tracking and start_background_updateindex modes

The problem is that i set my tables to "background update index", and then tell it to "start change tracking", but then some months later it doesn't seem to be tracking changes.

How i can i see the status of "background updateindex" and "change tracking" flags?

example:

sp_fulltext_table @tabname='DiaryEntry', @action='start_background_updateindex'

Server: Msg 15633, Level 16, State 1, Procedure sp_fulltext_table, Line 364
Full-text auto propagation is currently enabled for table 'DiaryEntry'.

sp_fulltext_table @tabname='Ticket', @action='start_background_updateindex'
Server: Msg 15633, Level 16, State 1, Procedure sp_fulltext_table, Line 364
Full-text auto propagation is currently enabled for table 'Ticket'.

Obviously a table has an indexing status, i just want to know it show i can display it to the user (i.e. me).

The other available API:

EXECUTE sp_help_fulltext_tables

only returns the tables that are in the catalog, it doesn't return their status.

TABLE_OWNER  TABLE_NAME  FULLTEXT_KEY_INDEX_NAME  FULLTEXT_KEY_COLID  FULLTEXT_INDEX_ACTIVE  FULLTEXT_CATALOG_NAME
===========  ==========  =======================  ==================  =====================   =====================
dbo          DiaryEntry  PK_DiaryEntry_GUID       1                   1                      FrontlineFTCatalog
dbo          Ticket      PK__TICKET_TicketGUID    1                   1                      FrontlineFTCatalog

And i can get the PopulateStatus of an entire catalog:

SELECT FULLTEXTCATALOGPROPERTY('MyCatalog', 'PopulateStatus') AS PopulateStatus

which returns a status for the catalog:

0 = Idle
1 = Full population in progress
2 = Paused
3 = Throttled
4 = Recovering
5 = Shutdown
6 = Incremental population in progress
7 = Building index
8 = Disk is full. Paused.
9 = Change tracking

but not for a table.


SQL Server 2000 SP4

SELECT @@version
Microsoft SQL Server  2000 - 8.00.194 (Intel X86)
    Aug  6 2000 00:57:48
    Copyright (c) 1988-2000 Microsoft Corporation
    Standard Edition on Windows NT 5.0 (Build 2195: Service Pack 4)

Regardless of any bug, i want to create UI to easily be able to see its status.

 

 

T-SQL Code

This is how I wrote the query to capture this information.  I am sure there are other ways to pull this information, but this is one easy way to pull the data. This has been tested for SQL 2000 to SQL 2008. I have used cursors and several system stored procedures and also directly queried the system tables. In order to minimize the impact, I changed the transaction isolation level to read uncommitted to do dirty reads and avoid any potential blocking issues..

set transaction isolation level read uncommitted
set nocount on
declare @tbl sysname
declare @cat sysname
create table #temp_ca( 
TABLE_OWNER varchar(100),
TABLE_NAME varchar(256),
FULLTEXT_KEY_INDEX_NAME varchar(256),
FULLTEXT_KEY_COLID int,
FULLTEXT_INDEX_ACTIVE int,
FULLTEXT_CATALOG_NAME varchar(256)
)
create table #temp_status(
Catalog varchar(64),
TblName varchar(64), 
[IsEnabled] bit,
ChangeTracking varchar(24),
PopulateStatus varchar(64),
RowCnt int,
FTS_CT int,
Delta int,
PercentCompleted varchar(128), 
path nvarchar(260)
)
insert into #temp_ca
exec sp_help_fulltext_tables 
declare ca_cursor cursor for
select TABLE_NAME, FULLTEXT_CATALOG_NAME from #temp_ca
open ca_cursor
fetch next from ca_cursor into @tbl, @cat
while @@fetch_STATUS = 0
begin
insert into #temp_status
select 
cast (@cat as varchar(40)) Catalog
, cast(object_name(si.id) as varchar(25)) TblName
, cast(OBJECTPROPERTY(tbl.id,'TableHasActiveFulltextIndex') as bit) as [IsEnabled]
, case isnull(OBJECTPROPERTY(tbl.id,'TableFullTextBackgroundUpdateIndexon'),0) 
+ ISNULL(OBJECTPROPERTY(tbl.id,'TableFullTextChangeTrackingon'),0) 
when 0 then 'Do not track changes'
when 1 then 'Manual'
when 2 then 'Automatic'
end [ChangeTracking]
, case FULLTEXTCATALOGPROPERTY ( @cat , 'PopulateStatus' ) 
when 0 then 'Idle' 
when 1 then 'Full population in progress'
when 2 then 'Paused' 
when 3 then 'Throttled' 
when 4 then 'Recovering' 
when 5 then 'Shutdown' 
when 6 then 'Incremental population in progress' 
when 7 then 'Building index' 
when 8 then 'Disk is full. Paused.'
when 9 then 'Change tracking'
end PopulateStatus
, si.RowCnt, fulltextcatalogproperty(@cat, 'ItemCount') FTS_CT 
, si.RowCnt - fulltextcatalogproperty(@cat, 'ItemCount') Delta 
, cast ( 100.0 * fulltextcatalogproperty(@cat, 'ItemCount') 
/ cast(si.RowCnt as decimal (14,2))
as varchar) +'%' as PercentCompleted
, ISNULL(cat.path, 'Check Default Path')
from 
dbo.sysobjects as tbl
INNER JOIN sysusers as stbl on stbl.uid = tbl.uid
INNER JOIN sysfulltextcatalogs as cat 
on (cat.ftcatid=OBJECTPROPERTY(tbl.id, 'TableFullTextCatalogId')) 
AND (1=CasT(OBJECTPROPERTY(tbl.id, 'TableFullTextCatalogId') as bit))
INNER JOIN sysindexes as si on si.id = tbl.id 
where si.indid in (0,1) and si.id = object_id(@tbl)
fetch next from ca_cursor into @tbl, @cat
end
close ca_cursor
deallocate ca_cursor
select * from #temp_status
drop table #temp_ca
drop table #temp_status

Next Steps

 

Wednesday, February 24, 2010

Believe me it’s easy. If only you won’t get caught up with the 'Impersonation' word. A lot of sites took me for a jolly ride on the Impersonation road.

Here's a demo of the code:



using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Net;

public class ShareThis
{

 //used in calling WNetAddConnection2
 [StructLayout (LayoutKind.Sequential)]
  public struct NETRESOURCE
 {
  public int dwScope;
  public int dwType;
  public int dwDisplayType;
  public int dwUsage;
  [MarshalAs (UnmanagedType.LPStr)]
  public string lpLocalName;
  [MarshalAs (UnmanagedType.LPStr)]
  public string lpRemoteName;
  [MarshalAs (UnmanagedType.LPStr)]
  public string lpComment;
  [MarshalAs (UnmanagedType.LPStr)]
  public string lpProvider;
 }

 //WIN32API - WNetAddConnection2
 [DllImport("mpr.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
 private static extern int WNetAddConnection2A (
  [MarshalAs (UnmanagedType.LPArray)]
  NETRESOURCE [] lpNetResource,
  [MarshalAs (UnmanagedType.LPStr)]
  string lpPassword,
  [MarshalAs (UnmanagedType.LPStr)]
  string lpUserName,
  int dwFlags
  );

 //WIN32API - WNetCancelConnection2
 [DllImport("mpr.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
 private static extern int WNetCancelConnection2A (
  [MarshalAs (UnmanagedType.LPStr)]
  string lpName,
  int dwFlags,
  int fForce
  );

 public static void CopyFile (string share, string username, string password,
  string dirFrom, string dirTo, string filename)
 {
  NETRESOURCE [] nr = new NETRESOURCE [1];
  nr[0].lpRemoteName = share;
  nr[0].lpLocalName = ""; //mLocalName;
  nr[0].dwType = 1; //disk
  nr[0].dwDisplayType = 0;
  nr[0].dwScope = 0;
  nr[0].dwUsage = 0;
  nr[0].lpComment = "";
  nr[0].lpProvider = "";
  WNetAddConnection2A (nr, password, username, 0);

  // Do you stuff here, copy files, create dirs etc
  File.Copy (dirFrom + "\\" + filename, dirTo + "\\" + filename);

  WNetCancelConnection2A (share, 0, -1);
 }

 public static void Main(string[] args)
 {
  CopyFile(@"\\sa191", "username", "password", @"f:\shared",
   @"\\sa191\shared", "123.shp");
 }
}

 

Thursday, February 18, 2010

Every good developer knows never to re-invent the wheel, especially if there is software out there that has been tested by others, and has an established track record. As a developer using the .NET framework I’ve found some of these libraries invaluable, so I’m sharing them for some of the other dev’s out there with a brief outline of how to use.

Yedda Twitter Library.

URL: http://devblog.yedda.com/index.php/twitter-c-library/

I’ve used this on a number of very simple twitter projects, where I’ve just needed to send an update. As the site says its more of a wrapper for the Twitter API than an actual library, but none the less its an easy way to integrate with the service via a drop in dll. Here’s how to use it.

  1. Dim objYedda As New Yedda.Twitter
  2. Dim status as String
  3. Dim strTwitterUser as String = “username”
  4. Dim strTwitterPassword as String = “password”
  5. status = “Hello World”
  6. objYedda.Update(strTwitterUser, strTwitterPassword, strStatus, Yedda.Twitter.OutputFormatType.RSS)

This small section of code will update your Twitter stream (provided you have a reference to the DLL), and your username and password correct.

FileHelpers Library

URL: http://filehelpers.sourceforge.net/

The FileHelpers library was created to stop developers from continuing to parse CSV. If you are doing any kind of importing and exporting within your application using the CSV format to get data in or out, look no further.

You can strong type your flat file simply by coding up a class that maps a data type to each record. This way data consistency, and import / export reliability can be tightened up on quite a bit.  Writing out to a new file is also pretty easy once you’ve created your base classes defining the structure. Great little library for your toolkit.

First define the structure class…

  1. <DelimitedRecord(“,”)>_
  2. Public Class Product
  3. Public ProductName As String
  4. Public ProductCode As Integer
  5. etc..
  6. End Class

Add a reference to the FileHelper.dll, and read from the file , casting to a array of product objects.

  1. Dim engine As New FileHelperEngine(GetType(Product))
  2. Dim myProduct As Product() = DirectCast(engine.ReadFile(“product.txt”), Product())

Perform actions on the array of Products.

  1. For Each pro As Product In myProduct)
  2. Response.Write(pro.ProductName)
  3. Next

Elmah

URL: http://code.google.com/p/elmah/

Elmah stands for error logging module and handlers. It is a completely pluggable in system for error handling within your .NET app. It catches bot thrown and unhandled exceptions across the scope of your app, logs them, and allows you to browse the full stack trace, all without exposing the error to the users of your application. That’s useful for a number of reasons. Firstly you aren’t getting the performance hit of using debug=true within your application (which by the way you should never be using in a production environment anyway) – and it means you can still get to the bottom of little blips as and if they happen. Coolio.

Elmah works as an HTTP module, so it takes little or no effort to deploy on any project. Just configure a few bits and bobs, and away it goes. All of the configuration is performed in the configuration file – just telling it whether you want your errors logged in a database, in memory or in a txt file is as simple as changing some web config parameters. You can even grab recent errors via RSS and get notified like that.

Log4Net

URL: http://logging.apache.org/log4net/

Following in the same vein as Elmah – Log4Net is a port of the well known logging framework for Java log4J. Whilst Elmah concentrates on exceptions that are thrown, Log4Net allows a much more granualar approach to program debugging.

With log4net it is possible to enable logging at runtime without modifying the original application binary and without incurring a high performance cost. Multiple “levels” of logging can be set within your program as well, and so you can determine quickly where “fatal” errors occur, and where “warnings” occur that can be ignored in the safe running of your application.

Log4Net enables all of these things whilst providing the same level of control over the logging format and location as Elmah. You can decide whether you’d like your debug message sent  to a database, a text file, or indeed a TCP port. Different “Appenders” define where and how to send the messages, so if there’s somewhere else you’d like to see errors, you can easily write your own appender to perform this. Again, the appenders are defined in the web.config file.

  1. Imports log4net
  2. Imports log4net.Config
  3. Private Shared log As log4net.ILog
  4. Public Sub Page_Load(Byval s as Object, Byval e As EventArgs) Handles MyBase.Load
  5. log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
  6. BasicConfigurator.Configure()
  7. log.Debug(“Debug Message”)
  8. log.Warn(“Warning Message”)
  9. log.Fatal(“Fatal Message”)
  10. End Sub

Enterprise DT FTP Library

URL: http://www.enterprisedt.com/products/edtftpnet/overview.html

Enterprise DT is a great little FTP library, that performs all the needful without you getting your hands too dirty. It works with both web and offline applications, and again is a port of a Java library. I’ve used it for automating FTP tasks at the command line, sending photos between two sites automatically via FTP, and for sending feeds to google. It’s really easy to use, and saves you from having to write your own FTP operations. Fire it up, pass some usernames and passwords to it, and away we go. As below:

  1. Dim ftp as FTPConnection = new FTPConnection()
  2. ftpConnection.ServerAddress = “myserver”
  3. ftpConnection.UserName = userName
  4. ftpConnection.Password = password
  5. ftpConnection.Connect()
  6. ftpConnection.UploadFile(localFilePath, remoteFileName)
  7. ftp.Close()

HtmlAgilityPack

URL: http://www.codeplex.com/htmlagilitypack

The Html Agility Pack is a library for parsing HTML. It is particularly useful if you are doing any kind of scraping work, with the main object of the software to transform real world HTML into structured and parseable DOM structure. It supports plain XPATH or XSLT syntax for traversing through HTML, making loops and extraction of text a breeze.  Knowing these two technologies isn’t a pre-requisite to using it, but it sure as heck helps.  You don’t have to setup the WebRequest or anything to grab remote files, which is handy – as you’ll see from the example.

  1. Dim hw As New HtmlAgilityPack.HtmlWeb
  2. Dim doc As HtmlAgilityPack.HtmlDocument
  3. doc = hw.Load(“http://blog.webdistortion.com”)
  4. For Each s As HtmlAgilityPack.HtmlNode In doc.DocumentNode.SelectNodes(“//a[@href]“)
  5. Dim att As HtmlAgilityPack.HtmlAttribute = s.Attributes(“href”)
  6. Response.Write(att.Value & vbCrLf)
  7. Next

OpenAuth Library

URL: http://code.google.com/p/oauth-dot-net/

Open Auth is slowly becoming the norm, with web apps many preferring its usage over other less secure forms of authentication. This library is a .NET implementation of OpenAuth, and is mighty useful if you need to get up and running quickly. You are sure to run into a web service that needs you to auth via it. Google, Yahoo, Netflix and Twitter all support OpenAuth to interact with their service. The code needed for open auth is more extensive than some of the other bits and bobs, and has been better explained by others. Some of these links are worth a look.

  • Shannon Whitley offers this example: Code | Live demo
  • Daniel Crenna’s examples:

OAuth Specification

The OAuth Workflow

OAuth Walkthrough

Microsoft AntiXSS library

URL: http://bit.ly/toCrt

This is one of the security packs that MS have released to help .NET developers write better, more secure code. Essentially it is an encoding library designed to help protect ASP.NET web-based applications from XSS attacks, and works on the principals of inclusion (white-listing) to accept valid characters. I’ve used it successfully on a couple of projects, and some of the pre-written methods have been rigourously tested by leading security experts.

  1. Microsoft.Security.Application.AntiXss.HtmlEncode(strNotrust)
  2. Microsoft.Security.Application.AntiXss.JavaScriptEncode(strNotrust)

C5 Collections – Collections for .NET

URL: http://www.itu.dk/research/c5/

C5 provides functionality and data structures not provided by the standard .Net System.Collections.Generic namespace, such as persistent tree data structures, heap based priority queues, hash indexed array lists and linked lists, and events on collection changes. Also, it is more comprehensive than collection class libraries on other similar platforms, such as Java. Unlike many other collection class libraries, C5 is designed with a strict policy of supporting “code to interface not implementation”. Definitely worth a look.

Honourable Mentions

Dependency Injection/Inversion of Control

Logging

Compression

Ajax

Data Mapper

ORM

Charting/Graphics

PDF Creators/Generators

Unit Testing/Mocking

Automated Web Testing

URL Rewriting

Controls

Unclassified

More

Tuesday, February 2, 2010

I’m not using NAnt or anything fancy for most of my projects—so I needed a simple, MSBuild way to automate my version numbers in a project..

<tangent>
HOLY CRAP! Why isn’t this built into Visual Studio Pro?
</tangent>

Here we go:

1. Download the latest build of AssemblyInfoTask (download here) (was 1.0.51130.0 for me).  This is a semi-Microsoft supported MSBuild task that gives you a lot of flexibility over your AssemblyInfo.cs files.

2. Install AssemblyInfoTask.  When prompted where—install into the GAC.  If you don’t have access to the GAC on your workstation, then why aren’t you developing on a VM? ;)

3. Locate the Microsoft.VersionNumber.targets file.  If you installed to the GAC, it should be at %ProgramFiles(x86)%\MSBuild\Microsoft\AssemblyInfoTask Or %ProgramFiles%\MSBuild\Microsoft\AssemblyInfoTask (depending on your architecture).

4. Copy the Microsoft.VersionNumber.targets file into a location in your solution or project.  I recommend $(SolutionDir) so you can share it amongst all of your projects.  The guilde recommend pointing to the file directly; however, you can’t modify the base Major versions that way (without setting the same major version for ALL projects you ever work on).  You can also rename it as approprate.

“Int16s Are Too Small” Or “Why 2007 Broke Versioning” Fix

According to experts who are much smarter than me, the build version numbers are Int16s—meaning 65535 caps out the number.  Unfortunately, the year 2007 breaks this (070101 or 70101 for 07 jan 01) doesn’t fit within an Int16.  Stellar.

The MSBuild team recommended taking out the year and simply placing a 1 infront of it.  That works; however, I really like having the year in there somewhere.

For me, I’ve placed the year into the MinorVersion.  After reviewing most of our practices, the minor version for most of our projects changes with annual maintenance OR not at all (we bump the major version).  This, if nothing else, will help standardize when it changes. :)  As always, YMMV.

No matter which solution you choose, you’ll need to remove the year from the BuildNumberFormats.

In your Targets file, you can change the two lines to report out the MMdd (0309, for example, today) to work around the bug.  I’ve bolded the two lines below.  As you can see, I also added the “9” to the MinorVersion to represent 2009. 

<PropertyGroup>

  <AssemblyMajorVersion>3</AssemblyMajorVersion>

  <AssemblyMinorVersion>9</AssemblyMinorVersion>

  <AssemblyBuildNumber></AssemblyBuildNumber>

  <AssemblyRevision></AssemblyRevision>

  <AssemblyBuildNumberType>DateString</AssemblyBuildNumberType>

  <AssemblyBuildNumberFormat>MMdd</AssemblyBuildNumberFormat>

  <AssemblyRevisionType>AutoIncrement</AssemblyRevisionType>

  <AssemblyRevisionFormat>00</AssemblyRevisionFormat>

</PropertyGroup>

 

<!– Properties for controlling the Assembly File Version –>

<PropertyGroup>

  <AssemblyFileMajorVersion>3</AssemblyFileMajorVersion>

  <AssemblyFileMinorVersion>9</AssemblyFileMinorVersion>

  <AssemblyFileBuildNumber></AssemblyFileBuildNumber>

  <AssemblyFileRevision></AssemblyFileRevision>

  <AssemblyFileBuildNumberType>DateString</AssemblyFileBuildNumberType>

  <AssemblyFileBuildNumberFormat>MMdd</AssemblyFileBuildNumberFormat>

  <AssemblyFileRevisionType>AutoIncrement</AssemblyFileRevisionType>

  <AssemblyFileRevisionFormat>00</AssemblyFileRevisionFormat>

</PropertyGroup>

 

This results in a version string that looks like 3.9.0309.{increment}.

5. Open up your project’s solution and unload the project you are wanting to auto-increment. Towards the end of the file, you’ll see the default MSBuild C# build path; add the location to your new .targets file in your solution directory.

<Import Project=$(SolutionDir)MyProject.VersionNumber.targets />

7. Save and Close and Reload the project.

8. Build/Rebuild your project and the AssemblyInfo.cs should set to the specified increment scheme.

You’re done!

“Too Many WebResources?” Fix 

My project references numerous resources for images and style sheets; however, having these inside of AssemblyInfo.cs seems to cause it to go haywire and throw array errors (assumingly because there is more than one [assembly:WebResource()] call).

To fix this, I moved my WebResources out of AssemblyInfo.cs and into a new file under Properties called WebResources (Add New Item > Assembly Information File).  Strip out everything except the WebResources you copy in and the project now compiles like a champ.

For additional setup details and options within the .targets files, the AssemblyInfoTask installer comes with a CHM help file that covers additional customizations available.

More