public class ben:harrell

January 3, 2013

TFS Synchronization and Migration

Martin Hinshelwood recently posted about the current state of TFS sync and migration tools here and while I thought the post was very detailed and covered the market pretty well I think he did miss one smaller tool that I’ve used with some success:  TFS Bug Item Synchronizer .

Now I don’t know what his criteria was for the article and if perhaps this tool didn’t fall into some category but I definitely think it is worth a look especially for smaller companies with smaller budgets or even TFS teams that might not need one of the huge enterprise solutions.  (and it even has a trial period)

From the product site

 

TFS Bug Item Synchronizer is an tool which allows testing and development teams to work together using tools built for their usage. Testers enter defects in Quality Center and when defect is created and updated into TFS, developer can fix it, link all changes to it and mark it as fixed. After this the tester will continue process on Quality Center side to verify the fix.

 

I implemented this product last year and like most sync tools it takes a little up front work and definitely some understanding of how TFS works but the support  that was available was incredibly helpful and you can’t beat the price point.

So hopefully this will add one more tool to what seems to be an ever growing list of tools in this space.   Now if we can just get one that requires little to no configuration  😉

 

September 18, 2007

SSIS Custom Component – ProvideComponentProperties vs ReInitializeMetadata

Filed under: .NET, Custom Source Component, database, Integration Servicees, SQL Server 2005, SSIS, Technology — benjamin harrell @ 9:47 am

 

I am currently working on a custom source component in SSIS that converts EBCDIC data to ASCII inline and one of the challenges I face is creating dynamic outputs and output columns based on the layout process of the source component.  Normally, when you want to additional outputs on your component you create them in by override ProvideComponentProperties like this:

