Archive

Archive for the ‘.Net’ Category

Recursive generic extensionmethods are fun! (Recursive FindControl)

November 12th, 2008 No comments

Just thought I should share a little piece of code with you this evening. It’s a little extension method (i.e it requires .Net 3.5) that extends Control and helps you find all instances of a certain controltype under the Control on which you invoke the method. Just put the following code in an assembly (or a .cs-file in App_Code).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;

/// <summary>
/// Holderclass for extension methods
/// </summary>
public static class ExtensionMethods
{
    /// <summary>
    /// Recursively searchs for all instances of a specified control type.
    /// </summary>
    /// <typeparam name="T">The type of control to search for.</typeparam>
    /// <param name="control">The control to search from.</param>
    /// <returns>A List<> with the found controls.</returns>
    public static List<T> FindControls<T>(this Control control) where T : Control
    {
        List<T> myList = new List<t>();
        FindControls</t><t>(control, ref myList);
        return myList;
    }

    private static void FindControls<T>(Control control, ref List<T> controlList) where T : Control
    {
        for (int i = 0; i < control.Controls.Count; i++)
        {
            Control currentControl = control.Controls[i];
            if (currentControl is T)
            {
                T typedControl = control.Controls[i] as T;
                controlList.Add(typedControl);
            }

            FindControls<T>(currentControl, ref controlList);
        }

    }
}

To call it you just invoke FindControls<Control>() on any object that derives from Control (i.e. Page, Label, Calendar, the list can go on forever), see the sample below. Hope you find some use for it!

List<HtmlMeta> meta = Page.FindControls<HtmlMeta>();

CrazyBeavers YouTube Downloader

April 19th, 2008 No comments

It’s been a while now since there was a new release from CrazyBeaver Software so I thought I should make some fuzz about it and talk about it here as well.

A few weeks ago a friend of mine asked if I knew any way to save a video from YouTube onto his harddrive so he could use it in his school presentation. A quick search on google turned up few services that could download the .flv for you which was pretty neat though not enough since it would require that the schools computers could play .flv, which they can’t. My idea then was to make a simple wrapper for FFmpeg (a great open-source tool for recording and converting audio and video streams) and let him use that for conversion. The goal at this time was to make it easy for him to do this without my help in the future and maybe to let my other classmates do it as well. It worked out pretty well in the end and I now have a really neat C# wrapper for FFmpeg.exe which I hope to release some day for everyone to use. It was however not really satisfied with this, my application only did half the job, and the easy part was what was missing. I went looking around the net a bit for solutions on how to download the .flv-files from YouTube and found several ways which had their advantages and drawbacks. In the end, I borrowed a few ideas from most of them and got my own working solution for getting the .flv-files.

CrazyBeavers YouTube Downloader 1.01

The result of this was the brand new CrazyBeavers YouTube Downloader which was released yesterday as version 1.0 and earlier today as 1.01 (just love the early bugs, so simple, so devastating). I’ve seen another program out there that does the same as mine but seeing the page I found it on i didn’t really want to download and run that .exe so hopefully this will be of use to more then just my class now.

With this release I also returned to NSIS (NullSoft Install System) for the installation which works a ton better then the Visual Studio setup projects I’ve used for BeaverSFV. I’ve scripted it to check for .Net 2.0 and if not it will download and install it. It also checks if the system is x86 or x64 to decide which package to get. Hopefully I’ll get around to discuss that one some day as well since it turned out really great. But until then, enjoy my new application!

Categories: .Net, Beaver, c# Tags:

Uploading multiple files and form fields in .Net

January 23rd, 2008 No comments

Recently while building a small application for a friend of mine I came across a part where I needed something that I just couldn’t find in the .Net framework. I needed to upload two files (and specify their fieldnames) and a few form fields to a webpage. I thought this would be easy just using the provided WebClient class but after looking closer at it I found that it didn’t really offer anything of what I needed. Trying not to feel let down by this I started to write my own extended version of WebClient with a few new tricks that the old one couldn’t do.

I tried to keep it as simple as possible so instead of writing new classes to hold form and file data I used two Dictionary<string, string> to pass the values. The Key is the fieldname and the Value the value or the path to the file. An example of uploading a few files and adding a few fields to that could look like this:

Dictionary<string, string> FormFiles = new Dictionary<string, string>();

FormFiles.Add("mypet", "C:\\cat.jpg");
FormFiles.Add("me", "C:\\myself.jpg");

Dictionary<string, string> FormFields = new Dictionary<string, string>();

FormFields.Add("age", "22");
FormFields.Add("location", "Sweden");

WebClientEx WC = new WebClientEx();

try
{
    WC.UploadData("http://www.myserver.com/upload.aspx", FormFiles, FormFields);
}
catch(WebException E)
{
    System.Console.WriteLine("Upload failed with HTTP-Code" + ((HttpWebResponse)E.Response).StatusCode.ToString());
    System.Console.ReadKey();
    return;
}

It doesn’t look that hard does it? It’s perfect to use if you need to “submit” a form on a webpage from your c# application or just need to send several files to a webserver in the same request. Below is the complete code for WebClientEx displayed. You may use it for anything you want as long as you don’t claim it as your own. If you use it in a project of yours then please write a comment or send me an email about it!

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using CrazyBeavers.Utils;

namespace CrazyBeavers.Net
{
    /// <summary>
    /// Provides common methods for sending data to and receiving data from a resource identified by a URI. This version comes with extended support for uploading files and formfields.
    /// </summary>
    public class WebClientEx : WebClient
    {
        public byte[] UploadData(string Address, Dictionary<string, string> Files, Dictionary<string, string> Fields)
        {
            string Boundary = "----------" + DateTime.Now.Ticks.ToString("x");
            byte[] BoundaryEnd = Encoding.ASCII.GetBytes("\r\n--" + Boundary + "--");

            MemoryStream MS = new MemoryStream();
            byte[] Buffer;

            foreach (KeyValuePair<string, string> Field in Fields)
            {
                StringBuilder Header = new StringBuilder();
                Header.Append("\r\n");
                Header.Append("--");
                Header.Append(Boundary);
                Header.Append("\r\n");
                Header.Append("Content-Disposition: form-data; name=\"");
                Header.Append(Field.Key);
                Header.Append("\"");
                Header.Append("\r\n");
                Header.Append("\r\n");
                Header.Append(Field.Value);

                byte[] PostHeaderBytes = Encoding.UTF8.GetBytes(Header.ToString());

                MS.Write(PostHeaderBytes, 0, PostHeaderBytes.Length);
            }

            foreach (KeyValuePair<string, string> File in Files)
            {
                StringBuilder Header = new StringBuilder();
                Header.Append("\r\n");
                Header.Append("--");
                Header.Append(Boundary);
                Header.Append("\r\n");
                Header.Append("Content-Disposition: form-data; name=\"");
                Header.Append(File.Key);
                Header.Append("\"; filename=\"");
                Header.Append(Path.GetFileName(File.Value));
                Header.Append("\"");
                Header.Append("\r\n");
                Header.Append("Content-Type: ");
                Header.Append(MimeHelper.GetMimeTypeForExtension(Path.GetExtension(File.Value)));
                Header.Append("\r\n");
                Header.Append("\r\n");

                byte[] PostHeaderBytes = Encoding.UTF8.GetBytes(Header.ToString());

                FileStream FS = new FileStream(File.Value, FileMode.Open, FileAccess.Read);

                MS.Write(PostHeaderBytes, 0, PostHeaderBytes.Length);

                Buffer = new Byte[checked((UInt32)Math.Min(4096, (Int32)FS.Length))];
                Int32 BytesRead = 0;
                while ((BytesRead = FS.Read(Buffer, 0, Buffer.Length)) != 0)
                    MS.Write(Buffer, 0, BytesRead);

                FS.Close();
            }

            MS.Write(BoundaryEnd, 0, BoundaryEnd.Length);
            MS.Position = 0;

            if (this.Headers["Content-Type"] != null)
                this.Headers.Remove("Content-Type");

            this.Headers.Add("Content-Type", "multipart/form-data; boundary=" + Boundary);

            Buffer = new byte[MS.Length];
            MS.Read(Buffer, 0, (Int32)MS.Length);

            return this.UploadData(Address, "POST", Buffer);
        }
    }
}

I won’t go in explaining line of this code as I’ve done in a few other samples. The code isn’t that hard to understand if you have moved beyond the “beginner stage” of coding. The thing worth mentioning is the part with MimeHelper.GetMimeTypeForExtension() which is a small function I wrote which checks the registry for any available mimetype for a given extension. I’ve included that code below aswell since it’s needed for WebClientEx.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.Win32;

namespace CrazyBeavers.Utils
{
    public static class MimeHelper
    {
        public static string GetMimeTypeForExtension(string FileExt)
        {
            if (!FileExt.StartsWith("."))
                FileExt = "." + FileExt;

            string Mime = "application/octet-stream";

            RegistryKey Classes = Registry.ClassesRoot;

            RegistryKey FileKey = Classes.OpenSubKey(FileExt);
            if (FileKey != null)
            {
                Mime = (string)FileKey.GetValue("Content Type", "application/octet-stream");
                FileKey.Close();
            }
            Classes.Close();
            return Mime;
        }
    }
}

Enjoy!

DynDnsLib and AkismetLib

July 15th, 2007 No comments

It’s been quiet around here lately. I moved to a new apartment a bit over a month ago now and won’t get an internet connection for at least another month it seems so things are going a bit slowly on the development front. I’ve managed to put together a few things though which might be of help to some.

First of all is a .Net library (and client) for working with DynDns services named DynDnsLib (and CrazyBeaversDnsUpdater for the client application) for people who want to add support for DynDns services to their applications. More information (and sourcecode via SVN) can be found at the link below.

http://beaverdnsupdater.devjavu.com/

Second up is an implementation of the Akismet (spam detecting service that WordPress and a few others use) API for .Net 2.0. It is a quite basic implementation that could be extended a bit more if someone wants to but it should be working fairly well as it is. More info (not much) and source at the link below.

http://akismetlib.devjavu.com/

None of these projects are in their final version, but both works fairly well at least. If anyone want to contribute to any of these projects then send me an email to karl.sjogren@gmail.com and tell me what you want to implement/change and I’ll consider giving you write access to the SVN repository.

When thinking about it, checking out source from an SVN repository might be a bit tricky unless you know what you are doing, maybe I should put together an article for that aswell some day if people seem to want it.

Categories: .Net, Beaver, Misc Tags: