Posted by admin on Thursday, October 30, 2008 at 1:19 PM

I was listening to a conversation between a man and his son the other day.  I've spent a fair amount of time with them over the years and was interested in what they had to say.  The man was reassuring his son that change is good even though sometimes it can be frightening.  That seems like a reasonable enough position I suppose.  But is change always good?

Take this Freedom Of Choice Act for example.  Just like the man's statement that change is good, it sounds great.  It's wholly American - Freedom and Choice.  Liking both I read it for myself to see what exactly it says.  First I found that in Section 4 it says that the government may not interfere with a woman's right to choose to either bear a child or have an abortion.  Okay, abortion is legal now.  Nothing new there.  Subsection b2 is a little more interesting.  It says the government may not "discriminate against the exercise of the rights set forth in paragraph (1) in the regulation or provision of benefits, facilities, services, or information."  Personally, I find this one a little confusing.  What does all that really mean? 

To understand the effect of b2 you have to take a look at the Hyde Amendment.  In 1976 passage of the Hyde Amendment prevented tax dollars from being used to fund abortion procedures through Medicaid.  This seems an equitable balance.  No citizen can be forced to fund abortions via their tax dollars.  However, if the FOC Act says that the government cannot discriminate against the exercise of these rights in the provision of benefits, then the FOC Act and the Hyde Amendment are in conflict.  Hyde is established law - already on the books.  It wins, right?  Actually, no.  This is where Section 6 comes in with the retroactive knockout punch.  Section 6 says that the FOC Act applies to all previous federal legislation, in effect negating the Hyde Amendment.  In short, the Freedom Of Choice Act would make abortions conducted for any reason, not just maternal health and the other usual exclusions, available through Medicaid.  But, strangely enough, that's the least scary part of this change. 

SEC. 6. RETROACTIVE EFFECT.
This Act applies to every Federal, State, and local statute, ordinance, regulation, administrative order, decision, policy, practice, or other action enacted, adopted, or implemented before, on, or after the date of enactment of this Act.

It also applies to every "State, and local statute, ordinance, regulation, administrative order, decision, policy, practice, or other action".  Not only does it negate the Hyde act, it also sets aside every state restriction on abortion as well.  Those exclusions include so called "conscience provisions" that allow healthcare personnel to opt out of participating in abortions without fear of losing their jobs.  It also includes requirements for parental consent for minors or even counseling prior to the procedure.  And what about limits on late term abortions?  All are swept aside thanks to the FOC Act's prohibition of government interference "prior to viability", the frontier of which is pushed back before our eyes thanks to advances in medical technology.

Of course you can you can guess by now, I'm pro-life.  I'm also strongly in favor of leaving as much power in the hands of the individual States of our Republic.  Like it or not, the Freedom Of Choice Act takes more than it gives.  It takes away my choice to not participate in or support abortion through my tax dollars.  It also takes away my voice at the state and local level of government.  And what of the choice of like-minded healthcare workers that agree there are better alternatives to abortion? 

So what does all this have to do with the conversation between the man and his son?  Just this: in a speech before Planned Parenthood on 7/17/2007, in response to a question from the audience, Barack Obama said, "the first thing I'd do as President is sign the Freedom Of Choice Act."  Am I afraid of this kind of change?  Absolutely.  Are you?

Comments [1]     Categories: Off Topic              
Posted by admin on Thursday, August 14, 2008 at 12:57 PM

One of the big new features in the upcoming release of HappyFish will be the ability of users to upload their data to their account and then download it elsewhere.  This is perfect for users who have HappyFish installed both at home and work.  Each time HF starts it will pull down the latest changes and then push them back up when it exits.  The value added feature in uploading will be that user's subscriptions will be anonymously aggregated to form a feed directory.  The result (I hope) is a directory of feeds that people actually subscribe to rather than a huge spam list.  Optionally, users will also be able to share, in a public feed of their own, their feed subscriptions along with favorite feed items and related comments.  I don't know about you, but that sounds like a perfectly good excuse for testing out the ASP.Net MVC framework.

For this article I am assuming you've worked through some introductory material like the tutorial videos found on the ASP.net MVC page.  At the time of this writing even though I've got Preview 4 installed on my machine the Preview 3 introductory videos are still relevant.  The videos do a good job of covering the basics of getting started.  My goal here is to expand on some of the details associated with setting up an MVC site that were not apparent to me when I first began.

Controllers and Actions

One of the differences in working with an MVC application that stands out even before delving into the code structure is the way the URLs in an application change.  No more http://mysite.com/default.aspx.  Under MVC the default page address probably looks like http://mysite.com/home.  The parts of URL specify controllers, actions, and arguments.  This is similar to class, method, arguments of the typical programming model.  The URL pattern maps to a route in the Global.asax file.  The default route specified is

routes.MapRoute(
    "Default",                                             // Route name
    "{controller}/{action}/{id}",                          // URL with parameters
    new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);

Based on that I began organizing my application around intended controller actions and arguments:

Controller Action Argument Description
Feeds Search keywords Search by keywords in the feed's title or description
  Browse letter of alphabet Alphabetical listing by feed title
  Recent number of new feeds to show The newest x number of feeds added to the directory
  Rating number of stars Lists feeds by user rating
  User username Not sure about this one

Everything is pretty straightforward until I come to the User action.  For the user's feed subscriptions I want two things, a web page view of the user's subscriptions and the subscriptions output in OPML format.  Likewise, with the user's favorite feed items I want to provide a web page view as well as output in RSS format.  Sounds like I need to promote the User action concept in my application to a controller. 

Controller Action Argument Description
User Feeds username, format The users feeds as either a web page or OPML.
  Favorites username, format The users favorites as either a web page or RSS.

This seems reasonable.  I have a lot of options for the action argument.  I could accept the username with an optional dotted suffix a la

  • Directory/User/Feeds/thirstycrow - outputs the feeds in a web page
  • Directory/User/Feeds/thirstycrow.opml - outputs the feeds in opml format

or simply always output the feeds in OMPL format and style them for browser consumption with xslt.  <groaning and gnashing of teeth />  I think I'll go with the former - a single argument.  It cleanly expresses the intent and will look familiar to users to see the .opml or .rss suffixes.  Still, seeing username, format made me wonder how to route multiple arguments to an action like

public ActionResult Feeds(string username, string format) { ... }

I fooled around with the Default route in the Global.asax page, extending the path with more slashes and parameters, but could not even get a single parameter Action to work. 

"id" Matters

When I set up my first test controller action it was

public ActionResult Search(string keyword) { ... }

However, when I tested ../Feeds/Search/test the argument 'test' wasn't making into the method.  Experimenting I found that ../Feeds/Search/?keyword=test worked, which was not the attractive URL that MVC had promised.  Is this some sort of bait and switch?  It turns out that by changing my method to

public ActionResult Search(string id) { ... }

the 'test' argument made it through.  In other words {id} in the default route "{controller}/{action}/{id}" should be the name of the argument in the method as well.  Despite going through several tutorials I never picked that up.  Applying this to the two argument question I now see the answer is an action on my User controller that looks like this

public ActionResult Feeds(string id, string format) { ... }

with a corresponding URL of ../User/Feeds/thirstycrow?format=opml.  Not as aesthetically pleasing as ../User/Feeds/thirstycrow.opml, but it's the answer none the less.  The thing to keep in mind is that what I've said above applies only if I want to funnel everything through the default route.  Ultimately what I realized I needed to do was establish other routes in my Global.asax file.  And this is where the routing concept finally clicked.  Back to Global.asax.

Expanding Routes

The purpose of routes in the MVC is to map a given URL pattern to a controller's action and pass in the associated arguments, if any.  Understanding that and based on what I had learned from experimentation I saw that if I want ../User/Feeds/thirstycrow.opml to map to

public ActionResult Feeds(string username) { ... }

on the User controller, instead of modifying the default route, I needed to add a route.

routes.MapRoute(
    "UserFeeds",               //Route name is arbitrary
    "User/Feeds/{username}",
    new { controller = "User", action = "Feeds", username = "" });

And by extension, a multi-argument action

public ActionResult FormattedFeeds(string username, string format){ ... }

requires a different route.

routes.MapRoute(
    "FormattedUserFeeds",               //Route name is arbitrary
    "User/Feeds/{username}/{format}",
    new { controller = "User", action = "FormattedFeeds", username = "",
    format = "" });

The FormattedUserFeeds route above would handle ../User/Feeds/thirstycrow/opml.  Not bad.  I still prefer the .opml variant, but you can see the point.  Don't funnel everything through the default route.  It's important to note in the above snippets I did not overload the Feeds method as you might expect.

public ActionResult Feeds(string username) { ... }               //will not work
public ActionResult Feeds(string username, string format){ ... } //will not work

Attempting an overload, even with differentiated routes like those shown above will throw an error along the lines of "More than one action named 'Feeds' was found on controller..."

Next Step

Having grasped the relationship between URLs, routes, controller actions, and arguments the next step is to write the bodies of the controller actions and create the associated views.  In the case of the HappyFish feed directory I'm using the new SQL Server Data Services beta for the back end.  In the next post I'll cover some of what I've learned while experimenting with the private beta.

Comments [1]     Categories: asp.net | MVC              
Posted by admin on Thursday, August 07, 2008 at 8:44 PM

Here's one of those things I do just infrequently enough to forget a step.  Now I just need to remember that I've put all the steps here.

  1. Provision a database.  It does not need to be new, but it cannot already have the ASP.net membership provider tables in it.  If it does, skip ahead to step 3.
  2. Use the aspnet_regsql.exe tool to create the necessary tables and stored procedures in the database.  The tool can be found at <system drive letter>:\Windows\Microsoft.NET\Framework\v2.0.50727.  The tool has a GUI wizard that will lead you through the steps.
  3. Create a web site.  A local web site works fine.
  4. Add the connection string to your database to the web.config file.  Connection strings are placed just inside the configuration root:

    <configuration>
      <connectionStrings>
        <add name="SqlMembershipConnection"
             connectionString="Data Source=IPADDRESS;Initial Catalog=DBNAMEHERE;User
             ID=DBUSERNAMEHERE;Password=PASSWORDHERE" />
      </connectionStrings>
    <configuration>

  5. Add the SqlMembershipProvider to the web.config file under the system.web node:

    <membership>
      <providers>
        <clear/>
        <add name="AspNetSqlMembershipProvider"
             type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
             connectionStringName="SqlMembershipConnection"
             enablePasswordRetrieval="false"
             enablePasswordReset="true"
             requiresQuestionAndAnswer="false"
             requiresUniqueEmail="true"
             passwordFormat="Hashed"
             maxInvalidPasswordAttempts="5"
             minRequiredPasswordLength="7"
             minRequiredNonalphanumericCharacters="1"
             passwordAttemptWindow="10"
             passwordStrengthRegularExpression=""
             applicationName="NAMEOFAPPHERE"/>
      </providers>
    </membership>

    NOTE: The connectionStringName parameter of the membership provider must match the name you chose for the connection string above.  The applicationName parameter allows you to use the same database for different web applications.  Choose a suitable name and set the other parameters as needed.

  6. Add a CreateUserWizard control to the default.aspx page of your web site. 
  7. Right click on the default.aspx page and choose "View In Browser" from the context menu.
  8. You know the rest...
Comments [0]     Categories: asp.net | SQL Membership Provider              
Posted by admin on Tuesday, August 05, 2008 at 3:52 PM

One of the benefits of working alone or in a small shop is the freedom to be an early adopter.  I'm not the bleeding edge type, but I certainly keep an eye out for new technologies and try to apply them in real world situations.  Typically this starts first with HappyFish.  (Side note: Every developer should have at least one pet project for experimentation and learning.)  For whatever reason I was slow to respond to LINQ.  I have since embraced it and am still surprised at how easily I can express my intent through LINQ.  Sure, at first the syntax feels like reaching around your back to scratch your navel, but there is a lot of power to be had.

My focus lately has been on SQL Server Data Services (SSDS) and ASP.Net MVC.  SSDS is a cloud based data service similar to what is currently available through Amazon Simple Storage Service program. While overall Amazon's offering is a more complete cloud computing solution, SSDS is focused on an infinitely scalable off site data storage solution.  This would be comparable specifically to Amazon's Simple DB, which like SSDS is in private beta.  I signed up for both but still have not gotten into Amazon's program so I cannot offer a comparison.  However, I really like what I've seen with SSDS so far.  Here are some related links for getting familiar with SSDS:

The ASP.Net MVC framework is my other focus lately.  From the official site:

"ASP.NET MVC provides a framework that enables you to easily implement the model-view-controller (MVC) pattern for Web applications."

Some argue that the code behind page model of ASP.Net represents the MVC pattern, but this is a more complete synthesis of the idea.  The separation of concerns - that is - one part being responsible for a single task - achieved via the framework makes it easier to test and maintain the code.  In fact, when you create an MVC project a testing project is created along side.  Preview 4 was released July 16 and is available for download from the CodePlex site.  Here are some related links:

The thing to keep in mind with both SSDS and MVC is that both projects are under development and are evolving quickly.  Some of these links will probably be stale in a week or so.  Still, I wanted to put them out there for early adopters like myself or others who may just need a push to get started.  Remember - adopt early, adopt often.

Comments [0]     Categories: asp.net | MVC | SSDS              
Posted by admin on Tuesday, July 29, 2008 at 2:06 AM

I've had this problem before.  I'm not exactly sure what causes it, but rarely I'll open a dataset in the design view and only the XML markup shows.  The first time this happened I made the mistake of running some Visual Studio reinstall command I found out there and lost a bunch of my personal settings.  Here's the quick, painless solution:

  1. Close the dataset file. 
  2. Find the file in the solution explorer, and click on the plus sign [+] to expand the subfiles of the .xsd file.
  3. Delete the .Designer.cs or .Designer.vb subfile.  It will probably be the first of three subfiles.
  4. Reopen the .xsd file to regenerate the .Designer.cs/.vb file thereby restoring your design view.

If that doesn't work you can always try a Visual Studio repair of some sort, but remember to backup your Visual Studio settings and any Code Snippets you've tweaked.

Comments [0]     Categories: Visual Studio