A classical musician turned programmer... or something

So, I totally dig pre-processor directives. Use them all the time. Do you? I hope so! It can make a Debug build ready for a Release build with the change of a dropdown in Visual Studio.

Here's an example to change the logPath string if you're building in Debug mode (or anything else). This could be very handy with programmatically creating a log4net config.

        string logPath;
#if DEBUG
        logPath = @"C:\csharptocsharp.com\log.txt";
#else
        logPath = @"Q:\sites\csharptocsharp.com\logs\log.txt";              
#endif

Anyway, if you're not using preprocessor directives in your code, then what are you waiting for?

Other References:
MSDN Preprocessor directives

Tags:

So in my first Log4Net Config post a weee time back, I talked about a hot way to configure your log4net settings using a composite, rolling logging model.

Here, I have that same log4net config, but done in code! It doesn't have the same flexibility of the web.config or an xml file if you're frequently changing values--since you'd have to push code for any changes--but it does make any logic easier.

It begs the usage of preprocessor directives for setting File [location], PatternLayout, or Threshold.

log4net.Appender.RollingFileAppender a = 
new log4net.Appender.RollingFileAppender();
a.Name = "RollingFileAppender";
a.File = @"c:\blah.com\log.txt";
a.AppendToFile = true;
a.RollingStyle = log4net.Appender.RollingFileAppender.RollingMode.Composite;
a.MaxSizeRollBackups = 14;
a.CountDirection = 1;
a.MaximumFileSize = "15000KB";
a.StaticLogFileName = true;
a.Layout = new log4net.Layout.PatternLayout(@"{%level}%date{MM/dd HH:mm:ss} - %message%newline");
a.ActivateOptions();
a.Threshold = log4net.Core.Level.Debug;
log4net.Config.BasicConfigurator.Configure(a);

(Thanks to my buddy J.A. for showing me this).

Enjoy!

kick it on DotNetKicks.com

Tags:

One of the things I learned at DevConnections 08 is the magic behind ASP.NET MVC, and how it actually works. Beside the UrlRouting (which you can do with HttpModule stuff), it's pretty easy and relies a lot on Activator.CreateInstance(). As seen in my post about creating a csv from list, you can read about it here.

The magic is...shhh...

To programmatically create the worker class based on the url.

magic mvc

Yeah, no-DUH you say. Well it took MS this long to come up with it for public consumption when MVC has been around for decades. Anyhooo.

NOTE: I'm more of an MVP guy, so this is geared toward using the MVP's Presenter rather than the MVC's Controller. They're similar patterns, 'cept MVP is a bit more decoupled (and deprecated...), so in my example below, you can replace 'Presenter' with 'Controller' if it makes you fuzzy, because really, that's where all the work gets done.

Here we go.

mvc is on fire!A request comes in for blah.com/hotguitars.aspx. Your UrlRouting can match the url up with the correct view [handler] and rewrite its path to that page handler. In this case, I'd most likely use the DefaultView since the page lives off of the root (/).

On PageLoad the presenter factory is going to take the url and try to figure out which class to instantiate [return] to make the contents for the view. Each of the classes returned implement Presenter, which implements IPresenter... so I can code to the interface, which is nicer. (Notice the interfaces. I'm an interface kinda dude, because they're hot when it comes to testing).

Ok, so here's the little POC for you.

    // Presenter class implements this because all *Presenter
    // classes need to have a DoIt() method
    public interface IPresenter
    {
        void DoIt();
    }
 
    public class Presenter : IPresenter
    {
        public Presenter() { }
        public virtual void DoIt() { }
    }
    public class PresenterFactory
    { 
        //return the url minus hyphens
        private static string GetPresenterName(Regex re, string url)
        {
            return re.Match(url).Groups[1].Value.Replace("-","");
        }
        //get the url
        private static Regex rePage = 
new Regex(@"/(.+?)\.aspx", RegexOptions.IgnoreCase);

This is the sexiness....

        public static Presenter GetPresenter(Page page)
        {
            // this is blah.com/hotguitars.aspx
            string rewrittenUrl = page.Request.RawUrl;
            string presenterName = GetPresenterName(rePage, rewrittenUrl);    
            //here is where you make sure you have a HotGuitarsPresenter
            string className = "BunchaJunk.Presenters." + presenterName + "Presenter";
            // get the type, throw error, and ignore case
            Type type = Type.GetType(className, true, true);
            // create an instance of the correct Presenter/Controller and return it
            return (Presenter)Activator.CreateInstance(type, new object[] { page });
        }
    }
    public interface IBasicPage
    {
        string HtmlTitle { get; set; }
        string HtmlMetaKeywords { get; set; }
        string HtmlMetaDescription { get; set; }
        string MainContent { get; set; }
    }
    public class HotGuitarsPresenter : Presenter
    {
        private IBasicPage ibp;
        public HotGuitarsPresenter(IBasicPage ibp)
        {
            this.ibp = ibp;
        }
        public override void DoIt()
        {
            ibp.HtmlMetaDescription = "Hot stuff!";
            ibp.HtmlMetaKeywords = "jackson, paul reed smith";
            ibp.HtmlTitle = "Here are the hottest guitars at csharptocsharp!";
            ibp.MainContent = "paul reed smith, jackson, gibson";
        }
    }
 
 

Here is how it is called from aspx code behind
    public partial class _Default : Page, IBasicPage
    {  
        protected void Page_Load(object sender, EventArgs e)
        {
            //coding to the interface is the cat's meoooooooooooow
            IPresenter p = PresenterFactory.GetPresenter(this);
            p.DoIt();
        }
        public string HtmlTitle { get; set; }
        public string HtmlMetaKeywords{get;set;}
        public string HtmlMetaDescription { get; set; }
        public string MainContent{get;set;}
    }

Here is how it's used in the aspx
<title><%=HtmlTitle%></title>

That is all!

kick it on DotNetKicks.com

Tags:

Since I'm a .NET dude, you might find this post a wee bit odd, because, I should worship MS, right?... well I don't :), so in any case...

Hokay. So...

I recently made the jump to be *that* much closer to an all-unix setup [at home]. I've had my macbook now for about a year, and it's totally dope, I love it. In fact, I just got 4 gigs of ram for $35 beans from newegg.com.

vmware rocks! The reason why I got that hot upgrade was because of the VMWare Fusion trial I had just decided to checkout.

Now, I'm very familiar with VMWare and its hotness. I used VMWare server on Ubuntu for some years as a way to tinker with a bunch of Unix and Linux OSes.

After DLing and messing around with it out for some time, (I used it at DevConnections Vegas 08) I knew that hog had to be mine! After turning my boot camped-Vista-partition into a virtual machine I soon realized that it was worth every penny. Twas always such a pain to have to reboot just to tinker with some idea in Visual Studio for five minutes. Just need to find a replacement for Texter (Spotlight is a great replacement for Launchy).

ubuntu rocks! On that note.... a couple weeks ago I setup my older ASUS Pundit-R barebones machine to run the latest version of Ubuntu (8.10 as of today)... and it flies. With a P4 chip, 1 gig of ram, and some low-end NVidia card, it's totally acceptable for doing most webby stuff. I haven't rally monkeyed with Ubuntu since Dapper/Edgy, but I can say it has come a long way since I started w/Hoary.

You have a site, a blog, a something. And you're using WordPress. Ok, that's cool. It's free and nifty, but you HAVE to keep it up-to-date. Nutty hackers and their b0ts are all over the net, HOPING people like YOU don't upgrade your site(s).

So after that warning, you want to upgrade to the latest version of WordPress. You upload your junk and go to your site and BOOM! Blank screen.

  • Make sure your wp-config.php file has no white space(s) after the closing ?> mark.

Ok fixed that...

Next you try to login... and WHAMMMMMM! You're bounced back to the login screen. No errors, no messages in the UI... nuttin.

  • Make sure that the wp-content/plugins folder has been renamed to something else, like wp-content/plugins_butt

Once you have logged in, rename that folder back to 'plugins' (you can also turn off the active plugins in the db, but it requires that you save its contents)

Those things helped me, I hope it helps you too!

Tags:

Here's a method I've been working on for a recent project. It will make a csv file from a generic list of type <T>.

There are methods out there for doing similar with DataTables... I like working with generic lists myself.

It does what it needs to do, but I'm not terribly happy with it yet, especially with a class with multiple constructors (all properties are used in csv).

(sorry about the formatting... gotta find a c# code format plugin...)
UPDATE: http://drupal.org/project/geshifilter

/// <summary>
/// Creates the CSV from a generic list.
/// </summary>;
/// <typeparam name="T"></typeparam>;
/// <param name="list">The list.</param>;
/// <param name="csvNameWithExt">Name of CSV (w/ path) w/ file ext.</param>;
        public static void CreateCSVFromGenericList<T>(List<T> list, string csvNameWithExt)
        {
            if (list == null || list.Count == 0) return;
 
                //get type from 0th member
                Type t = list[0].GetType();
                string newLine = Environment.NewLine;
 
                using (var sw = new StreamWriter(csvNameWithExt))
                {
                    //make a new instance of the class name we figured out to get its props
                    object o = Activator.CreateInstance(t);
                    //gets all properties
                    PropertyInfo[] props = o.GetType().GetProperties();
 
                    //foreach of the properties in class above, write out properties
                    //this is the header row
                    foreach (PropertyInfo pi in props)
                    {
                        sw.Write(pi.Name.ToUpper() + ",");
                    }
                    sw.Write(newLine);
 
                    //this acts as datarow
                    foreach (T item in list)
                    {
                        //this acts as datacolumn
                        foreach (PropertyInfo pi in props)
                        {
		  //this is the row+col intersection (the value)
                            string whatToWrite =
                                Convert.ToString(item.GetType()
                                                     .GetProperty(pi.Name)
                                                     .GetValue(item, null))
                                    .Replace(',', ' ') + ',';
 
                            sw.Write(whatToWrite);
 
                        }
                        sw.Write(newLine);
                    }
                }  
        }

So there you have it... C# generic list to csv file!

Couple things to change/ideas...

  • take in a delimiter (string) (comma is standard now, but it could be anything, use that as .Replace() of value as well)
  • remove last comma in header row.
  • fix this line 'Type t = list[0].GetType();' (I don't like it!)

Any suggestions are welcome!

kick it on DotNetKicks.com

Tags:

So, are YOU going to DevConnections 2008 at Mandalay Bay? (See pathetic poll to the right).

This is my second time to vegas in <6 months and this time, I'm hoping to check out Alex, Picasso, and Ed Roman Guitars.

I'm going with a bunch of guys from w0rk. Should be fun, though I've read some not-so-good reviews of our hotel... (Can't be the Venetian every time...)

kick it on DotNetKicks.com

When rockin' out the NAnt build process, I thought it was necessary to have a folder that accurately states the build version/number of the enclosed assembly. I'm sure I could have done this w/code, but eff that... I wanted to have a bit of fun, trying the <code> tags from within the build file itself.

Given a path to an assembly, ${build.dir} will echo something like:

build-38372-383748--2010-10-10

I've found it handy for:

  • Doing something at build time wo/another console app.
  • Keeping track of builds (duh)
  • Impressing the ladies.

(Sorry about the whacked formatting!)

<property name="build.dir" value="build" />
<property name="pathToAssembly" value="C:\your\moms\house\nice.dll" />
<target name="getbuildnum">
<script language="C#" prefix="method" >
<imports>
<import namespace="System.Reflection" />
</imports>
<code>
<![CDATA[
[Function("get-version-from-assembly")]
public string GetVersionFromAssembly(string assPath) {
Assembly ass = Assembly.LoadFrom(assPath);
return "build-"+ass.GetName().Version.ToString()
.Replace(".","-")+"--"+DateTime.Now.ToString("yyyy-MM-dd");
}
]]>
</code>
</script>
<property name='build.dir' value='${method::get-version-from-assembly(pathToAssembly)}' />
<echo message='${build.dir}' />
</target>

kick it on DotNetKicks.com

Tags:

So... who's going to OWASP NYC AppSec 2008 Conference?? It's coming up very soon...aka NEXT WEEK!

I'm looking forward to the following talks...

· Get Rich or Die Trying - Making Money on The Web, The Black Hat Way (HOT!)
· Next Generation Cross Site Scripting Worms
· Bypassing web application/service security controls using Encoding, Transcoding, Filter Evasion, and other Canonicalization Attacks

kick it on DotNetKicks.com

So just a quickie post. NAnt doesn't play very nicely with the MSBuild task especially with .NET 3.5, so I thought I'd post a snippet from a build file that I think I finally like (and works!).

* project has been renamed [to csharptocsharp] to protect the innocent lame!

<property name="msbuild" value="C:/WINDOWS/Microsoft.NET/Framework/v3.5/MSBuild.exe" />
<target name="compile" description="Compiles using the AutomatedDebug Configuration">
<!-- NAnt doesn't like this part! :( -->
<!--<msbuild project="src\csharptocsharp.com.sln">
<property name="Configuration" value="AutomatedDebug" />
</msbuild>-->
<!-- So we just use an exec task instead!-->
<exec program="${msbuild}">
<arg value="src\csharptocsharp.com.sln" />
<arg value="/v:n" />
<arg value="/p:Configuration=AutomatedDebug" />
<arg value="/p:WarningLevel=0" />
</exec>
</target>

kick it on DotNetKicks.com

Tags:

About Brian


profile for bluevoodoo1 on Stack Exchange, a network of free, community-driven Q&A sites

Brian Canzanella brings you nifty tips and tricks for most things .NET. read more...

Readers / Stuff