Request a topic or
contact an Arke consultant
404-812-3123
January 2008

Arke Systems Blog

Useful technical and business information straight from Arke.

About the author

Author Name is someone.
E-mail me Send mail

Recent comments

Archive

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2017

Creating a Horizontal Tabbed Menu with the Menu Control

I needed to create a quick horizontal tabbed menu with the Menu control.  The tabs have rounded corners so we're using image backgrounds.  We also have different images for the selected tab and when you hover.

image

<asp:Menu runat="server" ID="Menu1" SkinID="MenuHorizontalTabs">
    <Items>
        <asp:MenuItem Text="Tab 1" Value="Tab1" Selected="true" />
        <asp:MenuItem Text="Tab 2" Value="Tab2" />
        <asp:MenuItem Text="Tab 3" Value="Tab3" />
        <asp:MenuItem Text="Tab 4" Value="Tab4" />
    </Items>
</asp:Menu>

Then I added MenuHorizontalTabs to my skins file. 

<asp:Menu runat="server" SkinID="MenuHorizontalTabs" Orientation="Horizontal">
    <StaticItemTemplate>
        <div>
            <span>
                <asp:Literal runat="server" ID="Literal1" Text='<%# Eval("Text") %>' />
            </span>
        </div>
    </StaticItemTemplate>
    <StaticSelectedStyle CssClass="MenuHorizontalTabsSelectedMenuItem" />
    <StaticHoverStyle CssClass="MenuHorizontalTabsHoverMenuItem" />
    <StaticMenuItemStyle CssClass="MenuHorizontalTabsMenuItem" />
</asp:Menu>

Now, let's look at the CSS file.

.MenuHorizontalTabsMenuItem * div
{
    background:url(/images/header/left_both.gif) no-repeat left top; 
    height: 22px; 
    padding-left: 9px; 
    cursor: pointer;
}
.MenuHorizontalTabsMenuItem * span
{
    background:url(/images/header/right_both.gif) no-repeat right top; 
    padding: 5px 15px 4px 6px; 
    font-size: 10px; 
    color: #333; 
    height: 22px;
}
.MenuHorizontalTabsSelectedMenuItem * div
{
    background-position: 0px -150px;
}
.MenuHorizontalTabsSelectedMenuItem * span
{
    background-position: 0px -150px;
}
.MenuHorizontalTabsHoverMenuItem * div
{
    background-position: 0px -150px;
    color: Blue;
    text-decoration: none;
}
.MenuHorizontalTabsHoverMenuItem * span
{
    background-position: 0px -150px;
    color: Blue;
    text-decoration: none;
}

And finally, let's see the images.

left_both

left_both.gif

right_both

right_both.gif


Categories: ASP.NET
Posted by eric stoll on Thursday, January 31, 2008 10:07 AM
Permalink | Comments (0) | Post RSSRSS comment feed

SQL Server 2005 Reporting Services on Vista x64

Recently I was working on a project that called for Reporting services, and I ran into a couple of annoying issues with using it on Vista (x64, not sure if it behaves similarly on x86 versions). 

 

The first issue I ran into was setting up the Reporting Services server with SQL Server Express 2005 Advanced and IIS 7.

 

Basically if you're trying to set up the Reporting server with Integrated security, don't.  It doesn't work.

You need to install SQL Server 2005 in mixed mode.  You'll need to create a SQL User for logging into the reporting services databases.  And when you configure reporting services for IIS 7, use this user for your SQL connection.   You can leave your .config files for the web site as user Impersonate, as long as that user has access to the reporting services directories.

 

 

The Second issue is with using the Report Viewer with Visual Studio 2008.  I don't know if this is an issue with other configurations, but I ran into it when I was using forms authentication.

 

You need to include a security exclusion for the ReportViewer, else VS 2008 will CRASH when trying to run a report.

 

Here is the Security config line I used.  Modify as needed.

<location path="Reserved.ReportViewerWebControl.axd">
    <system.web>
        <authorization>
            <allow users="*"/>
        </authorization>
    </system.web>
</location>

 

kick it on DotNetKicks.com


Posted by trenton adams on Sunday, January 27, 2008 6:38 PM
Permalink | Comments (0) | Post RSSRSS comment feed

LinqDataSource with uniqueidentifier Primary Key

I tend to use uniqueidentifiers for my primary key columns with a default value of newid() so the database will generate a Guid for me.  I created a LinqDataSource and bound that to a DetailsView control.  I was able to insert my first row within 10 minutes of writing all this code but subsequent inserts would always throw a unique constraint exception.  After looking at the database, I saw my first row's Id was Guid.Empty so I knew that Linq was pushing this as a default value to the database instead of letting the database create a newid() for me.  It turns out the solution is very simple.  Open your DBML file, select the primary key column and change the Auto Generated Value property to true.  So far, I'm still impressed with Linq.

