Saturday, May 12, 2012

Copy specific object properties using reflection and inferface

Building view models for use within your MVC solution is great to combine objects for a strongly typed view. And I have been all about them. I just encountered a situation where I needed to update values for specific models contained within the view model. Getting the view model back from the view was the easy part thanks to MVC.

        [Authorize]
        public ActionResult Index()
        {
            var context = new Context();
            var repo = new UserRepository(context);

            var user = repo.GetUserByEmail(User.Identity.Name);

            var account = new Account { User = user };

            return View(account);
        }

In a perfect world I would have loved to just have done this

        [Authorize]
        [HttpPost]
        public ActionResult Index(Account account)
        {
            UpdateModel(account.User);
            repo.Save();

            return RedirectToAction("Index");
        }

This immediately didn't told me it wouldn't work. Update what model? and in what context??? The solution I am making rebuilds the context each get/post. Is there a better way, probably, but this is what I do for now. After searching for some .net built in solutions, I started creating an update function that would copy values from the modified object into a context object, allow Entity Framework to detect the change and commit. First round looked like this.

        public void Update(User copyToUser, User copyFromUser)
        {
            var type = typeof(User);
            foreach (var pi in type.GetProperties())
            {
                var copyValue = copyFromUser.GetType().GetProperty(pi.Name).GetValue(copyFromUser, null);

                copyToUser.GetType().GetProperty(pi.Name).SetValue(copyToUser, copyValue,null);
            }

        }

This was working great, except it was modifying values related to identity and references! And then creating new objects! ACK! While I could have hard coded specific property names to either be skipped or evaluated, I wanted a more concrete and testable way.

I created a specific Interface under my current IUser and named it IUserDetailsCompare. Then instead of using the User type during my reflection loop I told the loop to evaluate the Interface. Done!

    public interface IUser
    {
        long Id { get; set; }
        string Email { get; set; }
        string NameFirst { get; set; }
        string NameLast { get; set; }
        DateTime DateJoined { get; set; }
        Guid Ref { get; set; }
        bool Active { get; set; }
        bool Disclaimer { get; set; }
    }

    public interface IUserDetailsCompare
    {
        string NameFirst { get; set; }
        string NameLast { get; set; }
    }

        public void Update(User copyToUser, User copyFromUser)
        {
            var type = typeof(IUserDetailsCompare);
            foreach (var pi in type.GetProperties())
            {
                var copyValue = copyFromUser.GetType().GetProperty(pi.Name).GetValue(copyFromUser, null);

                copyToUser.GetType().GetProperty(pi.Name).SetValue(copyToUser, copyValue,null);
            }

        }
I consider this a huge win in my strive to follow a more TDD approach.

Monday, February 27, 2012

MVC and Facebook for real

Believe it or not. I am about to release my first professional MVC 3 application for a client. I have done a few personal projects to learn and play with. But this one is for real and will get high traffic. This site also has a facebook integration on creating and managing events.

Since this isn't my first MVC 3 application, I really wanted to get a better grasp on partial views and how to implement them successfully. What I knew about partial views before going into this project is they are the ideal substitute of custom controls in a webform app. My first ever MVC 3 project coming from webforms I was expecting it to be a self contained "drop in" piece of functionality. And the first code example I saw was calling HTML.RenderPartial("_partial.cshtml"). Well I didn't really get how it was self contained, the partial views depended on objects in the viewbag without going back to the server. In order to different object it felt as if I had to much .net code going on in the partial view for it even to be considered a 'view'.

Even though I have heard and seen Controller Actions return a partial view I couldn't figure out why a controller action would just return a partial when I want a full user experience. Looking back this is mainly new syntax learning with razor vs traditional asp code. I finally ran into HTML.RenderAction() What a game changer it was. I could now drop in functionality independent of location and it would render proper html.

Monday, November 21, 2011

TDD Adventure: Repository Newb

Forcing myself to use Test Driven Development is teaching me more than expected. Last year I learned about Entity Framework and the ease it brings to developers who want to focus on functionality. I created a project with it, and looking back on the code now it looks very much 'rookie'. I have matured quite a bit with the idea of context.

Recently with a new idea for another project I want to tackle TDD this time. Being experienced with Entity Framework I still felt like I was making hard coded database calls in the controllers. It wasn't really hard coded database procedures, but it was direct expressions against the entity object set. I feel really newb saying this, but I heard talk and would read about this 'repository' class. But didn't fully understand it and what it was for.

Just going through this tutorial twice, once as exampled and the second using my project. I could almost hear the light bulb click on. Repositories are the place for all the Linq code which could be SQL or even calls to stored procedures. And using a fakeObjectSet as the context really sets me up for the way I approach projects and allowing me to also start my newest project with TDD.

Tuesday, November 15, 2011

WebGrid Duh


Why reinvent the wheel for a Porsche when Microsoft already has a Ford in full production.
As I am doing another start up idea, I have been able to implement a lot of what I have learned previously with MVC. There is talk around a few 3rd party libraries out their to perform specific tasks designed to help speed up development time.
MvcContrib is one of these. Looking for a better and more strongly typed way of displaying table data I ran into MvcContrib being talked about quite a bit. I also noticed the comments where 2-3 years dated. The class I wanted to implement was the .Grid().
While searching for specifically MVC and Grid() the System.Web.Helpers Namespace also showed up. Now while using the MvcContrib class may have more functionality than the limited bare bones you get with a Microsoft Library, Microsoft is the 800 pound Gorilla. For learning a new class and shooting for functionality vs efficiency and problems I wish I had, the WebGridclass is treating me right.

TDD is great to talk about.


My latest upcoming project I am vowing to use Test Driven Design/Development. Reading books, going through tutorials, even watching videos of rock star TDD professionals is very inspiring. The problem I am having is re-gearing my approach to code. My standard thought process involves thinking of the root level object and how to build on top of it. Where TDD should be getting straight into the real problem and top down development.
I am trying to bring TDD into existing projects but keep walking away because I convince myself writing the solution would be quicker. Deep down, I know the more I practice I get with TDD, the better and more proficient I will become and eventually be coding faster than before with tested code. As I force myself though the books, the urge to utilize TDD in current projects grows stronger. Soon, I hope, I will be confident enough in my TDD skills to bust into it. Just as I taught myself MVC, I need to do the same for TDD.

MVC / MVC?


Using a shared hosting server has a huge advantage of cost. Especially if you don’t expect large traffic. It does provide some unique challenges when dealing with configuration though.
By default, web.config files inherit from each other. Awesome news if your building sub folders to contain micro-sites of your original. You immediately get access to all your connections, provides, and even custom classes you previously imported. But when creating sub folders within your root directory housing a different domain, things get a little messy.
After getting a base MVC site set up locally I deployed it to my shared hosting solution. The first thing I noticed was the url routing was off. Instead of the typical “domain.com/{controller}/{action}” I was seeing “domain.com/{subfolder}/{controller}/{action}” While I could manually remove the subfolder from the url and still get a successful request. This was not ideal and I don’t think the end user is interested in my subfolder naming convention.
I knew I was going to have to use some url rewriter to accomplish this. It didn’t take long for me to find out my hosting provider has dealt with this before and has pre-installed a URL Rewrite Module on all their windows shared hosting accounts with IIS 7. Lucky me. Easy fix, all I had to do was add some specific xml to my subfolder web.config system.webServer section.
<rewrite>
     <rules>
          <rule name="Remove Virtual Directory">
               <match url=".*" />
               <action type="Rewrite" url="{R:0}" />
          </rule>
     </rules>
</rewrite>
The second piece was not inheriting the connections and providers from the parent web.config. There are two ways of doing this, the easiest is putting
<clear />
after your section deceleration and before your names. This worked for most of it, what the previous doesn’t cover is any attributes you may have declared in the section deceleration, such as
<membership defaultProvider="customProvider">
The clear needs to go after this line, but doesn’t clear the attributes. So how do we remove this from our config? First, hopefully you have access to the root directory. Now edit the root web.config and place a section before your <system.web>, it should look like this.
<location path="." inheritInChildApplications="false">
        <system.web>
            ....
        </system.web>
    </location>
The only thing you really need to be careful here is this will wipe out your entire <system.web> for any sub folder you create. So make sure your children applications have valid web.config’s. Enjoy!

Switching from full Entity Framework to POCO


A big challenge I had with moving from a full Entity Framework solution to adopting a POCO set was managing state. Since my project was working well and I went to POCO I starting picking up issues with data not saving.
A huge issue was logging into the webapp. Obviously the most important function. The application tracks the logged in user via a session token saved to the database. After many frustrating tests and a half solution I thought was working, I finally found the ObjectStateEntry wasn’t keeping track of the object. The changes I was making to the object properties didn’t notify the OSE because I was using POCO and didn’t have it set up.
Searching google for some time I ran into this article http://blogs.msdn.com/b/adonet/archive/2009/06/10/poco-in-the-entity-framework-part-3-change-tracking-with-poco.aspx . Great article and I came up with an ugly, but working resolution of changing the state manually before saving. Is there a better way? Most likely, but this works and was speedy fix to get users logged into the system.