Tuesday, November 24, 2009

Find next specific day of week

It’s not cutting edge but it’s something I forget about every 6 months and have to look up or figure out again.  So here it is.  Also I’m not convinced that it is the best way so if anyone knows a better one feel free to let me know.

ok I have written a battery of tests changing both days around and this is the real deal.

public DateTime getNextSpecificDay(DateTime d1, DayOfWeek day)
        {
            var diff = day - d1.DayOfWeek;
            if(diff <= 0)
            {
                diff = diff + 7;
            }
            return d1.AddDays(diff);
        }

 

this will find the next sunday.  if you pass in a sunday it will find the next one not the current one.

Wednesday, September 9, 2009

FluentNHibernate 'urn:nhibernate-mapping-2.2' has invalid child element

Just a quick post for anyone who may be suffering with this error.  If you get an error that looks like this,

NHibernate.MappingException: (XmlDocument)(3,6): XML validation error: The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'property' in namespace 'urn:nhibernate-mapping-2.2'. List of possible elements expected: 'meta, subselect, cache, synchronize, comment, tuplizer, id, composite-id' in namespace 'urn:nhibernate-mapping-2.2'. --->

then there could be two causes for this depending on how you are configuring FNH.

If you are using FluentMapping which is to say you are explicitly mapping each class then you must map the ID Column differently then the rest of them.  I just upgraded from NH 1. something and it’s concurrent version of FNH and I had the following in my origional mapping  UseIdentityForKey(x=>x.Id, “id”). After upgrading I saw that the UseIdentityForKey no longer existed and having read that there is a convention for discovering the Id column I figured that I’d just map it the same as the other Map(x=>x.Id).  Well that was kind of silly and produced the above error.  So I changed it Id(x=>x.Id) and all was good.

The second case may be a bit more insidious.  If you are using Automapping, FNH will indeed discover your id columns for you.  Yay!  However, only if you have named then Id.  That’s capital I lower case d. If you have it all caps ( or for some reason all lower ) like ID then you will get the above error.

I posted this cuz I didn’t find any other posts on this error.  Which could mean that I’m sooo brilliant that no one has even thought of making the mistakes that I make.  There’s another interpretation which I’m sure you’ve already come up will so I will leave it un uttered.

Monday, May 11, 2009

Poor man’s MVC

Hi, I’m considering using a what I call a poor man’s MVC for a project at work.  Actually the more I think about it, the more I think I’m going to use Fubu, so I figured I’d blog this out before I forgot about it.

The idea is that if you are in a medieval torture chamber and are being forced to use WebForms to write an app you could do the following.

Let’s say you have a page with the following event’s on it. 

Load()

ApplyThumbscrew()

ListenToScreams()

the Load you surely recognize as one of the god awful page life cycle events. ApplyThumScrew() and ListenToScreams() are obviously ways that a user can enjoy ones self.  They click a button and said event happens.

For each page you will have a corresponding controller ( or presenter if you will.  I’d rather not. ).  The Controller will have corresponding methods to the Page.  It will also have a specific input and output.  The sig will look something like this.

public ApplyThumbscrewOutputModel ApplyThumbscrew(ApplyThumbscrewInputModel input) { }

the input and output models are just DTOs. The input model has everything form the page that you need to do you stuff.  the output model has everything that the page needs from the server to do it’s stuff.

so the ApplyThumbScrew() event would look like this

but wait first let me tell you that you should be using Dependency Injection for the controller ( and later the torture object ) and a proper IOC Container.  But that is beyond the scope of this blog and would require that I write more code in this horrible editor.

protected void ApplyThumbscrew(blah blah blah)

{

var input new ApplyThumbScrew{

SizeOfThumb = txtSizeOfThumb.Text,          

HowBadIsPerson = txtHowBad.Text,                          

HowSickAreYou = txtHowSick.Text,           

                                           };

var controller = new TortureController();

var output = controller.ApplyThumbScrew(input);

// then do something with return. my imagination is waning

txtPersonsThumb.text = output.PainExpression;

txtUsersEnjoyment.text = output.Enjoyment;

}

Then the corresponding Controller action would look like so

public ApplyThumbscrewOutputModel ApplyThumbscrew(ApplyThumbscrewInputModel input)

{

var torture = new InterigationTechnique();

var fun = torture.DoTheScrew(input.SizeOfThumb,input.HowBadIsPerson,input.HowSickAreYou);

return new ApplyThumbscrewOutputModel{

PainExpression=fun.Pain;

Enjoyment = fun.Enjoyment;

                                                        };

}

 

So you get the idea.  coding like this sucks and the formatting is all fubar so no more code.

But the idea is that now you have the “codebehind” doing nothing but view related stuff.  I harvests information gives it to a more responsible agent then receives some goo to spread back on the view.  In so doing you have completely severed the nasty httpcontext and Request object and all that untestable shite from the business logic.  Rendering the business code, yep you guessed it, TESTABLE!  yay.  furthermore, if you ever are released from the dungeon, you will have code that you can then hook into any view mechanism you want.  Fubu, Asp.Net, some other shite.

