Welcome to ASP.NET Guild

Be sure to come back often and tell others. If you have any tips, tricks, examples, please email them to me at chris.williams@techguilds.com and I will post them. Check out our ASP.NET QuickStart and C# QuckStart Libraries. Below is my latest articles.

Friday, December 15, 2017

Reading and Writing files to Google Drive

It has been a while since I posted but I have been playing with Google Drive and accessing it from a console application and had to search in a few places to find the right way to do it. The documentation tells you to download the .JSON file and that is helpful.  You can find the sample on how to get a list of files from Google Drive in a Console application.

This is a good start but I was getting errors related to the Certificate:

"At least one client secret (Installed or Web) should be set"

The problem is that the code provided has you using UserCredentials and some funky streaming stuff.  The credentials can be read from the stream like this into a Google Credentials object.

            GoogleCredential credential = null;

            using (var stream = new FileStream(credentialsFileName, FileMode.Open, FileAccess.Read))
                credential = GoogleCredential.FromStream(stream);
                credential = credential.CreateScoped(scopes);

You then use that Google Credentials along with your application name to get the service:

            // Create Drive API service.
            return new DriveService(new BaseClientService.Initializer()
                HttpClientInitializer = credential,
                ApplicationName = applicationName,

Now after that fix, the original example works. I am assuming that since the article was written this has changed and the article has not been updated.  After applying this I do get the list of files from the article.


A scope is what determines what the calls made using the service can do. In general there are 2 scopes: Read-Only and Full Access. There are other scopes you can use as well.

If you want to do more than read from the drive then you will need to change your scope.  

        string[] ReadOnlyScope = { DriveService.Scope.DriveReadonly }; // Read Only
        public static string[] FullAccessScope = { DriveService.Scope.Drive }; // Full Access


It took a while to find how permissions work but I did find an article on Managing Shares that does go into it. It boils down to 2 types of permission: user and domain. A user permission assigns an individual user access. A domain permission assigns a domain access eg. "sitecore.net".  A permission has a role. The article describes the roles as "reader" and "writer".  This is a text string so possibly there are other roles as well.

Now personally, I have got the user permissions to work but when I try domain permissions I get an error. If you have successfully got domain working can you provide an example or take a look at the functions on GitHub for Domain Permission to see if there is something I am doing wrong?  I am passing "readwatchcreate.com" as domain. 

GitHub Libraries

I have created a GoogleAPIs public repository on GitHub. There are 2 folders. One for those still using .NET Framework which will not be updated and a DotCore folder with the new version built on .NET Standard and .NET Core. This includes a base library that has the code to connect to the API, a library that wraps some Google Drive functions to help you, and a unit test console app that will show sample calls and do positive and negative testing of the library. As I continue my learning of Google APIs, I will be adding more libraries for GoogleSheet and other API sections.

Monday, May 01, 2017

Introducing the ASP.NET Facebook Login QuickStart

Logging into Facebook is actually quite simple especially if you use our new ASP.NET Facebook Login Quickstart.

If you do not have a copy already email chris.williams@readwatchcreate.com to get instructions on how to access.


The first step is setting up your database.

  1. Open the database scripts in the QuickStart zip that start with CREATE_TABLE_.  Ensure they table names match your application prefixes for consistency.
  2. Open the database scripts in the QuickStart zip that start with CREATE_PROC_.  Ensure the table names match the tables in the CREATE_TABLE_ scripts in step 1.  
  3. Rename the procs to match your application prefixes for consistency. 
  4. Add the appSetting entries from the web.config in the Quickstart in the Web.Config file for your project. Make sure you change the stored procedure names in the appSettings to match your stored procedure names.
The second step is configure your ASP.NET application to use the plug-in.

  1. Add standard button or link button to page and implement click event.
  2. Call the LoginToFacebook function on this class with a call similar to the following but replace {my_site_name} with your site url.

    You may also want to change the access you desire:

    ASPNET.Authentication.Facebook.FacebookLogin.LoginToFacebook(ConfigurationManager.AppSettings["FacebookAppId"], "http://{my_site_name}/fb.aspx", "offline_access, email, user_likes, friends_likes");
  3. Create a page called fb.aspx and on load add the following code:

    if (Request["code"] != null) Session["AccessToken"] = FacebookLogin.GetAccessToken(ConfigurationManager.AppSettings["FacebookAppId"], ConfigurationManager.AppSettings["FacebookAppSecret"], Request["code"], ConfigurationManager.AppSettings["FacebookReturnUrl"]);
  4. Next you need to add the configuration keys to the web.config in teh appSettings section. These are provided by Facebook when you register your application:

    <add key="FacebookReturnUrl" value="http://{my site}/fb.aspx"/>
    <add key="FacebookAppId" value="{Likely a 15 digit number}"/>
    <add key="FacebookAppSecret" value="{This is a guid with no dashes}"/>
  5. Use the code returned to get the profile info back in JSON then use the helper functions to get each attribute you wish:

    string userProfileJSON = CXFacebook.GetUserProfile(Session["AccessToken"].ToString());
    ///     string id = CXFacebook.GetUserProfileId(userProfileJSON);
    ///     string name = CXFacebook.GetUserProfileName(userProfileJSON);
    ///     string firstName = CXFacebook.GetUserProfileFirstName(userProfileJSON);
    ///     string lastName = CXFacebook.GetUserProfileLastName(userProfileJSON);
    ///     string email = CXFacebook.GetUserProfileEmail(userProfileJSON);
    ///     string birthday = CXFacebook.GetUserProfileBirthday(userProfileJSON);
    ///     string link = CXFacebook.GetUserProfileLink(userProfileJSON);
    ///     string locale = CXFacebook.GetUserProfileLocale(userProfileJSON);
    ///     string quote = CXFacebook.GetUserProfileQuotes(userProfileJSON);
    ///     string userName = CXFacebook.GetUserProfileUserName(userProfileJSON);
    ///     string timeZone = CXFacebook.GetUserProfileTimezone(userProfileJSON);

Sunday, February 28, 2016

MVC RedirectToAction Explained for Beginners

RedirectToAction should be simple but sometimes they are confusing to beginners.  There are 3 ways to call RedirectToAction
  1. If you are already on a page within a controller you can use the shortest one which is only the caption and the action.

    eg. RedirectToAction("MyActionName")
  2. If you are referencing another controller or you want to include parameters.

    IMPORTANT: It may seem redundant but you need to list the action name twice. Notice Login is listed twice. 

    eg. RedirectToAction("Login", new RouteValueDictionary(new { controller = "Account", action = "Login", returnUrl = "/PersonalizedLearn" }));
I hope this clears up how RedirectToAction calls work.

If you have any questions feel free to email me at chris.williams@readwatchcreate.com

MVC Html.ActionLinks Explained for Beginners

Html.ActionLink should be simple but sometimes they are confusing to beginners.  There are 3 ways to call @Html.ActionLink:

  1. If you are already on a page within a controller you can use the shortest one which is only the caption and the action.

    eg. @Html.ActionLink("Click Here", "MyActionName")
  2. If you are referencing another controller or you want to include attributes on the link such as the css class


    @Html.ActionLink("Click Here", "Index", "Home", null)

    @Html.ActionLink("Click Here", "Index", "Home", new { @class = "myHrefClass" })
  3. If you need to pass parameters to your action then you need to use the full version.

    IMPORTANT: If you are NOT Specifying a class, you still need to pass NULL or it will assume that the parameters you are passing are actually the attributes like in the version in the section way above.


    @Html.ActionLink("Click Here", "Index","Home", new { paramName = value, param2Name = value}, null)

    @Html.ActionLink("Click Here", "Index","Home", new { paramName = value, param2Name = value}, new { @class = "myHrefClass" })

I hope this clears up how ActionLink calls work.  If you have any questions feel free to email me at chris.williams@readwatchcreate.com

Thursday, May 28, 2015

Redirect Url using IIS

Taken from https://support.microsoft.com/kb/324000

When you use Apache, you can redirect URLs by using the Redirect directive to point a folder or a location to a different folder on either the same Web site or a different Web site. You can also alias a folder to another location by using the Alias directive. If you use IIS, you can perform the same tasks by using the URL Redirection functionality.

To redirect a folder or file IIS:

  1. Log on to the Web server computer as an administrator.
  2. Click Start, point to Settings, and then click Control Panel.
  3. Double-click Administrative Tools, and then double click Internet Services Manager.
  4. Right-click the Web site or the folder, and then click Open.
  5. Right-click the folder display, point to New, and then click Folder.
  6. Return to Internet Services Manager.
  7. Right-click the folder that you just created, and then click Properties.
  8. Click the Directory tab, and then click A redirection to a URL.
  9. To redirect the folder to another URL, click the URL of the folder or the Web site that is described in step 4, and then type the complete URL to the new site in the Redirect to box.
  10. To redirect the folder to another folder within in this folder (for example, Projects to Sections/Departments/Projects), click A directory below this one, and then type the new folder in the Redirect to box.
  11. To mark the redirection type as a permanent redirection (and not a temporary redirection), click A permanent redirection for this resource
    If you use this setting, bookmarks and other details are automatically updated on some browsers.
  12. Click OK to save the changes.

Monday, May 18, 2015

ASP.NET Bootstrap Template Quickstart - Part 2: Using Email Address as UserName

When you first generate your application, the registration page insists on a UserName and Email Address from your clients, however it is more common to reduce the number of fields the user has to fill in as it increases registration.  The Email Address is much more valuable than the UserName as you can interact with it.

There are a couple changes you must make to use Email Address as the UserName:
  1. Change the UserName field to Email Address.
  2. In the control open tag you must add RequiresEmail=false
    If you forget to set this you will get the error message: 

    RegisterUser: CreateUserWizardStep.ContentTemplate does not contain an IEditableTextControl with ID Email for the e-mail, this is required if RequireEmail = true.

  3. Next you will want to add a validator to your username field to ensure it is in email format.  There are a few ways to do it.  You can use the RegEx Validator as a minimum or extend it to do a DNS lookup depending on your needs. Below is a sample I got from a StackOverflow article:

    <asp:RegularExpressionValidator ID="regexEmailValid" runat="server" ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" ControlToValidate="tbEmail" ErrorMessage="Invalid Email Format"></asp:RegularExpressionValidator>
If you have any tips, tricks or resources you would like to share with the guild email me at chris.williams@readwatchcreate.com

ASP.NET Bootstrap Template Quickstart - Part 1: Creating a new application

When you create your next project, choosing the WebForms application will do a lot more for you than previous versions. For example, you now get a solution built on Bootstrap, it uses friendly names for links eg. /About instead of /About.aspx. It provides you with two master pages: one for regular sites and one for mobile. To start using this template follow these steps:

  1. Open Visual Studio and choose to File -> New Project
  2. In the left panel Click on Visual C# -> Web -> Visual Studio 2012
  3. On the center panel choose ASP.NET Web Forms Application
  4. At the bottom choose where to put your project and give your project a name
Voila, you have yourself a great application to build on top of.  You can start applying your design and customization. 

In our followup articles we will cover some of the functional changes you may want to make to to this template to suit your needs.  

If you have any tips, tricks or resources you would like to share with the guild email me at chris.williams@readwatchcreate.com

Sunday, July 06, 2014

Cannot find Microsoft.Web.Administration.dll

If you are getting this error, the most likely cause is that you do not have IIS 7 installed on your computer.\
Here are the steps involved to install IIS 7 on Windows 8.1

Click on the start menu and type Control Panel. When the choices come up choose Control Panel

Click on Programs

Click on Turn Windows features on or off

Click on Internet Information Service and click OK

Windows will apply the changes.  Windows will tell you when its complete.  Click Close on the dialog.

You should now be able to reference the Microsoft.Web.Administration.dll

If you are getting started with IIS 7 and would like assistance getting started check out the ASP.NET IIS 7 QuickStart.

Sunday, April 13, 2014

Experience with version 4 of .Net (No version 1.5 or 2.0

I saw an odd job listing today it wanted someone with the following:
  • Experience with version 4 of .Net (No version 1.5 or 2);
I thought it was kind of odd.  Why do they prefer someone without 1.5 or 2.0 experience.  I did some Google and found a basic rundown of the differences.   The job post does not list WCF experience or LINQ or Entity Framework or MVC.

.Net 2.0
1.CLR Features
3.Other basic concepts

.Net 3.0

.Net 3.5 - Enhanced Feature of .Net 3.0

.Net 4.0 
2.Entity Framework

For more details you could always look through these but that is not really the point of my article.

.NET 4.0
.NET 3.5
.NET 2.0

At first I thought it was odd but then it clicked. This kind of reminds me of the article written by Ryan O'Connell about all the things you would have different opinions on.


So I am guessing that rather than a technology requirement in as much as its a personality requirement.  If you started with .NET 4.0 you don't know any of the sloppy hacks we had to do regarding stuff as simple as reading the config file.  Remember the including of a separate DLLto read the web.config in 2.0 as opposed to 1.1 having it native in the DLL.  I guess if you remember that you don't qualify for this job.

I look forward to hearing other your comments.  I know I would prefer someone who has been through the trenches than one who just arrived as a new private but that is just my opinion how about you.

If you have more insight then please email me at chris.williams@threepointturn.com or dennis.augustine@threepointturn.com

Are you a .NET Developer or Contractor interested in working with Sitecore or Dynamics CRM?

Apply for our Mentorship Program. If accepted, we will mentor you on Sitecore and provide you with project to help you build your skills and make some money at the same time. If you are interested send your resume with details on why you want to work with Sitecore or Dynamics CRM to: Chris Williams - chris.williams@techguilds.com or Dennis Augustine - dennis.augustine@techguilds.com We look forward to working with you to achieve your goals.