Saturday, December 29, 2012

How to set up OAuth and SimpleMembership on MVC4 with IIS

If you're new to MVC4, you will notice that a lot has changed with the Membership Provider.  You no longer need to run Aspnet_regsql.exe and you no longer need to run the ASP.NET Web Configuration Tool.

In MVC4, user registration and authentication is done using SimpleMembership.  By default, when you run your web application, users are registered in a lightweight database within your project called LocalDb.  If you want to use a different database such as SQL Server 2008 or 2012 then all you have to do is modify your connection string in your web.config.   What i did was I commented out the LocalDb connection and added a new one that points to my SQL Server 2012 database.


 <!--<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-CoolDB;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-CoolDB.mdf" providerName="System.Data.SqlClient" />-->

    <add name="DefaultConnection"
       connectionString="Data Source=gmisa-win;Initial Catalog=CoolDB;Integrated Security=True;MultipleActiveResultSets=True"
       providerName="System.Data.SqlClient"/

Also, add the Role Manager and Membership to your web.config:


 <roleManager enabled="true" defaultProvider="SimpleRoleProvider">
      <providers>
        <clear />
        <add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
      </providers>
    </roleManager>
    <membership defaultProvider="SimpleMembershipProvider">
      <providers>
        <clear />
        <add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
      </providers>
    </membership>



Once this is set, I can run my application and start registering new users.   You will notice that there are new tables created on your SQL Server database.

If you are using IIS, you have to make sure that the Application Pool that you're using runs on an Identity that can access your SQL Server database.

Now another interesting feature in MVC4 is how easy you can let users register using OAuth.  This means that users can register on your site using their Facebook, Twitter, MSN and Google accounts.  This is very simple to set up.  All you have to do is go to AuthConfig.cs which is under the App_Start folder in your project.  Uncomment the client that you want users to be able to use.  Add your app's authentication details to it.  It's usually an App Id and a Secret key.


 OAuthWebSecurity.RegisterFacebookClient(
                appId: "119036189745",
                appSecret: "ef9dj4730fkdj4ae3acc8eab4a117577");

Once this is set, run your application and click Log In.  You will see that there is a Log in using Facebook button.   Isn't that cool!??

Friday, December 28, 2012

YouTube Data API (V3) Javascript Client Example problem


Everyone knows the YouTube Data API (V3) is still experimental.  But still, i'm sure most developers are excited to try new stuff from Google.

I was eager to build an ASP.NET MVC site that would be able to upload videos to YouTube.

I tried playing around with the YouTube .NET Client API hoping it would simplify things but then I realized this was a no browser implementation and the user had to manually enter an authorization key.  Ok this is not what I need.

I tried out the YouTube Javascript Client API and followed the instructions on the Samples page and it looked pretty neat and straightforward.  Then when i tried to run the application, it didn't work! (of course, it's experimental).  

First, let me show you the code from Google:

//Retrieve the uploads playlist id.
function requestUserUploadsPlaylistId() {
    // https://developers.google.com/youtube/v3/docs/channels/list
    var request = gapi.client.youtube.channels.list({
        // mine: '' indicates that we want to retrieve the channel for the authenticated user.
        mine: '',
        part: 'contentDetails'
    });
    request.execute(function (response) {
        playlistId = response.result.items[0].relatedPlaylists.uploads;
        requestVideoPlaylist(playlistId);
    });
}

There were 2 errors i got:

1.  TypeError: response.result is undefined

When i looked at the JSON response from Google, here's what I saw:

[
 {
  "error": {
   "code": 400,
   "message": "Invalid boolean value: ''.",
   "data": [
    {
     "domain": "global",
     "reason": "invalid",
     "message": "Invalid boolean value: ''."
    }
   ]
  },
  "id": "gapiRpc"
 }
]


Then i looked at the line of code making the request:
var request = gapi.client.youtube.channels.list({
        // mine: '' indicates that we want to retrieve the channel for the authenticated user
        mine: '',
        part: 'contentDetails'
    });