I don’t understand what is going on with the formatting.  this is bullocks.  Anyway, sorry that this is kind of superficial but really you should be using a proper MVC framework anyway, not this webforms crap.

“I am not a crook!” Impersonation

I was recently tasked with creating little web page that monitors the backup files on our servers.  Obviously I’m going to need to use particular credentials since the server hard drives are locked down.

So I set about creating a little impersonation object.  I read a number of blogs and they all seemed to be showing similar systems and then I came across a tutorial from Microsoft.  Now normally I back page as quick as possible when I end up on one of there documentation pages because they are invariably Byzantine, but this time I figured I’d give it a shot.  Well they were saying oh you don’t have to do it this ways ( the way most blogs were showing it ) if you do this and that. So I said aha!  A short cut.  Well after many errors and exceptions it occurred to me to search the code repository on my machine and see if there was anything already there.  Brilliance! Low and behold!  log4net needs to access your file system in order to write it’s logs.  And guess what?  They are doing it the same way everyone else ( except microsoft ) is doing it.  So I kinda stripped out some of the stuff they had that was specific to their use and came up with the following.

public class Impersonator
    {
        private readonly string _userName;
        private readonly string _domainName;
        private readonly string _password;
        private IntPtr _tokenHandle;
        private WindowsIdentity _identity;
        [DllImport(&quot;advapi32.dll&quot;, SetLastError = true)]
        private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

        [DllImport(&quot;kernel32.dll&quot;, CharSet = CharSet.Auto)]
        private extern static bool CloseHandle(IntPtr handle);

        [DllImport(&quot;advapi32.dll&quot;, CharSet = CharSet.Auto, SetLastError = true)]
        private extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

        public Impersonator(string userName, string password, string domainName)
        {
            _userName = userName;
            _domainName = domainName;
            _password = password;
            LogonUser();
        }

        private void LogonUser()
        {
            const int LOGON32_PROVIDER_DEFAULT = 0;
            //This parameter causes LogonUser to create a primary token.
            const int LOGON32_LOGON_INTERACTIVE = 2;

            // Call LogonUser to obtain a handle to an access token.
            _tokenHandle = IntPtr.Zero;
            if (!LogonUser(_userName, _domainName, _password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _tokenHandle))
            {
                //log4net error handler.  I'm using log4net so I figured I'd take advantage
                //NativeError error = NativeError.GetLastError();
                throw new Exception(&quot;Failed to LogonUser [&quot; + _userName + &quot;] in Domain [&quot; + _domainName + &quot;].&quot;); // Error: &quot; + error.ToString());
            }

            const int SecurityImpersonation = 2;
            IntPtr dupeTokenHandle = IntPtr.Zero;
            if (!DuplicateToken(_tokenHandle, SecurityImpersonation, ref dupeTokenHandle))
            {
                //log4net error handler.  I'm using log4net so I figured I'd take advantage
                //NativeError error = NativeError.GetLastError();
                if (_tokenHandle != IntPtr.Zero)
                {
                    CloseHandle(_tokenHandle);
                }
                throw new Exception(&quot;Failed to DuplicateToken after LogonUser.&quot;); // Error: &quot; + error.ToString());
            }

            _identity = new WindowsIdentity(dupeTokenHandle);

            // Free the tokens.
            if (dupeTokenHandle != IntPtr.Zero)
            {
                CloseHandle(dupeTokenHandle);
            }
            if (_tokenHandle != IntPtr.Zero)
            {
                CloseHandle(_tokenHandle);
            }
        }

        public IDisposable Impersonate()
        {
            return _identity != null ? new DisposableImpersonationContext(_identity.Impersonate()) : null;
        }

        private sealed class DisposableImpersonationContext : IDisposable
        {
            private readonly WindowsImpersonationContext m_impersonationContext;
            public DisposableImpersonationContext(WindowsImpersonationContext impersonationContext)
            {
                m_impersonationContext = impersonationContext;
            }
            public void Dispose()
            {
                m_impersonationContext.Undo();
            }
        }
    }

 

One would then use it like so

 

  var impersonator = new Impersonator(LoginName, Password, Domain);
            using(impersonator.Impersonate())
            {
                if (!Directory.Exists(DirectoryPath)) return;
                var dir = new DirectoryInfo(DirectoryPath);
             }

Sorry about the code formatting I have to learn how to do this.

After calling the impersonator.Impersonate() method( provided your credentials are proper ) you will be operating under those credentials.  In example I’m accessing a directory on a server that I specified in code else where.

So this is the quick and dirty plus some of my bitching.  Here is a nice post by Rick Strahl who goes into more detail.

Saturday, May 9, 2009

My Current Project

So I’ve been tasked with re writing the booking engine ( basically the check out process for reserving a room at a bed and breakfast ) at work.  The current system was written five years ago and with what seems like a conscious effort towards obscurity, bloat, and inextricability.  The current system was some time after it’s creation cloned and the clone was used to access product listed on a listed on a winforms product.  It’s a little complicated.  

The two use different databases: SqlServer and Oracle, and have diverged considerably over time. There is, as one might imagine, an awful lot of logic in the code behind, the middle tier is composed of almost all static methods and the data layer is a combination of a number of messy home rolled ado wrappers using in line sql.

I’m to combine the two processes into one as well as add considerable new functionality and checkout logic.  I will create a seam where the property ( a bed and breakfast ) has been chosen and the book it button is clicked, and replace everything through where the reservation conformation screen shows.  Sadly I will most likely have to interface with some legacy objects such as the credit card processing object and who knows what else.  And of course I will be using the legacy database schema.

This promises to be a rather exciting project for me.  At the very least I will be able to create a proper business process, in a middle tier, using nice clean SOLID principles.  I will also be able to interface with webforms in my chosen manner ( see next post, if I ever write it ) and hopefully I will be ale to use NHibernate for data access, at least for some of it.  I will be slipping structuremap into the project.  If they don’t like it I can always back it out and use a poor mans dependency injection, but the hope is that they will think DI and StructureMap in particular are very cool.  I believe and or hope that this will sow the seeds of future patterns ( i.e. using NHibernate, SOLID, StructureMap etc ) for future projects.  Hopefully it wont also cost me my job.  You know how people love change.

Sunday, February 1, 2009

T4 Templates, T4 Toolbox, and VisualSVN

Hello, I spent some time messing with T4 this week. It seemed that T4 could be pretty powerful once you put in the considerable time and effort necessary to figure out how it works. Having said that It's not very intuitive. I guess that the basic template is pretty easy to do. It ends up looking like an old asp page, alot of the code that should be rendered then blocks of escaped code for some c# that can creates the dynamic info you need. This will then create a file as a subfile of your template every time the template is saved. So if your template is called MyStupidTempate.tt then when you save it you will see in solution explorer a plus sign next to the file. When expanded you will see MyStupidTempate.cs or .sql or .wtfe.
In short order you realize that you'll need T4 toolbox to do anything much more advanced than that. T4 Toolbox is an open source set of tools that allows you to do things such as create multiple output files for a template, use multiple templates to create the output and several other nifty things.
Here's the bitch. T4 Toolbox has an incompatability with VisualSVN. It's one or the other. In my office it's VisualSVN because it is an intragal part of our productivity. I did conciderable due dilligence on the subject and found that Kyle Baley had been down the same road before. I email Kyle and was informed that the issue hadn't been resolved, that is was on the T4 Toolbox side and in fact seems not to really even be acknowledged by the T4 Template guys. This, for the time being has landed T4 and it's nifty Toolbox in the crapper for me. I subsquently just wrote some C# code which did my codegen for me for this particular job and went on my merry way.
All told I have to say that my experience with CodeSmith in the past was much more fruitful. Pretty inutitve stuff and a very helpful IDE with intellisence and other perks. It's not free which is a drawback I guess but it's not very expensive either.
I don't do a whole lot of codegen so this isn't too big a deal for me but if I did or when I do I will definitly look back into CodeSmith and see if it has the capabilities I would need to integrate it into our application, build process, etc.

Thursday, January 22, 2009

I'm a little lizard trapped in a man's skin

Hello.
Today is truly a glorious day. Yes today, some several weeks of struggle and strife have come to an end. After terrific hardship suffered at the hands of a terrible depot I can now say that I xxx xxxx have persevered. My computer is now in a state not unlike it was in at the beginning of these troubled times. I may be older. But I am also definitely wiser. Having had to rub bellies with the darkest of vermin I have learned much about thier habbits and idiosycracies. Today friends and loved ones, today my computer works again!

I will give detail about my trial and tribulations when I have recovered from the effort of perseverance.

Tuesday, January 13, 2009

Freakin IIS Start Website

Ok, so here we go a real post!
I've been using the visual studio development server to run an app that I'm building using FubuMVC. For some reason I was getting some rather strange behavior and I remember that Chad had said that the vs dev server is a FPOS and that I should use IIS so I switched over only to receive this retarded message.

Unable to start debugging on the web server. The server does not support debugging of ASP.NET or ATL Server applications. Click Help for more information on how to enable debugging. You may also want to refer to the ASP.NET and ATL Server debugging

well after searching high and low and trying all sorts of BS I started digging in IIS (7) and found that the Default Web Site was not started and in fact bloody well wouldn't start. So back to the freakin google and I find that perhaps my port 80 is being used and that if go to a command prompt and type NETSTAT -ano I could see a list of all the ports being used. Sure enough port 80 is being used by a PID 1928. To see if that is truly the problem, I change the bindings in IIS7 (hyperlink on the right side of then now extremly cluttered iis screen) from port 80 to port 8080 and indeed that works.

So what the hell is PID 1928 well I don't know so I go to Task Manager and on the process tab I select view -> select columns and check PID. That ought to do it I think, but pid 1928 doesn't show up. Well it's back to the interweb for some more of the google and I find out about a program called Process Explorer This is essentially Task Manager on steroids and, well, frankly I like steroids. This thing is pretty cool and has way more colors that TM and it actually shows me my blasted PID. It turns out that I have Apache server running for some freakin reason. I kill the process and pow the Default Website starts right up!

So there you have it I have posted on something that might be helpful to someone if they can get through all the prose to the meat.