public override void ProvideComponentProperties()
{
    // add the outputComponentMetaData.UsesDispositions = true;
   IDTSOutput90 output =     ComponentMetaData.OutputCollection.New();
   output.Name = “My New Output”;
   output.ExternalMetadataColumnCollection.IsUsed = true;

This works really well if all of your output information is available at design time (in the SSIS ui) but what happens if your dynamic outputs are determined at runtime?  ProvideComponentProperties is only called one time, when the component is added to designer surface.  In order to dynamically add outputs at a later point you must use ReInitializeMetaData which is called whenever Validate returns VS_NEEDSNEWMETADATA.

public override void ReinitializeMetaData()
{
   // add the output
   ComponentMetaData.UsesDispositions = true;
   IDTSOutput90 output = ComponentMetaData.OutputCollection.New();
   output.Name = “My New Output”;
   output.ExternalMetadataColumnCollection.IsUsed = true;
 }
 

Note that I have not shown the additional work of adding columns to either of these scenarios, you will need to add that code yourself. 

July 10, 2007

SSIS Row Limits and DefaultBufferMaxRows

Filed under: C#, database, errors, Integration Servicees, SQL Server 2005, SSIS, Technology — benjamin harrell @ 9:51 pm

I had an odd issue during some testing I was doing on a custom source component I’m writing for EBCDIC data conversion.  I first assumed that surely my code was at fault but the test just seemed to simple to be “my code”.  So here’s the scenario,  I have a file with 100,000 bytes of the number ‘1’ in EBCDIC.  I created a simple package to import the file as 1 byte rows into a Dataset Destination.  I was surprised when I executed the package and found that only 65,536 rows were processed.  Now if you have been around software for more than a week you probably recognize this magic number and unfortunately it triggers all sorts of theories about what could possibly be going wrong.  Well, I’m still trying to investigate the “why” and I’ll update this post and welcome comments if anyone has input but for now the solution to this oddity is to increase the DefaultBufferMaxRows to greater than your number of records.  This seems like a horrible workaround for a situation that should happen quite often so the hunt continues…

March 1, 2007

Reporting Services 2005 Rotation and Orientation

Filed under: .NET, ASP.NET, C#, Reporting Services 2005, SQL Server 2005, Technology — benjamin harrell @ 4:54 pm

As many of you might have figured out by now Reporting Services 2005 doesn’t support rotating objects or multiple orientation (as in per sub report).  Depending on your situation there might still be an answer.  I was in a situation recently where I need certain pages of a report in landscape and some in portrait.  I was told that this is not possible out of the box in Reporting Services 2005 but have since found a workaround that might work for you.  Microsoft has done a great job with making SSRS an open architecture and the web services are a key part of this approach.  Behind the scenes of your Report Viewer control (in “remote” mode) it is actually making a request to the Render command of the SSRS Web Service.  So to pull of the rotation of a report I created a new web page with a web reference to the ReportService.  I then request the report in IMAGE format and store the byte[].  I create a new Bitmap object and stream in the byte[] so that I have full control over my newly created report Image in GDI.NET.  Bitmap supports a RotateFlip method that has just what we need and then I save the Bitmap to the Response.OutputStream object.  You are probably familiar with the concept of pointing an Image to an ASPX page that dynamically generates the bytes of the Image and this solution is no different.  Once you have an ASPX that can generate a rotated Image of the report then you treat it just like any other Image in the Report or on a WebForm.

This solution was adapted from Bryan Kelly’s post on Programmatically Printing RS 2000 Reports found HERE

The source code for the page is below:

 using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Drawing.Imaging;
using System.Drawing;
using System.Runtime.InteropServices; // For Marshal.Copy
using System.IO;
using System.Web.Services.Protocols;

public partial class ASR_ReportAsImage : System.Web.UI.Page
{
    ReportService.ReportingService rs;
    private byte[][] m_renderedReport;
    private System.Drawing.Graphics.EnumerateMetafileProc m_delegate = null;
    private System.IO.MemoryStream m_currentPageStream;
    private System.Drawing.Imaging.Metafile m_metafile = null;
    int m_numberOfPages;
 
    protected void Page_Load(object sender, EventArgs e)
    {
       
        rs = new ReportService.ReportingService();
        rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
        PrintReportAsImage();
    }

    public byte[][] RenderReport(string reportPath)
    {
        // Private variables for rendering
        string deviceInfo = null;
        string format = “IMAGE”;
        Byte[] firstPage = null;
        string encoding;
        string mimeType;
        ReportService.Warning[] warnings = null;
        ReportService.ParameterValue[] reportHistoryParameters = null;
        string[] streamIDs = null;
        Byte[][] pages = null;

        // Build device info based on the start page
        deviceInfo =
           String.Format(@”<DeviceInfo><OutputFormat>{0}</OutputFormat></DeviceInfo>”, “emf”);

        //Exectute the report and get page count.

        // Renders the first page of the report and returns streamIDs for
        // subsequent pages
        firstPage = rs.Render(
           reportPath,
           format,
           null,
           deviceInfo,
           null,
           null,
           null,
           out encoding,
           out mimeType,
           out reportHistoryParameters,
           out warnings,
           out streamIDs);
        // The total number of pages of the report is 1 + the streamIDs        
        m_numberOfPages = streamIDs.Length + 1;
        pages = new Byte[m_numberOfPages][];

        // The first page was already rendered
        pages[0] = firstPage;

        for (int pageIndex = 1; pageIndex < m_numberOfPages; pageIndex++)
        {
            // Build device info based on start page
            deviceInfo =
               String.Format(@”<DeviceInfo><OutputFormat>{0}</OutputFormat><StartPage>{1}</StartPage></DeviceInfo>”,
                 “emf”, pageIndex + 1);
            pages[pageIndex] = rs.Render(
               reportPath,
               format,
               null,
               deviceInfo,
               null,
               null,
               null,
               out encoding,
               out mimeType,
               out reportHistoryParameters,
               out warnings,
               out streamIDs);
        }

        return pages;
    }

    public bool PrintReportAsImage()
    {
        this.RenderedReport = this.RenderReport(“/ASR Prototype/ASR_TransactionOverview”);

        // Wait for the report to completely render.
        if (m_numberOfPages < 1)
            return false;

        for (int i = 0; i < m_renderedReport.Length; i++)
        {
            //write all of the pages to stream….

            System.IO.MemoryStream memstream = new System.IO.MemoryStream(m_renderedReport[i], false);
            System.Drawing.Bitmap oBitmap = new System.Drawing.Bitmap(memstream, true);
            //now rotate the bitmap 90 degrees
            oBitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
            //write it to the output stream
            Response.ContentType = “image/jpeg”;
            oBitmap.Save(Response.OutputStream, ImageFormat.Jpeg);

        }
        return true;
    }
 

    // Method to draw the current emf memory stream
    private void ReportDrawPage(Graphics g)
    {
        if (null == m_currentPageStream || 0 == m_currentPageStream.Length || null == m_metafile)
            return;
        lock (this)
        {
            // Set the metafile delegate.
            int width = m_metafile.Width;
            int height = m_metafile.Height;
            m_delegate = new Graphics.EnumerateMetafileProc(MetafileCallback);
            // Draw in the rectangle
            Point destPoint = new Point(0, 0);
            g.EnumerateMetafile(m_metafile, destPoint, m_delegate);
            // Clean up
            m_delegate = null;
        }
    }
    private bool MoveToPage(Int32 page)
    {
        // Check to make sure that the current page exists in
        // the array list
        if (null == this.RenderedReport[m_currentPrintingPage – 1])
            return false;
        // Set current page stream equal to the rendered page
        m_currentPageStream = new MemoryStream(this.RenderedReport[m_currentPrintingPage – 1]);
        // Set its postion to start.
        m_currentPageStream.Position = 0;
        // Initialize the metafile
        if (null != m_metafile)
        {
            m_metafile.Dispose();
            m_metafile = null;
        }
        // Load the metafile image for this page
        m_metafile = new Metafile((Stream)m_currentPageStream);
        return true;
    }
    private bool MetafileCallback(
       EmfPlusRecordType recordType,
       int flags,
       int dataSize,
       IntPtr data,
       PlayRecordCallback callbackData)
    {
        byte[] dataArray = null;
        // Dance around unmanaged code.
        if (data != IntPtr.Zero)
        {
            // Copy the unmanaged record to a managed byte buffer
            // that can be used by PlayRecord.
            dataArray = new byte[dataSize];
            Marshal.Copy(data, dataArray, 0, dataSize);
        }
        // play the record.     
        m_metafile.PlayRecord(recordType, flags, dataSize, dataArray);

        return true;
    }
    public byte[][] RenderedReport
    {
        get
        {
            return m_renderedReport;
        }
        set
        {
            m_renderedReport = value;
        }
    }

}

October 7, 2006

TreeView Render Speed

Filed under: .NET, Technology — benjamin harrell @ 10:15 pm

Here is a quick tip when doing large updates and adds to the Windows Forms Treeview control. Use the beginupdate() method to “turn off” rendering and then after your changes are complete use the endupdate() method to turn rendering back on which will then render all of your changes.

Sometimes it is necessary to do this for a control that doesn’t have these wonderful methods but no to worry you can easily derive a control, add your own “flag” variable and then just override the OnPaint method and if your variable is set to not render then simply return from OnPaint. I have also added the Begin and EndUpdate methods below for setting the variable. If you want to force the control to repaint then you can call EndUpdate( true ). Here is a sample :

public class FastDrawTreeView : System.Windows.Forms.TreeView
{
private bool _disableRendering = false;

public void BeginUpdate()
{
_disableRendering = true;
}

public void EndUpdate(bool redraw)
{
_disableRendering = false;
if (redraw)
this.Refresh();
}

protected override void OnPaint(PaintEventArgs e)
{
if (_disableRendering)
return;
base.OnPaint(e);
}
}

July 29, 2006

ASP.NET 2.0 where are my references!!!!

Filed under: .NET, Technology, Visual Studio — benjamin harrell @ 6:27 pm

ASP.NET 2.0 web projects have references but don’t show them as a ‘References’ folder in the project.  This might be a preference setting buried somewhere in the options page but for now it is easy enough just to right-click the project and choose the menu item ‘Property Pages’.  You will get a screen like below where you can manage both project and web references.   

 Project Properties Page

July 26, 2006

Web Parts Manager personalization without SQLExpress

Filed under: .NET, Technology — benjamin harrell @ 3:15 pm

Earlier I posted about wanting to put personalization on a separate SQL instance (not local).  Well, this gives me a chance to say thanks to the MSDN2 team for making more information available in .NET 2.0.  I was a little worried during the BETA because of so many empty pages but MSDN is loaded with good information and plenty of walkthroughs!  There is even a MSDN WIKI found here .  OK here is the answer I promised: 

Personalized settings are not tied to a single browser session. Because they are stored in long-term storage, the application can retrieve a user’s settings each time the user visits a specific page.

Personalization uses an ASP.NET application services database to store personalization data. By default, ASP.NET creates this database automatically in a subfolder named “app_data” when an ASP.NET application first uses personalization or one of the other application services such as roles, membership or profiles. Also by default, ASP.NET creates the database as a single SQL Server Express database file that contains the database schema for all of the application services. Using the Web.config file, you can configure your application so that a separate database file is created for personalization. Further, in the Web.config file, you can specify a SQL Server database to store the application services data instead of using the default SQL Server Express database file.

The mechanism for storing and retrieving personalization data consists of a provider component and a data store. ASP.NET includes a default Microsoft SQL provider and database. You can also create a custom provider and configure it to use any data store.  (THANK GOD!  gotta love the new provider model)

essentially this is the web.config section you need under <system.web>

(the MSDN entry is here for the element)

<webParts><personalization ><providers>

<remove name=AspNetSqlPersonalizationProvider />        

<add connectionStringName=my_connection_stringname=AspNetSqlPersonalizationProvider

type=System.Web.UI.WebControls.WebParts.SqlPersonalizationProviderapplicationName=//>

 </providers></personalization></webParts>

Some of this was information was found in a really good article on personalization here . 


 

technorati tags:, , ,

odd sql 2005 connection error

Filed under: .NET, Technology — benjamin harrell @ 2:46 pm

An error has occurred while establishing a connection to the server.  When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: SQL Network Interfaces, error: 26 – Error Locating Server/Instance Specified)

 If all else looks correctly configured then this might be a control using personalization that uses SQLExpress by default.  An example of such a control is the WebPartsManager, this control is a wonderful control in ASP.NET 2.0 and allows for the web part behavior on a page but if you enable the personalization in the properties screen (default is enabled) then this control will attempt to use SQLExpress to store its personalization info.  This might be fine for some sites but not everyone wants to run SQLExpress in production so I disabled personalization for now until I can figure out how to point personalization to a SQL Instance on another server.  I’ll post that as soon as I figure it out, in the meantime if anyone has the answer please fill me in.

