Posts Tagged C#

A new guard page for the stack cannot be created

 

You get a nice error that says, “A new guard page for the stack cannot be created”, well easy fix. I could be long winded, but the issue is simply this, you caused a stack overflow.

How you say? Well, check to see if you are using a Server.Transfer that transfers you to a page that then Transfers you back and forth, or even to yourself.

Have login code that checks to see if you are logged in? If not, then it bounces you to a login page. Maybe you put it in a master page. Well, if the login page uses the master page, it will just keep transferring itself to itself and you blow the stack.

Response.Redirect will give you a different error as the browser only jumps a low number of redirects before giving up. Server.Transfer uses the internal stack, so it blows up on the server itself.

Happy coding!

, , , ,

No Comments

How to optimize download performance for files stream from your database via asp.net

I had a requirement to create a download page that streamed office documents to the client from our website. The way Office (Word and Excel at least) open documents from URL’s are the browser downloads it first, then Word and Excel call back to the server to make sure nothing changed.

Normally, these results in you streaming the file twice, unknowingly. That is bad for performance and your bandwidth. No one wants a laggy and latent operation.

So, what is there you can do? Well, if you intercept the headers to a normally hosted document, you will see a header called ETag. This is basically a document hash reference that can be used when the follow request occurs.

Ok, English right.

So, the solution I implemented is pretty easy. I created a unique hash tag (it can be a true hash, or simply a rowid and the recordtimestamp combined) and set the ETag header.

You ask, “Well, how does setting an ETag header prevent duplicate efforts?”. It doesn’t. Here comes the work you do first.

When a request comes in. Look for a header called: IF-None-Match. If you see it, you need to jump into a little simple logic.

First, calculate your Etag value and compare it to the value of the If-None-Match and if it, well, matches, you get to do something special. If it doesn’t match, act like nothing happened and continue on with the normal data return.

So, what is the something special you ask? Simple, Clear your response contents, set your StatusCode to 304, and end the response .

Now I hear, geez. You made this sound very complicated. Is there an easier way to explain this?

Sure…I’ll try.

 

Here are the steps for simplicity:

  1. Check for If-None-Match header
    1. If Exists, compare value of header to your hash(id combo, CRC, whatever you want to use)
      1. If Matches,
        1. Set StatusCode =304,
        2. Clear Response Contents
        3. End Response
      2. Else.
        1. Continue as normal
  2. Normal Winking smile
    1. Generate ETag hash (again, however you want to identify this file as unique, something that changes if the file changes)
    2. Response with ETag in header

What does that mean in code? I don’t speak flow.

Here is a code example.

  private const string _wordMimeType = "application/msword";// (for Microsoft Word files)
    private const string _excelMimeType = "application/vnd.ms-excel"//(for Microsoft Excel files)
   
    private void StreamDocumentfromDatabase(Guid documentID)
    {
        string etagFilter = Request.Headers["If-None-Match"];
        string etag;
        //load the bits into memory
        using (var context = new EvidenceReviewContext())
        {
            if (!string.IsNullOrEmpty(etagFilter))
            {
                //check db to see if to respond with ignore (cached copy already found)
                var blobCheck = (from ev in context.Documents
                                 where ev.documentID == documentID &&
                                 ev.BlobDataId.HasValue
                                 select ev.BlobDataId.Value
                                     ).FirstOrDefault();
                if (blobCheck != null)
                {
                    if (etagFilter == (documentID.ToString() + blobCheck.ToString()))
                    {
                        Response.ClearContent();
                        Response.StatusCode = 304;                       
                        Response.End();
                    }
                }
            }

            var theBlob = (from ev in context.Documents
                           where ev.documentID == documentID &&
                           ev.BlobDataId.HasValue
                           select new
                           {
                               Data = ev.BlobData.Data,
                               FileExtension = ev.FileExtension,
                               BlobID = ev.BlobDataId.Value
                           }).FirstOrDefault();

            if (theBlob == null)
                return;

            if (theBlob.FileExtension.ToLower().StartsWith(".doc"))
                Response.ContentType = _wordMimeType;
            else if (theBlob.FileExtension.ToLower().StartsWith(".xls"))
                Response.ContentType = _excelMimeType;
            Response.AddHeader("Content-Disposition", "attachment; filename=" + documentID.ToString().Replace("-", "") + theBlob.FileExtension);
            etag = documentID.ToString() + theBlob.BlobID.ToString();
            Response.AddHeader("ETag", etag);

            //Write the file directly to the HTTP content output stream.

            //NOTE: THIS IS NOT MEMORY EFFICIENT AT ALL. TODO: change compression technique for documents
            byte[] dataToSend = null;
            using (MemoryStream dataStream = new MemoryStream(theBlob.Data))
            {
                using (MemoryStream stream = UnzippedData(dataStream))
                {
                    dataToSend = stream.ToArray();
                }
            }
            //relieve some pressure by pushing write of data outside of the blocks above to allow for memory free.
            Response.BinaryWrite(dataToSend);
            Response.Flush();
        }
        Response.End();
    }

I hope this article helped you out a little and saved you some serious download times. (When Office revisits the file, it remembers the ETag. So you get efficiencies all over the place).

Happy Coding!

, , , , , ,

No Comments

Deep Clone objects in Silverlight with simple extension method and Serialization

I had the need to clone objects to do original vs modified delta checks. I decided that I could either do a lot of work to make copies or go the easy route. As always, smarter over harder prevailed.

Here is a simple extension class to put into your infrastructure. Enjoy!


using System;
using System.IO;
using System.Xml.Serialization;

namespace Seekford.Extensions
{
public static class ObjectCopyMachine
{
/// <summary>
/// Extension to perform a deep Copy of the object specified.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T Clone<T>(this T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}

// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
XmlSerializer serializer = new XmlSerializer(source.GetType());
Stream stream = new MemoryStream();
using (stream)
{
serializer.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)serializer.Deserialize(stream);
}
}
}
}


Now you can just call any object and say. Abracadabra……      myObject.Clone();

Happy Coding!

, , , ,

1 Comment

Dynamic service endpoint binding for Silverlight using WCF

As part of my continuing effort in create a high quality line of business application in Silverlight, I am laying out a nice foundation for the repository layer. The services interaction is being shielded from the higher layers.

The main hurdle that was annoying me was having to change the endpoint the Silverlight application was pointing by editing a configuration file that was embedded in the application. Mainly, the fact that this required a recompile when going from local build to server. What a pain!!! Bad Microsoft…Bad..

I decided to just write a simple addition to my factory to generate the endpoints on the fly, no more recompile per site required. This also lets the application easily be moved server to server without any pains. Relative WCF URLS should have been a mandatory addition, but alas their not. If Microsoft had thought of everything, I wouldn’t have a job I guess.

Here is the simple code to do a dynamic endpoint in Silverlight. Enjoy!

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Windows;

namespace Seekford.Repository.MyServices
{
    internal class MyServiceFactory
    {
        private const string myServiceLocation = "../Services/MyCService.svc";

        /// <summary>
        /// Creates the binding.
        /// </summary>
        /// <returns></returns>
        private static CustomBinding CreateBinding()
        {
            CustomBinding binding = new CustomBinding();
            binding.Name = "SilverlightBindingGoodTimes";
           binding.Elements.Add(new BinaryMessageEncodingBindingElement());
            binding.Elements.Add(new HttpTransportBindingElement()
                {
                    MaxBufferSize = int.MaxValue,
                    MaxReceivedMessageSize = int.MaxValue
                }
            );

            binding.OpenTimeout = new TimeSpan(0, 5, 0);
            binding.CloseTimeout = new TimeSpan(0, 5, 0);
            binding.ReceiveTimeout = new TimeSpan(0, 5, 0);
            binding.SendTimeout = new TimeSpan(0, 5, 0);         

            return binding;
        }

        /// <summary>
        /// Creates the aand C service client.
        /// </summary>
        /// <returns></returns>
        public static MyServiceClient CreateMyServiceClient()
        {
            var binding = CreateBinding();
            return new MyServiceClient (binding, new EndpointAddress(
                new Uri(Application.Current.Host.Source, myServiceLocation )));
        }       

    }
}

You will obviously need to tailor to your needs, but the idea is pretty straight forward.

Happy coding!

, , , , ,

No Comments

Validate ACH Routing Numbers for EFT and Electronic Checks

I was looking for a way to validate the routing numbers for an eCommerce system I am working on and found a nice VB sample here.

I converted the logic to C# and optimized it for better performance and use.

Hopefully some others out there will find use:

   ///
    /// Validates the routing number.
    ///
    private bool ValidateRoutingNumber(int routingNumber)
    {
        //The check equation for a number a1a2a3a4a5a6a7a8a9 is 3a1 + 7a2 + a3 + 3a4 + 7a5 + a6 + 3a7 + 7 a8 + a9 mod 10 = 0

        //rewrote for higher efficiency

        //must be 9 digits
        if(routingNumber < 100000000)
           return false;
       if(routingNumber > 999999999)
            return false;
        //build array for quick comparison
        //left to right using fun with math.

        int[] routingNumberAsArray =
        {
           routingNumber / 100000000,
            (routingNumber % 100000000) / 10000000,
            (routingNumber % 10000000) / 1000000,
            (routingNumber % 1000000) / 100000,
            (routingNumber % 100000) / 10000,
            (routingNumber % 10000) / 1000,
            (routingNumber % 1000) / 100,
            (routingNumber % 100) / 10,
            (routingNumber % 10) / 1
        };

        //calculate the route sum using the formula above. 3 7 1.
        int routeSum =
            3 * routingNumberAsArray[0] +
            7 * routingNumberAsArray[1] +
            routingNumberAsArray[2] +
            3 * routingNumberAsArray[3] +
            7 *+routingNumberAsArray[4] +
            routingNumberAsArray[5] +
            3* routingNumberAsArray [6] +
            7 * routingNumberAsArray [7] +
            routingNumberAsArray [8] ;
        return routeSum % 10 ==0;
    }

, , , , ,

No Comments

Visual Studio 2010 – Intellisense nonsense

I started getting really annoyed with the Intellisense in VS 2010. It doesn’t automatically highlight the best match for what I am typing. It seems to loosely highlight it, but hitting enter or . doesn’t act upon it.

Well, I figured out how to make it work, but requires a small change in workflow. Hit TAB. Start typing, and when the box highlights AROUND, because it doesn’t seem to select it, hit the TAB key.

Easy solution to an annoying feature. I switch between 2008 and 2010 so much I can’t remember if 2010 has always been this way, or I pissed it off.

Annoying Intellisense irritating me

Happy Coding!

, , ,

2 Comments

InstallUtil and BadImageFormat with a normal C# service

So, you get the old BadImageFormat error when installing your service. If you aren’t writing C++ extensions, then this is probably because you forgot to use the right version of InstallUtil for your target platform.

i.e. x86 build using x64 InstallUtil or vice versa.

Easiest fix? Just build for Any CPU. Then you really don’t have to think about it too hard.

Happy coding!

, , , ,

No Comments

Unknown exception (0×8000500) when querying LDAP in .NET

I had a colleague that kept getting errors doing their LDAP queries. I realized that most developers don’t know about the sticky gotcha with the LDAP. Your url has to have the LDAP capitalized. Crazy right?

So your query string:

ldap://ldapServer:1000/ou=internal,ou=people,dc=yours,dc=com

should be

LDAP://ldapServer:1000/ou=internal,ou=people,dc=yours,dc=com

Nice gotcha, right?

Happy Coding!

, , ,

No Comments

DataGridView bug with the AutoWrap and the AutoRowSize not resizing rows on scroll

I put my DataGridView on a Form and setup the autowrap on the cells. So far so good. Then I realized my rows didn’t autosize.

I set the dataGrid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;.

That worked fine, until…..I had a few thousand rows. Then the grid’s performance sucked.

So, changed it to DisplayedCells. This worked awesome too, until I scrolled. So…….What to do? Well, time for the old workaround..

Simple code change, to correct their retarded flaw. Capture the Scroll event. Then throw this code in.

private void dataGrid_Scroll(object sender, ScrollEventArgs e)
{
       //Workaround for datagrid view bug.
       dataGrid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedHeaders;
       dataGrid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells;
}

That little gem of code will get you back on your way.

Happy Coding!

, , ,

1 Comment

WCF Timeouts: To send or to receive, that is the question!

You decide to write a nice WCF service and you know the operation could take up to 5 minutes to complete. Well, what to do? What to do?

It is possible you say, well I well manually set the operation timeouts in code. That works but is annoying. How about setting the binding timeouts? There you go, nice and easy right?

Let’s take a look at the following binding:

<binding name="MyBinding" closeTimeout="00:00:30" openTimeout="00:00:30" receiveTimeout="00:05:00" sendTimeout="00:0:30">

It looks pretty accurate right? The operation takes 5 minutes or less, so it should work fine with the receiveTimeout being set to 5 minutes. No worries.

Well, YOUR WRONG!. Surprise!

The retarded illogical answer to the above quandary is that WCF uses the sendTimeout to figure out how long to wait to RECEIVE data. I know, painful. You will get timeout errors out the wazoo with the simple mixup of this little fact.

So, next time you setup your bindings, make sure to know the client really cares about the sendTimeout. It doesn’t seem to really concern itself with the receiveTimeout so much.

Here is the right binding:

<binding name="MyBinding" closeTimeout="00:00:30" openTimeout="00:00:30" receiveTimeout="00:05:00" sendTimeout="00:05:00" maxBufferSize="500000000" maxReceivedMessageSize="500000000">
 </binding>

Enjoy this little trickery and hopefully you save some time.

Happy coding!

, , , , , ,

No Comments