And I just changed mine: '' to mine: true which went through.  But there was 
another error.

2.  TypeError: response.result is undefined (same error actually)
But happens on this line:
Looking at the response, I saw this:
[
 {
  "error": {
   "code": -32602,
   "message": "No filter selected.",
   "data": [
    {
     "domain": "youtube.parameter",
     "reason": "missingRequiredParameter",
     "message": "No filter selected.",
     "locationType": "parameter",
     "location": ""
    }
   ]
  },
  "id": "gapiRpc"
 }
]
The solution is to change this:

playlistId = response.result.items[0].contentDetails.uploads;

to

playlistId = response.result.items[0].contentDetails.relatedPlaylists.uploads;

And i'm glad i was able to retrieve my uploaded videos!!!

Thursday, December 27, 2012

IIS - Cannot read configuration file due to insufficient permissions

Did you ever try to create a new website in IIS, run it and get this error?


The requested page cannot be accessed because the related configuration data for the page is invalid.

Easy fix!

  • Go to IIS, right click on your website and choose Edit Permissions. 
  • Click on the Security tab.  
  • Click on the Edit button.  
  • Click on the Add button.  
  • On the Enter the object names to Select, Type "Everybody" (without the quotes)
  • Click all the OK buttons.

Had to list this down because i keep forgetting!

Tuesday, December 11, 2012

Combining ASP.NET Webforms and MVC into one solution


If you've been wanting a Hybrid ASP.NET Application with both Webforms and MVC in it, then you've come to the right place.  You may have an existing Webforms site and need to migrate to MVC but you don't know where to begin.  There are different approaches to do this.  Of course creating an MVC web application from scratch is the cleanest and easiest to maintain.  However you might need to deploy 2 websites in parallel to do this transition.  If you are not able to deploy 2 websites in parallel then an option is to add MVC code into your Webforms project .  This will definitely work.  The only thing is that you lose some nice MVC development features like Scaffolding. But if you're ok with creating these MVC files manually then it won't be an issue.  Thanks to Scott Hanselman's Blog for most of the information.  I am using Visual Studio 2012 for this test.

1.  First, add these references to your Webforms project:
a.     System.Web.MVC
b.     System.Web.Razor


2.  Add this in appSettings to your web.config

<appSettings>
   <add key="ClientValidationEnabled" value="true"/>
   <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>



3.  Add these under compilation to your web.config

<   <compilation debug="true" targetFramework="4.0">
  <assemblies>
    <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  </assemblies>
</compilation>


4.  Add these namespaces in pages to your web.config

<system.web>
  <pages>
     <namespaces>
       <add namespace="System.Web.Helpers" />
       <add namespace="System.Web.Mvc" />
       <add namespace="System.Web.Mvc.Ajax" />
       <add namespace="System.Web.Mvc.Html" />
       <add namespace="System.Web.Routing" />
       <add namespace="System.Web.WebPages"/>
     </namespaces>
   </pages>
</system.web>



5.  Add this to your web.config. This is under the <configuration> node
<system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>



6.  Add this to your Global.asax

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
        filters.Add(new HandleErrorAttribute());
}

public static void RegisterRoutes(RouteCollection routes)
 {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

 }

protected void Application_Start()
{
        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
}


7.  If you want the default Webforms page to load first, add this line before the other routes.  Or else the MVC default page will render first.

            routes.MapPageRoute("MyWebFormDefault", "", "~/Default.aspx");
        

     8.  Make sure you add these to your Global.asax

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

Copy some MVC files into your Webforms project.  In my case, I copied the Controllers, Models, and Views folders.  For simple testing purposes, I removed files related to AccountController and its views.  I only left the HomeController and its views plus the Shared views.

Thats it!  If you run your application, you should see the default.aspx on the browser.  If you type in a friendly URL such as http://localhost:8023/Home you should see the MVC Home page.