July 20, 2006

Search Engine Optimization and Keyword Choice

Filed under: .NET, Technology, Uncategorized — benjamin harrell @ 6:10 pm

I learned a funny lesson today that would seem obvious but might be helpful to repeat.  When we create .NET websites especially outward facing, commercial sites we try to squeeze every last bit of Search Engine Optimization in order to get the almighty Google page rank up but is this always the best approach?  Case in point, I am creating a site for a local car company from my home town that specializes in Dodge vehicles and the purpose of one page is to attract Dodge Caravan buyers.  I worked overtime to get this page optimized for the word “caravan”, perhaps I should have been more specific….

 geo stats

June 7, 2006

Tech Interviews

Filed under: Careers, Technology — benjamin harrell @ 9:52 pm

Continuing with the “career” theme, I thought I would take a second to talk about tech interviews. I have done quite a few interviews and I have seen what I consider all types so I wanted to talk about the most common and see if anyone has experience with these interviews and perhaps any others that I missed. So here is the short list from easiest to most difficult!

1. The Conversation – This is usually a joke, if you can talk about a few things on your resume and some newer technologies without swallowing your tongue you are probably going to do well. The trick to this inteview is find out what peeks the interviewers interest and have a fun conversation about it. Don’t forget to plug yourself when appropriate, not in an awkward way but in the flow of the conversation. (ex. “I am very excited about C# generics, I used several strongly typed collections in my last project and can see the benefit.”)

2. The Behavioral – This interview type is a little different, you are given questions where you have to discuss situations. For example, “Tell me about a time when you disagreed with your boss and how you handled it.” The best way to handle these is to be truthful (duh!) but prepare for this one by answering some common questions in advance. Here are some links to sample questions:

http://www.quintcareers.com/sample_behavioral.html
http://www.brockport.edu/career/behave.htm
http://jobsearchtech.about.com/od/interview/a/behavioral.htm

3. The Quiz – This type of interview is really just a machine gun of questions about your past, projects, technologies, and pretty much any other trivia you can think of. It really helps to be prepared for this type of interview but in a pinch it is ok to say that you haven’t worked with a certain tech (if it isn’t on your resume) or to give the old “I remember reading about that but haven’t had a chance to use it, I’m sure I could find the answer pretty fast if needed.” Don’t be surprised if you get brain teasers and code on the whiteboard questions in this one. Don’t get too fancy on the whiteboard stick to pseudocode if not given a language and just make sure that you talk about what you are doing. When you get a brain teaser don’t just think about it and freeze up. Start making notes and talking about the problem, most interviewers don’t care too much about the answer just your process for getting it.

I hope these reviews help, feel free to leave a comment about interviews you have had and any tough questions you can remember.

Older Posts »

Create a free website or blog at WordPress.com.