Ryan LanciauxNew Media Mercenary

Are you a Control Freak?

March 24, 2009 by ryan

No Controls?
Since the very early ASP.NET MVC previews, the most common argument I've heard against using the framework is the lack of user controls. In my opinion, this is a mixed blessing, however, for some, this is a show stopper. What can you do to provide a rich user interface with the MVC framework, while not reinventing the wheel?

jQuery
Now you could go ahead and program a full fledged data grid or WYSIWYG editor, however, unless you have a bit of time to spare this is not the ideal solution. As most may realize, jQuery fits very nicely to fill in the gaps left by the absence of user controls. For the most part, the controls are not going to let you just drag-and-drop, type in a dataset and profit but a lot of the pain is kept to a minimum.

Examples
Ingrid

If you're looking for a data grid there are a number of options available pictured above is Ingrid. Flexigrid is another good one that people have used with the MVC framework, however, their site appears to be down at the moment.


Treeviews are available

Radio Buttons / Check Boxes

Check out the jQuery plugin database.

Getting Started
So, if you've decided you want to look more into using jQuery plugins -- a couple of tips that may make the transition a little easier:

  • Read up on what people using different languages are doing. I'm not saying that you should necessarily go out and learn Rails or CakePHP/CodeIgniter (although, it is beneficial). but at least look at the techniques that programmers from that realm of things are doing -- see how they are implementing their controls.

What tips do you have for creating robust user interfaces with the MVC framework?
kick it on DotNetKicks.com




Findlay .NET UserGroup Recap

January 27, 2009 by ryan

I had a great time tonight at the Findlay .NET User group! Thanks everyone that battled the weather to come out and hear me talk about the ASP.NET MVC Framework. As promised, I have posted the route constraint to allow only alphabetical values to be accepted as valid input for the display named message.

  routes.MapRoute("Message",

                 "Message/{action}/name/{Name}/",

                 new { controller = "Message", action = "HelloWorld", name = "" },

                 new {name="[a-zA-Z]+"}

  );


I apologize about the lapse in memory -- The regular expression needed a + at the end to signify that it was more than one character whoops :)  For more information on Routes check out Justin Etheredge's post on routing


MVC Framework Talk : Findlay .NET User Group

January 23, 2009 by ryan
I will be giving a talk on the ASP.NET MVC Framework at the Findlay .NET User Group on Tuesday, January 27th (5:30pm - 7:30pm). If you're in NW Ohio and want to learn more about the MVC framework and how to get up and running with it you might be interested. The talk is taking place at the Marathon building downtown -- 539 S. Main St., Findlay, OH - Room 106M. More information is available at the User Group site. Hope to see you there!


Do you suffer from this condition?

December 17, 2008 by ryan

Oxitis [oks - ahy - tis]
-Noun

Acute or chronic anxiety toward sharing code online; this anxiety is usually caused by fear of public ridicule or excessive criticism regarding imperfections in code.

Origin: 
2008, Josh Schwartzberg (n.); Oxitephobia; avoidance of placing imperfect code online; initially referring to Microsoft Oxite


kick it on DotNetKicks.com




What Constitutes Ethical SEO?

December 12, 2008 by ryan
"nice post!!thanks for the info..that's great and cool"
                                               -Random Spammer

As a web developer / someone who has a blog, I understand dealing with spam is one of the necessary evils of having a comments enabled on my site. For the most part, my site has remained far enough under the radar that most spammers do not waste their time. More recently, however, there has been a gradual influx of comment spam with a title something along the lines of "[Company Name] SEO Test." There is worse spam for sure but it was definitely annoying.

A quick Google search pointed me to a Web Development and Search Engine Optimization company hosting an SEO competition. I checked the rules and sure enough, there was a rule stating that only Ethical SEO Techniques would be permitted. Quickly, I emailed the organization one of the comments (with url, ip, email, etc) exepecting the offending parties would be removed from the competition, eliminating additional garbage comments. I was shocked to receive their reply.
Unfortunately this is not against the rules of the competition – I would encourage you to remove the spamming links for your website to discourage this behaviour but as I said I can’t actually penalise this person for making posts on other peoples websites.

Sorry about the spam.
Gaming the System
In my opinion, Search Engine Optimization should be about perfecting a website and the website's content; not tricking google into thinking more people find your content useful than actuality. Optimizing tags and titles is one thing but gaming the system to garner search ranking is wrong and is detrimental to the web as a whole. Just because commenting is legal and allowable does not make it ethical. Unfortunately, this practice will continue to exist as long as it gets results and organizations act as enablers to those who would use these tactics for financial gain (not to mention increased search engine ranking for the enabling organizations).

Link Spam is Digital Graffiti
Imagine for a second if companies condoned this practice outside of the Web -- what if McDonalds or Nike paid for their logos to be spray painted on other's property? To make matters worse what if after receiving numerous complaints they held a press conference and said "soap and water removes the paint" or "just hire some guards and the problem will go away."? I think it's safe to assume that practice would not be received so kindly (h/t Matt Braun on the graffiti analogy)! Fortunately a link is not as hard to remove as paint but the concept is similar.

Solutions anyone?
Social networks such as Digg, DotNetKicks and DZone have always been plagued by those who would try to circumvent the rules for personal gain. Where honeypots and captcha systems would traditionally help against bots, an increasing number of spammers seem to be actual people. The administrators of these social networks are constantly coming up with more sophisticated ways to combat spam but what should small blogs and websites do?

Currently, there are a number of methodologies for preventing blog spam that work with varying degrees of effectiveness but none are ideal. Obviously, you can moderate comments -- this works okay but is painful if you are getting a lot of spam or a lot of comments. Also, make sure your comment links have a rel="nofollow" attribute (h/t Simone Chiaretta). Google does not take nofollow links into account when calculating page rank. Although this does not reward the spammer, it does not prevent spam.

What I would like to see is a centralized comment system like Disqus or IntenseDebate that lets a user login with OpenID, Google Friend Connect, Microsoft LiveID, Facebook Connect (whichever the user wants). There would be a standard vote up / down vote for every comment a user makes where the overall votes across all sites would determine the users rating. Casting a down vote would remove a minimal amount of points from the voter to prevent someone from going on a down vote rampage (exactly how StackOverflow works). Site owners could set restrictions that would prevent users with a rating less than a specified number from posting on their site. This may be idealistic and introduce a new realm of privacy concerns but if done properly, I think it would help eliminate a great deal of spam.

Wrapping things up
Although there are many less-than ethical tactics to increasing a site's ranking, site structure and site content are the best methods of SEO. I would love to hear your thoughts, ideas and any suggestions you have in eliminating link spam.
If you liked this post...
kick it on DotNetKicks.com

Subscribe via RSS


Tags: , , ,
Categories: General
Actions: E-mail | Kick it! | Permalink | commentComments (22) | RSS comment feedComment RSS


MVC HtmlHelper for Gravatar

November 13, 2008 by ryan

Based on a great suggestion from Ben Scheirman and Simone Chiaretta I have converted the Gravatar URL helper class into a HtmlHelper extension method. This was my first stab at making a HtmlHelper extension but it seems to be working nicely and helps me keep my code a lot cleaner. Instead saving the URL (which I would highly advise against) or doing some weird method calling acrobatics in the Controller, I can simply say <%= Html.Gravatar("email@email.com") %> inside the view.

I've added a couple different method definitions for various parameters. You can pass in just an e-mail address, an e-mail and gravatar parameters (see here for more info on gravatar parameters) or an e-mail address, gravatar parameters and html attributes. A quick usage summary is listed below (I'm using my brother Joel's gravatar in the examples)


<%= Html.Gravatar("email@email.com") %>

Base Gravatar Helper 

 

<%= Html.Gravatar("email@email.com", new  { s = "128", r = "pg" })%>

Gravatar helper with optional Gravatar Parameters

 

<%= Html.Gravatar("email@email.com", null, new  { style = "border:5px solid" })%>  

Helper with HTML attributes. Please note, this is still expecting the Gravatar parameters -- you can pass in null if you want to just grab the default image with no additional properties.

 

<%= Html.Gravatar("email@email.com", new { s = "128", r = "pg" }, new { style="border:5px solid;"})%>

Helper with both Gravatar parameters and HTML attributes

 

Anyways, I've posted the class file below. Hopefully you find it useful -- I would love to hear what your thoughts are or of any changes you would like to see.
GravatarHelper.cs (2.72 kb)




Gravatar on ASP.NET MVC

November 9, 2008 by ryan

UPDATE: See here

In the near future, I have a web project coming out that I've been working on for the past month or so. I'm not going to give too much detail on that just yet, however, in working on this project, I had to come up with a way for users to have profile images. I would rather not host these images on my server, I decided to leverage Gravatar (Globally Recognized Avatars).

There are a couple pre-existing options for dealing with gravatar in the .NET framework, however, I'm using the MVC framework -- standard ASP.NET controls are out of the question. After a brief look on the Gravatar site (specifically the page dealing with how the URL is constructed), it seemed like this would be a pretty easy task to write a class that I could use to get gravatar image paths. Below is the main part of the class I created to retrieve gravatar information based on an e-mail address:


        public static string GetGravatarURL(string email, string size)

        {

            return (string.Format("http://www.gravatar.com/avatar/{0}?s={1}&r=PG",

                EncryptMD5(email), size));

        }

 

        public static string GetGravatarURL(string email, string size, string defaultImagePath)

        {

            return GetGravatarURL(email, size) +  string.Format("&default={0}", defaultImagePath);

        }

 

        private static string EncryptMD5(string Value)

        {

            System.Security.Cryptography.MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

            byte[] valueArray = System.Text.Encoding.ASCII.GetBytes(Value);

            valueArray = md5.ComputeHash(valueArray);

            string encrypted = "";

            for (int i = 0; i < valueArray.Length; i++)

                encrypted += valueArray[i].ToString("x2").ToLower();

            return encrypted;

        }


All we're really doing is creating a URL based on the Gravatar path, an MD5 encrypted version of an e-mail address and some user specified parameters. For the methods, Size is how many pixels the image should be (up to 500) and defaultImagePath is the url to use as an alternate image if the user does not have a Gravatar image. There is a rating parameter also but for my site, I'm setting it to PG always.

This is not all that difficult but hopefully useful. I plan to continue writing examples as I make progress on the web application I mentioned.





Theme Generator on Channel9!

August 18, 2008 by ryan

Wow, the theme generator that my brother and I made is on Channel 9.

It's in the video at about 11:30. Thanks to Dan and team for mentioning it! View the channel 9 site here.

 




Some tools for working with distributed teams

June 11, 2008 by ryan
Whether you're creating a project for fun or freelancing (etc.), working remotely as part of a team is becoming more and more common. Communication is still key to a successful project, however, it's much more difficult when your working with people in different locations and on different schedules. Although, you will not be able to achieve the same level of communication as face-to-face, there are some tools beyond E-mail, IMs and Remote Desktop that could make your life a little easier. Here are some of the tools I use when I'm not in the vicinity of as the team I'm working with.

Source Control
Obviously, source control is a must-have. This is a given for development projects; even if you're working by yourself. I use Subversion for all of my code because it's relatively easy to set up and, for the most part, pretty intuitive for newer users. When creating a source repository you need to choose to:
  1. Host your own
  2. Go through a third party
    • Assembla -Although there are many options in this arena, this is the host that I use for remote collaboration so it's the one I'm going to focus on. You can set up a Subversion repository simply by adding a new project to your workspace and specifying that you want to use subversion (in the setup configuration). From there you can add users or make your project open to the public. Apart from Subversion, there are many other features that may make Assembla a worthwhile site to check into.
Finally when running Subversion, you're either going to need an IDE that supports SVN, use the command line or download a client. I use Tortoise SVN and the command prompt, however, Visual SVN for Visual Studio looks nice (and when I'm using Eclipse, the SubVersion plugin is wonderful).


Screen capture software
It can be confusing trying to fix an issue based on a text description. Having a screenshot or video that explains how to reproduce a bug can be invaluable. Coupled with a bug tracking application, this can be an extremely effective way to quickly resolve issues. Camtasia is probably the ideal application for creating screen casts of a bug but for the price tag it might be overkill (especially if it's just for fun / open source). Currently, I usually use Wink by Debug mode for this sort of functionality. Although it's definitely not as feature rich as Camtasia, it gets the job done.

Also see: Jing

Real-Time Collaboration
Some situations require an extra level of involvement from team members. Vyew has been an awesome addition to the tool belt. With it, I can collaborate / share desktop / share files real time with someone else anywhere in the world in. Similar to the screen capture application, it really helps to communicate something that otherwise may be difficult to explain. Earlier in the week, for example, I was having some trouble with an Eclipse setting for a project I'm working on. Rather than sending e-mails back and forth trying to explain the issue, I used Vyew to share my desktop with a friend half way across the country. In a matter of minutes, he was able to diagnosis the problem and I was back in business. Vyew is free if you don't mind having ads on the page. Otherwise, it's $6.95/month for the Plus Package and $13.95/month the Professional version. For more information, vist the Vyew site or check-out Guy Kawasaki's synopsis of Vyew.

 

What tools do you use to stay connected with your team? 




RhinoCommons, NHibernate and ASP.NET MVC Part 4 - The MVC Application

May 26, 2008 by ryan

Finally we're to the point where we can see all our hard work come together. We have most of the hard work done but we still have a lot of ground to cover. If you haven't been following along, please check out Setting Up The Assemblies, Configuring the Application and Developing the Model.

Unit of Work

In some of my initial tests with NHibernate and ASP.NET MVC Pattern I kept seeing the benefits of having a Unit of Work or Session Per Request (that is opening and closing the NHibernate session at the begining and end of the http request respectively). To Recap a little, I started to write my own Session Per Request, however, Chad Myers pointed me to the Rhino Commons project which already implemented this. I think it's worthwhile becuase I don't really like putting NHibernate session code in my controller plus as Martin Fowler writes

A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.

Luckily, with RhinoCommons, it's pretty easy to implement this pattern (check out Ayende's post on this). In a standard web forms application, we would normally create a Global.aspx that inherits UnitOfWorkApplication. Since we're using ASP.NET MVC, however, we don't necessarily want to go that route. As Michael Hanney notes on his post on MVC and Castle we can have our Global.asax inherit from UnitOfWorkApplication.

 

    public class GlobalApplication : UnitOfWorkApplication

    {

 

        public override void Application_Start(object sender, EventArgs e

        { 

            base.Application_Start(sender, e); 

            RegisterRoutes(RouteTable.Routes); 

        }

...

     }

If you know of another way to do this, please be sure to let me know. Also, the routing still works as it normally would -- we're just running this code first to instantiate the UnitOfWork.

In our controllers we can call our reference our Hibernate repositories and classes without specifying an ISession.

        public ActionResult InsertProductGroup(string Title)

        {

            ProductGroup pg = new ProductGroup();

            pg.Title = Title;

            Repository<ProductGroup>.Save(pg);

            UnitOfWork.Current.Flush();

            return RenderView("AddProductGroup");

        }

Notice we're still flushing our data -- but it makes the controllers a LOT cleaner. Imagine if we had to instantiate and clean up our session in each controller.

One further thing, the UnitOfWorkApplication supports both short and long conversations. I'm not going to go too much into that but if your application requires keeping objects around for a couple HTTP Requests before saving to the database Long Conversation may be the way to go. See Ayende's Wiki for more on this

NHibernate Query Generator
In the first post of this series we looked at what it takes to setup NHibernate Query Generator (NHQG from here out). Now we get to use it to make some really nice looking code (in a later post, however, we'll be using LINQ to NHibernate). If we've set up the tool as mentioned in the first post (listed earlier), all we have to do is run the tool and make sure the generated code is added to the project.

NHQG lets us use a fluent interface to set filters on our Hibernate queries; this results in code that, in my opinion, is very easy to write and understand later on. If we wanted to Find one Product with a specific title, our code would look something like this:

        public ActionResult ViewProduct(string ID)

        {

            var p = Repository<Product>.FindOne(Where.Product.Title == ID);

            if (p != null)

            {

                return RenderView("DisplayProduct",

                                  p); 

            }

            return RenderView("DisplayProduct");

        }

The Where.Product.Title == ID is all from the NHQG autogenerated code. Now we actually have something to show for all our configuration and setup work. Soon, we're going to take a look at using LINQ to NHibernate instead of NHQG. In the meantime, I have checked all the code in to my svn at Assembla. My standard disclaimer on demo code applies here too :) This is just demo code for the sake of example. Some of it is far from ideal but great for learning.

Check out / update with SubVersion from the following location: http://svn2.assembla.com/svn/NHibernateTest









© 2008 Ryan Lanciaux :: powered by BlogEngine.NET