Categories: LINQ
Posted by Eric Stoll on Sunday, January 20, 2008 2:18 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Web Application Foundation - Part 1 - Preparing a Continuous Integration Server

This is the first article in a series that I intend to be a step by step walkthrough of preparing for a new web project. 

  1. Part 1 is going to cover creating a continuous integration server using CruiseControl.NET, and assumes that you already have a server setup with Windows Server and a Visual Source Safe Server.
  2. Part 2 is going to cover setting up a client computer for running Visual Studio 2008 and integrating with CCNet and VSS
  3. Part 3 is going to cover creating a sample web application with a deployment project and having this project run in our continuous integration environment
  4. Part 4 will be adding the ASP.NET Membership Provider to our Web Application
  5. Part 5 is going to cover using MVP Architecture to be able to unit test our web application
  6. Part 6 will be using WiX to create a setup file
  7. Finally part 7 will go over various tools and applications that really go hand-in-hand with CI.  Tools will include FxCop, Simian, NCover, NDepend, and others.

We're going to start with a base install of Windows Server 2003 (2008 will work just fine as well), all all the latest updates from Microsoft. 

  • Create a user "CruiseControl" with local administrative rights
  • Make sure that IIS is installed and running.
  • Create a shared directory called "Builds", and another directory called "vssroot"
  • Install the .NET Frameworks v2.0, v3.0, and v3.5
  • Install WiX v3.0.3621 or greater
  • Install CruiseControl.NET v1.3
  • Optionally install CCNetConfig a tool to edit CruiseControl.NET configuration files with a GUI
  • Install the Visual Source Safe 2005 client utilities
  • Install Nant 0.85
  • Run services.msc
  • Open the properties of the "CruiseControl.NET Server" service
  • Set the Startup type to Automatic
  • Under the Log On tab, select Log on as the CruiseControl user you created

Configuring the VSS Database: (more on this later)

  • Create a new VSS Database
  • Add a read/write user by the name cruisecontrol 
  • The project should be layed out in the following manner:
    • $/
    •     trunk
    •         buildScript
    •             cruise.build
    •         source
    •             project.sln

Configuring the project in CruiseControl.NET

  • Open the CruiseControl.NET Config file located by default here:  C:\Program Files\CruiseControl.NET\server\ccnet.config
  • Insert the following project xml into the config file changing the fields in brackets to meet your needs: 

 

<project name="[MyProjectName]">
<sourcecontrol type="vss">
<project>$/trunk</project>
<username>cruisecontrol</username>
<password>[CruiseControlUserPassword]</password>
<executable>[path to visual source safe]\SS.EXE</executable>
<ssdir>[ Path to VSS database .ini file ]\</ssdir>
<autoGetSource>True</autoGetSource>
<applyLabel>False</applyLabel>
<workingDirectory>c:\vssroot\[MyProjectName]\</workingDirectory>
<cleanCopy>True</cleanCopy>
      </sourcecontrol>
<triggers>
            <intervalTrigger seconds="60" />
</triggers>
      <tasks>
            <nant>
                  <executable>C:\Program Files\nant-0.85\bin\NAnt.exe</executable>
                  <baseDirectory>C:\vssroot\[MyProjectName]</baseDirectory>               
                  <buildFile>C:\vssroot\[MyProjectName]\buildScript\cruise.build</buildFile>
                  <nologo>True</nologo>
                  <buildTimeoutSeconds>30</buildTimeoutSeconds>
                  <targetList>
<target>run</target>
                  </targetList>
            </nant>
</tasks>
</project>

 

  • All of the other scripts will be included in VSS and pulled automatically during a build.

 

[Added]

 

I had a couple questions about the proper way to install NAnt in our configuration.  Basically there are three items you need in order to have a successful installation.

  1. Unzip the NAnt-0.85 folder into your program files directory under c:\Program File\NAnt-0.85
  2. Unzip NAnt-Contrib into the NAnt installation directory.  The files will need to be in the following Locations:

    \
        bin\
            lib\
                net\
                    CollectionGen.dll
                    Interop.MsmMergeTypeLib.dll
                    Interop.StarTeam.dll
                    Interop.WindowsInstaller.dll
                    SourceSafe.Interop.dll

            tasks\
                net\
                    MSITaskErrors.mst
                    MSITaskTemplate.msi
                    MSMTaskErrors.mst
                    MSMTaskTemplate.msm
                    NAnt.Contrib.Tasks.dll
                    NAnt.Contrib.Tasks.pdb (not available for releases)
                    NAnt.Contrib.Tasks.xml

            SLiNgshoT.Core.dll
            SLiNgshoT.exe

    Note: you might have to manually create the "tasks\net" and "lib\net" directories. (taken from NAnt Contrib Readme file)

    3. Finally you'll need to modify the NAnt config file in order for it to handle working with VS2008, Palermo offers an excellent article on this:

    Jeffrey Palermo's Explaination of the NAnt Upgrade to 3.5

     


kick it on DotNetKicks.com

Posted by Trenton Adams on Friday, January 4, 2008 4:23 PM
Permalink | Comments (0) | Post RSSRSS comment feed

DNN Performance Troubleshooting

I was troubleshooting a client's DNN site today because the response time was horrible.  Their site was relatively small and every page load was taking up to 30 seconds.  By logging in to the production server, I could see that the CPU would spike to 100% on the sqlsrvr.exe process during the entire page load so that gave me a starting point.  Then I dug in to SQL Profiler to identify the problematic query.  The resolution was to delete everything from the ScheduleHistory table.  I purged the data and the website immediately became fast again.  If you notice SELECT queries on the ScheduleHistory table taking a long time, this may be the solution to your problem.


Posted by eric stoll on Thursday, January 3, 2008 6:13 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Extending LINQ to SQL

We have been experimenting with LINQ to SQL on a couple projects lately and I am constantly impressed.  I'll post some tidbits as I come across some neat features.

Today I had to display the last 4 digits of a customer's credit card number on the UI.  I already have a DBML file in my project and the Customer table has been added to the designer.  Customer has a CreditCardNumber property (ignoring encryption for purposes of this example).  Of course business logic layers aren't new but all too often, you would find logic in the UI that displays the right 4-digits.  But now implementing the BLL is even easier by simply implementing a partial class.

Partial Public Class Customer
    Public Readonly Property Last4 as String
        Get
            Return Right(Me.CreditCardNumber, 4)
        End Get
    End Property
End Class

You can take it one step further and override the CreditCardNumber property and change the Get to return ************XXXX instead of the clear text credit card number, which will make your business logic even more secure.


Posted by Eric Stoll on Wednesday, January 2, 2008 1:40 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Serving PDF Reports from ASP.NET using SQL Reporting Services

I recently had to create a PDF on the server-side and deliver it to the client via ASP.NET.  There are several open source PDF APIs out there so the options are vast.  But I chose to leverage SQL Reporting Services instead of learning another API.  Plus, why program a report when you can design it using proven tools?

Using SQL Server Business Intelligence Development Studio, I created a reports project, developed a report called Report1, and deployed to SQL Reporting Services.  Here is a great article if you want help creating your first report.  Tutorial: Designing Your First Report in SQL Server Reporting Services.

Next, in my ASP.NET application, I added a Web Reference to http://server/Reportserver/reportservice.asmx and named it ReportsWS, which generates all the proxy classes needed to interface with Reporting Services from my code.  Now I just have to write a little bit of code to generate the report and deliver the PDF.  In the example below, you can also see how to pass parameters to the report named StartDate and EndDate.

Using rs As New ReportsWS.ReportingService()
    rs.Credentials = New System.Net.NetworkCredential(ConfigurationManager.AppSettings("RSUser"), ConfigurationManager.AppSettings("RSPassword"), ConfigurationManager.AppSettings("RSDomain"))
   
Dim sReportPath As String = ConfigurationManager.AppSettings("RSReportPath")
   
Dim sReportName As String = "Report1"

   
Dim ResultStream() As Byte

   
Dim StreamIdentifiers() As String = Nothing

   
Dim optionalParams(2) As ReportsWS.ParameterValue

   
Dim OptionalParam As String = Nothing

   
Dim optionalWarnings As ReportsWS.Warning() = Nothing
 
   
optionalParams(0) = New ReportsWS.ParameterValue

   
optionalParams(0).Name = "StartDate"

   
optionalParams(0).Value = "1/1/2007"

   
optionalParams(1) = New ReportsWS.ParameterValue

   
optionalParams(1).Name = "EndDate"

   
optionalParams(1).Value = "12/31/2007"

   
' Create and set the content type string
   
Dim contentType As String = "application/pdf"

   
ResultStream = rs.Render("/" & sReportPath & "/" & sReportName, "PDF", Nothing, "<DeviceInfo><StreamRoot>/RSWebServiceXS/</StreamRoot></DeviceInfo>", optionalParams, Nothing, Nothing, OptionalParam, OptionalParam, optionalParams, optionalWarnings, StreamIdentifiers)

   
Response.Clear()
   
Response.ContentType = "application/octet-stream"

   
Response.AddHeader("Content-Type", contentType)

   
Response.AddHeader("Content-Disposition", "attachment;filename=" & sReportName & ".pdf")
               
    Response.BinaryWrite(ResultStream)

   
Response.Flush()
               
   
Response.End()
           
End Using

 


Posted by Eric Stoll on Wednesday, January 2, 2008 9:39 AM
Permalink | Comments (0) | Post RSSRSS comment feed