What are you mad !! You can’t do it, how on earth are you going to suddenly be called again as an image and write binary data out.  

If you’ve read previous posts you will see that I have been writing a web part that gets SiteUsageData and displays it.  It uses some nasty COM+.  I got to thinking how on earth am I going to graph this dynamic data that changes per site?

HttpHandlers – for a bit more info on HttpHandlers see here on Scott Hanselman’s blog.

Now your up to speed on them, how can we use them with a part. 

First we have to spit out the IMG tag in your render section.

textWriter(“<img src=’_layouts/MyWebPartImage.ashx/’>”);

Of course that on its own does nothing, but note the url “_layouts”, not “/_layouts” this is very important as your part will run in the Site context of “/” if you do, instead of the current site.

Second you need to register this HttpHandler in web.config

<add verb=”GET” path=”MyWebPartImage.ashx” type=”Binaryjam.MyWebPartNs.MyWebPart, Binaryjam.MyWebPartNs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5**************d” />

Replace those details with your own namespace, typename, public key.  Ahh Did I say you need to GAC this part.  I haven’t experimented with not GACing this feel free to but to be sure GAC IT.

Third add the IHttpHAndler interface to your web part class

public class MyWebPart: WebPart, IHttpHandler

Nearly there now add your Interface methods, remember Scott’s article ? Here is a simple example of this:

public void ProcessRequest(HttpContext context)
{
    HttpResponse response=context.Response;
    HttpRequest request=context.Request;
    response.ContentType=”image/jpeg”

    Graphics g=null;
    System.Drawing.Image image=null;
    image=new Bitmap(Width,Height,PixelFormat.Format32bppArgb);
    g=Graphics.FromImage(image);
    g.FillRectangle(new SolidBrush
            (Color.White),0,0,image.Width,image.Height);
    g.DrawString(“YooHoo”,new Font(“Verdana”, 10.0f),
             new SolidBrush(Color.Black),0,0);
    image.Save(response.OutputStream,ImageFormat.Jpeg);

}

public bool IsReusable
{
  get
  {
    return true;
  }
}

These pieces of code give you the basics to dynamically generate an image from a web part.  Now because the webpart is being created again in the context of the site its running in in theory its Properties are populated, however you would need to check this.  For my use I only needed to now the site Context, I could then use the Sharepoint API and the site context

SPWeb thisWeb = SPControl.GetContextWeb(Context);

To get the data I need.  You could use the API to access list information in a site and graph that too.

And no I don’t have a full code example, my graphics code is too embarrassing.
🙂

 

Its here I might point out that doing this might be a really bad idea, lets face it we don’t know what’s happening behind the scenes, but lets have a guess.  You have already hit this page once to display the web part. To display the image the site is visited a second time, admittedly not the rendered page but the site all the same.  Now what could be happening here is that the Sharepoint httphandlers, because remember its not the aspx ones running, initialise loads of Sharepoint stuff.  Then you create a webpart, now either the Sharepoint context exists already of the webpart creates it, considering that on a page could be multiple web parts are they all creating contexts ? or calling a static to get it ?  Anything could be happening here.   On the other hand is it as bad as hosting an image held in a site list in a CWP part on your site ?  Probably very similar.

If there are any Sharepoint under-the-covers experts who know what’s happening, let me know please.

tags: sharepoint+webparts, sharepoint, GetUsageData, evil+voodoo+in+sharepoint

Advertisements