Wednesday, June 04, 2008

Now that I'm diggging a little deeper into my pet project web site, I'm learning how I really use the data. The Get() methods provided by .netTiers are great but I thought I would have more. I started looking at my database starting with the aspnet_Membership tables. I would expect unique indexes on something as obvious as the email column but it is not there. Same goes for other obvious columns in these microsoft-provided tables. So I add unique indexes to the membership tables. Of course, I do the same for my own custom tables and find that some of the text or varchar(max) have to be changed. No biggie but another step I have to take.

Now that the database is set, I need to regen the .netTiers templates, rerun the GrantUser stored proc, build the .netTiers stuff and copy it into the /bin of my project. Not hard work but just tedious to get each step completed and move on to the next one. All this so my .Get methods are consistent with my usage of the library.

All this so I can get my validators working - I really hate validators.

Wednesday, June 04, 2008 8:35:07 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  | 
 Tuesday, June 03, 2008

Yesterday, I was reading the MSDN FLASH email newsletter and saw a listing for another SQL injection article. Since one of Wayne's sites was recently hacked, I thought I would read it. The article is clear and gives explicit steps to take. Since I had only done one of the three things (SQL stored procs), I thought I would mess with the last one: execute permissions only.

Wayne pointed me to a stored proc to grant permissions to a user. Since users and roles are one of those areas that after you have them set up correctly, you don't mess with them, I stumbled my way through creating a user. I ran the stored proc (which will have to be run after every .netTiers generation), modified my sql connection in web.config and tried my pet project site. I get an error about SELECT statements and permissions. .netTiers was supposed to be configured in web.config to use stored procs but apparently not. So I change the file, build, and still get the error. Someone, somewhere is caching something. Close everything done. Reopen. Change web.config and checkin with comment. Test again and it works.

This is a really bad way to find a problem. It's getting to the point that I need someone to check my security changes so this type of thing isn't missed.

Tuesday, June 03, 2008 7:00:10 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, May 29, 2008

Here is my latest article on 15seconds.com: http://www.15seconds.com/issue/080529.htm titled "Implementing the .netTiers Template Library as a .NET Website's Data Layer - Part I"
 

Thursday, May 29, 2008 6:22:45 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, April 21, 2008

I'm still cleaning up code. One of the things that has never worked in NetTiers is the Microsoft Enterprise Library Exception Handling. I would get an exception thrown in the NetTiers code and the line was an exception with no data. I would get the error on a SQL insert via the NetTiers layers but no information about what was wrong with the data. Since I'm using the Insert where the param is the base type such as

   userService.Insert(newUser);

I knew that datatyping from a C#/.Net perspective wasn't the problem. I knew it was at a SQL level but I didn't know what it could be. So I finally had to fix the .NetTiers ExceptionHandling. I'm not sure why doesn't work right off the bat like the rest of NetTiers but I also didn't care enough to investigate. Once I get the ExceptionHandling working, I don't ever touch so I haven't had to REALLY understand it.

But now it has to work, it's hard to move forward without inserting data on this particular table. I knew I didn't have anything in web.config for this so that's where I started. I opened the ExceptionHandling Basic Quickstart and looked at the app.config. There were two different sections I added and then the true SQL error was displayed. While this isn't the entire work I'll have to do with Exception Handling on my pet project, at least I can keep going.

The SQL problem turned out to be that a datetime value was not being passed for a column where NULL was not allowed. Once the error handling showed the problem of datetime out of range, and I looked at the column definitions, I realized the problem.

Here are the sections I added to web.config:

1) in the <configSections>

<section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" />

2) the last entry before the end <Configuration> tag:

<exceptionHandling>

<exceptionPolicies>

<add name="Global Policy">

<exceptionTypes>

<add name="Exception" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="None">

<exceptionHandlers>

<!--<add name="Wrap Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WrapHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" exceptionMessage="Global Message." wrapExceptionType="ExceptionHandlingQuickStart.BusinessLayer.BusinessLayerException, ExceptionHandlingQuickStart.BusinessLayer" />-->

<add name="Custom Handler" type="ExceptionHandlingQuickStart.AppMessageExceptionHandler, ExceptionHandlingBasicQuickStart"/>

</exceptionHandlers>

</add>

</exceptionTypes>

</add>

<add name="Handle and Resume Policy">

<exceptionTypes>

<add name="Exception" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="None">

<exceptionHandlers />

</add>

</exceptionTypes>

</add>

<add name="Propagate Policy">

<exceptionTypes>

<add name="Exception" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="NotifyRethrow">

<exceptionHandlers />

</add>

</exceptionTypes>

</add>

<add name="Replace Policy">

<exceptionTypes>

<add name="SecurityException" type="System.Security.SecurityException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="ThrowNewException">

<exceptionHandlers>

<add name="Replace Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" exceptionMessage="Replaced Exception: User is not authorized to peform the requested action." replaceExceptionType="System.ApplicationException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

</exceptionHandlers>

</add>

</exceptionTypes>

</add>

<add name="Wrap Policy">

<exceptionTypes>

<add name="DBConcurrencyException" type="System.Data.DBConcurrencyException, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="ThrowNewException">

<exceptionHandlers>

<add name="Wrap Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WrapHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" exceptionMessage="Wrapped Exception: A recoverable error occurred while attempting to access the database." wrapExceptionType="ExceptionHandlingQuickStart.BusinessLayer.BusinessLayerException, ExceptionHandlingQuickStart.BusinessLayer" />

</exceptionHandlers>

</add>

</exceptionTypes>

</add>

</exceptionPolicies>

</exceptionHandling>

 

 

Monday, April 21, 2008 7:10:16 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, April 14, 2008

NetTiers will build methods for normal CRUD as well as anything they can determine. For example, if you have a table with 1PK and 2FKs, the template with build a method for select where the IN params are the two FKs. Great! I probably need that. But things get a little weird when I need to search. For example, I have a user's table and I want to be able to return results for all users that are like a searchterm. How about all user's like Dina. In T-SQL, I usually would have a where clause " UserName like '%@UserName%'. Works for me.

NetTiers has a Find method for each table. When creating a find proc, it's hard to determine which columns you would want to search through. NetTiers discovery does a bit of assuming that the first column (after the PK/FK columns) is THE main data column (such as a name). But that takes some forethought in terms of table creation. The NetTiers find method comes in two varieties: one with sql params in the NetTiers format and one with a SQL where clause. The NetTiers template should let you turn off this second way but it doesn't. Inside the stored procs that NetTiers creates, they put the where clause together. This makes me a bit nervous. I don't want a user entering something in a search textbox and have it passed to build a SQL query on the fly.

I'm going to write my own custom search proc sing the NetTiers naming conventions so I get a custom Find Method from NetTiers. I know what columns I want to search through on the Table but I also want to get my results in two line of c# code via NetTiers layer.

Monday, April 14, 2008 8:50:20 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, April 07, 2008

I stared working on my sitemap tonight. Never done the SiteMap stuff before. Opened my Pro ASP.NET 2.0 in C# 2005 that I use as a jump off point for intro topics I haven't touched yet. The chapter is great but I like my data in the database which gets backed up every night. I understood enough and even got a test page up using nested site map files. Hurray!

Now on to the SQL provider. I knew there had to be one so I googled and found an article with code by Jeff Prosise. The article covers the .cs file that is the SQL provider, as well as the web.config changes, the T-SQL, and the aspnet_regsql commands.

After you get the provider up and working, don't expect the SQL provider to show up in the Data Source Configuration Wizard:

You'll have the change the SiteMapDataSource to specify the Provider that you added to the web.config for SQL:

<asp:SiteMapDataSource ID="TotalSiteMap" runat="server" SiteMapProvider="AspNetSqlSiteMapProvider" />

 

But now my data is in the database and I changed the proc to be NetTiers-compliant so I can use their Admin pages for my data management.

Monday, April 07, 2008 8:22:52 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Sunday, March 30, 2008

After generating all CRUD procs with several different naming prefixes, my database was looking messy. So I knew what I wanted to produce but I needed to get rid of all these other procs. So how to quickly drop all the procs. Wayne said he had a codesmith template for it but I couldn't wait. I google'd and found another person that had the same problem after a heavy CodeSmith NetTiers session. His method was not too different from my post from yesterday. I did my final gen of procs via NetTiers but instead of going into the database, sent them to a file. I opened the file to find the following code which should have been both obvious in that NetTiers would need it and where I should look for it:

BEGIN

DECLARE @procedureName SYSNAME

DECLARE c CURSOR FOR

SELECT name FROM sysobjects WHERE type = 'P' AND objectproperty(id, 'IsMSShipped') = 0

AND name LIKE 'NetTiers_%' AND name NOT LIKE 'WW_{0}_%'

OPEN c

FETCH NEXT FROM c INTO @procedureName

WHILE @@FETCH_STATUS = 0

BEGIN

EXEC('DROP PROC ' + @procedureName)

FETCH NEXT FROM c INTO @procedureName

END

CLOSE c

DEALLOCATE c

END

 

Sunday, March 30, 2008 7:02:01 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, March 28, 2008

After using NetTiers for a couple of weeks now, here are some suggestions for usage:

1) Use NetTiers like any third party library. Build it and include the libraries. Do not alter code inside generated libraries unless mission critical. I also use the Microsoft.Patterns library. They ship the code but I don't alter it, I just use the built libraries. 

2) Prefix the library namespace with NetTiers so that the generated libraries look like NetTiers.Entities, NetTiers.Data, etc.

3) If you use NetTiers to generate your CRUD, set the ProcedurePrefix value to NetTiers_. When you are looking through a million procs, it easier to pass a whole section based on alphabetical sorting. If you use AspNet Membership, you will be accustomed to this naming schema as those procs are prefixed with aspnet_

4) If you create your own procs, prefix those procs to something that you won't confuse with any other library's procs, such as 'cust' for custom. Of cource, IncludeCustoms is set to true and CustomProcedureStartsWith should be set to 'cust_{0}_' so that a table name of Profile should have a custom proc of cust_Profile_SelectAll.

5) While still getting your template settings figured out:

  • Don't set ExecuteSQL to true until you have tested your generated SQL and looked through what was created.
  • Set LaunchVisualStudio to true and save yourself a few clicks.
  • Set ViewReport to false. You don't need another browser to open while you are still figuring out your templates.

6) Build the Web Service and the Admin site. Even if you don't plan to use AJAX or you have your own admin pages already built, these are just more examples of NetTiers code usage. Then when you need a data backdoor or quick AJAX, you are that much closer.

7) NetTiers documentation suggests using DeepLoad to get to a related table via FK. I can see how this would be used in their example of list of Orders in a grid and you also want to display the Customer's Name in the grid. What if you had a table of ProfileItems and a table of UserProfileItems and you wanted a list of all the ProfileItems in a grid with this user's settings? With the NetTiers usual get based on FK from either table, you won't get the grid I want (right?). So in that case, I'll create a custom proc with the proper bind.

Friday, March 28, 2008 8:03:23 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, March 27, 2008

I have a table with two FKs. NetTiers creates a stored proc for the PK as well as a stored proc for each FK however it doesn't create a stored proc that uses both FKs as the IN params. So I need to create this in a way that NetTiers can discover it and build the code objects to support it.

First I have to create the stored proc with a discoverable name. This requires several settings in the NetTiers template. First, that I want custom stored procs discovered so IncludeCustoms=true. Second, I want any stored procs to have a naming prefix so ProcedurePrefix=usp. Third, I need to handle the actual name of the stored proc. NetTiers uses discovery based on a template where the zeroth parm is the table name and the first parm is the Procedure Prefix so CustomProcedureStartsWith={1}_cust_{0}_. The remainder of the stored proc name is irrelevant but what is returned is very important. I usually return all columns which is NetTiers default object handling. If I choose not to include all columns, I would have to deal with an IDataReader or a DataSet.

If all the other stored procs and NetTiers code has been generated and you only new a few stored procs to be discovered, make sure to set ExecuteSQL=false and SourceTables=(only immediate tables.)

Once you generate your objects, you can verify the stored proc was discovered by looking in the Data layer in the base directory for the TableNameProviderBase.generatedCore.cs in the Custom Methods region.

Thursday, March 27, 2008 9:00:03 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |