Tuesday, February 19, 2013

Fix SSRS Report showing blank pages when exporting to PDF

The problem

You're designing a report on SSRS. Everything looks good until you export it to PDF and you realize that every other page appears blank.

If this is your problem, read on!

The solution

The solution is plain simple and rational but if you're already dealing with a complex report maybe you already switched off your rational part of the brain.

The idea basically is:

[Body width] <= [Report Width]+[Report Left Margin]+[Report Right Margin]

So do the following:

  • Go to Report properties
  • Take note of the Width and the left and right margin values
  • Go to the design view and select Body
  • Take note of the Body width

Do your math with the above formula, adjust as needed and it should be fine!

Cheers!

Sunday, August 05, 2012

Windows 7 / 2008 R2 as Internet Hot Spot!

Have you ever needed to share your internet connection wirelessly and found that the Windows ways are a bit hard?
This is vacations time and if you buy a USB pen you probably could use the hability to share your internet with everybody in the house instead of having to share the USB Pen itself!
Usually you think about a hardware router that supports USB pens but that's usually too expensive, or at least more expensive than FREE! :)
The solution is to use Virtual Router.
As you can see the configuration is straight forward:
  • Set the name of the NetWork (or leave it)
  • Set the password used to connect to this network
  • Select the connection you want to share
  • Finally click Start Virtual Router
So after this, no more sharing your USB pen... Share the connection!!! :) Have fun!

Thursday, June 14, 2012

Include javascript and css on your MasterPage

This is a quick one.

Around the web I see a lot of tricks on how to do this but in fact it's quite easy.

The problem

When you reference a script or a css file on your masterpage it takes the relative path of that file according to the MasterPage location.
The problem is that the MasterPage isn't the one that it's going to be shown, it will be the actual ASPX page the inherits from it.
This said, if your ASPX files are in other location than the MasterPage then the references script files path won't be resolved.

There's also the problem when your site can either run on a virtual folder or as a site on IIS.

The Solution

There are a lot of ways to handle this, but most rely on specific ASPX locations.
I like to have my ASPXs well organized on a convenient way, sometimes in the same folder but most of the times on separated folders.
I don't want to be forced to put all pages on the same folder just because of this.

So the idea is to put all the script and CSS references on the MasterPage <Head%gt;, make use of the server-side tilde (~) and write the correct paths on Page_Init.

If you need to reference jquery and jqueryUI your MasterPage <head> should look similar as the following:

<head runat="server">
    <title></title>

 <link href="<%# ResolveUrl("~/") %>css/custom-theme/jquery-ui-1.8.21.custom.css" rel="stylesheet" type="text/css" />

 <script src="<%# ResolveUrl("~/") %>Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
 <script src="<%# ResolveUrl("~/") %>Scripts/jquery-ui-1.8.20.min.js" type="text/javascript"></script>

    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>

Now, on the MasterPage CodeBehind you should include the following code:

protected override void OnLoad(EventArgs e)
{
 base.OnLoad(e);
 Page.Header.DataBind();
}

DONE!
Keep in mind that the script and css references path you write must always be relative to he root of your site.
This way, everywhere the MasterPage is used the paths to the resources will always be correct.

Cheers!

Saturday, March 24, 2012

Advanced Generic Handler ASHX

See the latest version at CodeProject

Introduction

In ASP.net we have something that is usually overlloked that is called Generic Handlers.
I see a lot o f people using pages to process AJAX requests when we can use this much less expensive endpont.
This is an completelly worked out Generic Handler that trully knows how to handle your http (AJAX and not) requests.

Sample code

Background

For a long time I used plain Generic Handlers (ASHX files) to handle my AJAX requests but it felt stupid and painful.
I mean, the functionality was there but the whole process of handling the requests wasn't straight forward.
So I made a list of the things I would like to have on and handler:

  • Standard way to parse the query string
  • Transparently handle multiple methods within the same handler
  • Support methods with multiple typed arguments, not just strings
  • Support Methods that receive lists as an argument
  • Support passing less arguments than the method is expecting (like optional parameters)
  • Transparently reply eather POSTs or GETs
  • Support default object serialization to JSON but still let me override it on each method
  • Return application/json by default but still let me override it on each method
  • Support JQuery $.ajax request
  • Support request by query string (url right on the browser)
  • A way to visualize the methods the hadler supports (like webservices do)
  • Extensible
And that's it...
I can tell you in advance that it already does all this and maybe more.

Using the code

List the Handler methods

I've provided a very basic way of listing the methods the Handler exposes.
This is specially useful to test if the handler is working correctly (like on webservices)
Do do so just append ?help at the end of the handler URL:

http://localhost/mydemohandler.ashx?help

Calling the Handler from the browser URL

Using this handles is very simple:

  1. Create a new Generic Handler
  2. Clear everything inside the handler class
  3. Inherit from my Handler class
  4. DONE! Now you only need to add your methods.

Lets create a very simple example that receives a name and returns a string (see on the project).

   
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using App.Utilities.Web.Handlers;

namespace CodeProject.GenericHandler
{
 public class MyFirstHandler : BaseHandler
 {
  // I don't bother specifying the return type, it'll be serialized anyway
  public object GreetMe(string name) 
  {
   return string.Format("Hello {0}!", name);
  }
 }
}
 

To call this method through a URL use:

MyFirstHandler.ashx?method=GreetMe&name=AlexCode

AJAX Request using JQuery

If you want to use JQuery AJAX method you just need to know the object the handler is expecting to get.
On the data property of the $.ajax request you must pass something like:

{ method: 'The method you want to call', args: { the arguments to pass } }
Be aware that everything is case sensitive!
$.ajax({
 url: 'MyFirstHandler.ashx',
 type: 'GET',
 data: { method: 'GreetMe', args: { name: 'AlexCode'} },
 success: function (data) {
  alert(data);
 }
});

Writing a method that returns HTML

Like I said on my intention points above, I need to have some methods that return whatever I want like HTML, XML, images, files, etc...
The default behavior of the handler is to return JSON so, by method, we need to explicitly say that we want to handle things our way.
For that just use these lines anywhere within the method:

SkipContentTypeEvaluation = true; 
SkipDefaultSerialization = true;

// you can specify the response content type as follows
context.Response.ContentType = "text/html";
Lets see an example on how we could write a method on the handler that returns HTML:
public object GiveMeSomeHTML(string text)
{
 StringBuilder sb = new StringBuilder();
 sb.Append("<head><title>My Handler!</title></head>");
 sb.Append("<body>");
 sb.Append("
This is a HTML page returned from the Handler
");
 sb.Append("
The text passed was: " + text + "
");
 sb.Append("</body>");

 context.Response.ContentType = "text/html";
 SkipContentTypeEvaluation = true;
 SkipDefaultSerialization = true;

 return sb.ToString();
}

Optional Parameters and nullable types

All parameters in the methods are optional. If they're not passed their default value is assigned.
Also all parameters can be nullable. In this case the default value will be null

Please have a look at the attached code sample for more examples.

Points of Interest

I can say that this handler already saved me a good amount of development and maintenance hours.
Currently all my AJAX requests point to a method on an handler like this.

History 

  • v1.0 - The first wide open version 
  • This is a work in progress, I keep improving it regularly.

I have no doubt that you'll try to use this in scenarios I haven't predicted.
Please send me your requests and desires, I'll do my best to implement them.

Sunday, January 22, 2012

ASP.net Routing vs ScriptManager

Recently I had a problem with ScriptManager on a WebForms site where I was also using the ScriptManager.

Suddenly my ASP.net validators stopped working client-side and on Firebug I could read this error:

ASP.NET Ajax client-side framework failed to load.

Crap... what am I doing wrong here!?

It seems that Rounting messes with the .axd files script manager generates so we only need to tell the routing to ignore those:
routes.Ignore("{resource}.axd/{*pathInfo}");

Done!!

Thursday, November 10, 2011

SQL Server 2008 Transactions Usage Template

I must admit I don't use Transactions that much, but the fact is that most of my stored procedures are atomic, i.e. although they may have a lot of code, only one data changing operation (INSERT | UPDATE | DELETE) is done, so there's no need to wrap it on a transaction.

Because I don't use them much, its not always clear to me what's the "best way" of using a transaction. Sure we all know the basics but:

  • Is the transaction always closed?
  • Are we handling the error that caused the transaction to rollback?
  • Are we accurately reporting the error to the caller?

To be able to always answer YES to all these questions without thinking much about it, my friend Rui Inacio dove into Google and came up with a template that can be used as a start point of all your transaction scripts.
 BEGIN TRY
  BEGIN TRANSACTION
  
   -- ADD YOUR CODE HERE --
  
  IF @@TRANCOUNT > 0
  BEGIN
   COMMIT TRANSACTION;
  END
 END TRY
 BEGIN CATCH
  DECLARE @ErrorMessage VARCHAR(4000)
  
  SET @ErrorMessage = 'ErrorProcedure: ' + ISNULL(ERROR_PROCEDURE(), '') + ' Line: ' + CAST(ERROR_LINE() AS VARCHAR(10)) + ' Message: ' + ERROR_MESSAGE()
  
  IF @@TRANCOUNT > 0
  BEGIN
   ROLLBACK TRANSACTION;
  END
  
  RAISERROR (@ErrorMessage, 16, 1)  
 END CATCH

You may change the way you report the error inside the CATCH but for most cases this is what you need.

Sunday, October 30, 2011

Overriding FormsAuthentication for some URLs

Is this for you?

How many times do you need you're website to have both public and private pages?

How many times did you thought that creating virtual directories with specific web.config files was lame?

If you feel the pain and want it to go away, read on!
Also note that although I'll refer a lot to HttpHandlers on this post, everything here (except the route registration) is also true for common web pages.

Be sure to have a look at this

A few days ago I wrote about handling HttpHandlers with ASP.net routing.
I'll refer to those extension methods to register my test handler route, so have a look on that post before continuing.

Now what I need is a way to override the default FormsAuthentication configuration for a specific set of HttpHandlers.

Virtual Folder, web.config and the ASHX files

FormsAuthentication support this out-of-the-box by simply putting the resources with special security concerns on a separated folder with its own web.config file.

So if you want a virtual directory to allow access to anonymous users just add a web.config file with nothing but this in it:


 
  
   
  
 

This will work for any resource can can be accessed through an URL but this isn't always the case with HttpHandlers.

FormsAuthentication and HttpHandlers without ASHX file

Using the extension methods I wrote on the said previous post you can create an HttpHandler by simply creating a new class and implementing the IHttpHandler interface and point a route to it, just like this:
RouteTable.Routes.MapHttpHandlerRoute("Test", "Unsecured/Controllers/Test", new MyApplication.UnsecuredHandlers.MyUnsecuredHandler());
This means that, whenever you call ht**://mydomain/Unsecured/Controllers/Test the request will be routed to MyUnsecuredHandler instance, not to a physical uri location as usual.
Now have a look at the route. It begins with Unsecured right? Keep reading and you'll understand why.

But we're not there yet, what I really want is to say that some of my handlers allow anonymous requests, and for that I'll edit my website web.config and add the following:


 
  
   
    
   
  
   

Now its done!
Notice that on the location path I only have unsecured. This will grant request permissions to all routes that begin with unsecured!
This is great because now I don't have to bother about structuring the resources on virtual directories and possibly duplicating the code for different scenarios.
Whenever I need a Page or and HttpHandler to be available to anonymous users I just need to create a route to it that begins with unsecured.

If you don't like this approach (specially for pages where the url is visible for the users) you can always add as much location entries on the web.config as you like.

If you're not using Routing you can still specify a location to your resources putting the uri of the Page or HttpHandler on the path attribute: