Deploying ServiceStack to IIS with a subdirectory

When deploying ServiceStack to a subdirectory (i.e. /Customer1/ServiceStack) what worked on your development and QA may all of a sudden not work here.  You’ll see an error like this:

Handler for Request not found:

Request.HttpMethod: GET
Request.HttpMethod: GET
Request.PathInfo: /Customer1/ServiceStack
Request.QueryString:
Request.RawUrl: /Customer1/ServiceStack

The solution is to add the following code:

SetConfig(new EndpointHostConfig
{
    ServiceStackHandlerFactoryPath = "ServiceStack", // change "ServiceStack" to your directory name such as "api"...etc
});

I found this solution here
Posted in Uncategorized

Entity Framework: Unknown column innerexception

When working with Entity Framework dbsets and using a generic repository pattern, in your repository base class you may have methods such as:

public virtual IEnumerable<T> GetAll()

and in these functions access “dbset” objects.  If you get an error that says your particular dbset contains an unknown column, it may be that another dbset object defines a virtual reference to the object complaining.

Example Problem:

Class User

Class Profile

You may get an error when doing a UserRespository.GetAll() call and the innerexception may say something like “Profile_ID not a part of User”.  Then you search your User class only to find that there is no mention of Profile_ID nor any reference to Profile!

Solution:  But when you peak inside of the Profile object, you’ll find a virtual parameter of type User.  This will automatically generate a new parameter in the User object and since it doesn’t exist in the database table, you get the exception.

public virtual ICollection<User> Users { get; set; }

Either remove the reference from Profile (in this case) or add a foreign key relationship in your database in the User table that links to Profile.

Posted in Uncategorized

XCode won’t open – The Mac OS X platform is missing – cannot set a default platform: XCPlatformSpecification –

If you get this error and cannot open XCode or cannot open XCode normally, follow this process:

1. Download AppCleaner app – https://www.macupdate.com/app/mac/25276/appcleaner

2. Open AppCleaner

3. Drag your XCode app form the Applications folder into the AppCleaner app.

VERY IMPORTANT: Do NOT click “delete” or uninstall XCode!

4. Look at the list of .plist files that are associated with XCode and make a list of all the directories the plist files exist: (i.e. ~/Library/Preferences)

XCode plist AppCleaner

5. Go to each directory and find the files listed in AppCleaner and see which files have been updated since the time you have not been able to open XCode.

6. Delete them one-by-one, most recently updated first and open XCode after each deletion to determine if that is the plist file causing issues.

Good luck and let me know if it works or if you have questions!

Posted in coding, iOS

AutoMapper and System.NullReferenceException: Object reference not set to an instance of an object.

Advice on dealing with strange errors (in general):

What’s the difference between the following lines of code (1 vs 3&4)?

Code Snippet
  1. dtoList.Add(AutoMapper.Mapper.Map<Model.example, Dto.example>(example));
  2. var dtoExample = AutoMapper.Mapper.Map<Model.example, Dto.example>(example);
  3. dtoList.Add(dtoExample);

Answer: Potentially many hours of hair pulling and frustration. By combining the two lines of code into one (line 1) it appears as though the error “System.NullReferenceException: Object reference not set to an instance of an object.” is coming from AutoMapper. By separating the the code into two lines it is not only readable, but easier to debug. The error will NOT occur on line 3 thereby ruling out AutoMapper and will occur on line 4, because the dtoLists object was not instantiated and therefore is null. You cannot add something to a null object.

Posted in Uncategorized

Resetting Entity Framework 5 code first migrations

Working with a messed up DB that had been manually modified while using Entity Framework 5 code first approach is not fun. Not only that, but the migrations had been deleted from the project and from the Migrations History table AND the production database and staging database had not been updated so it was out of sync. What to do while retaining the data?

1. Make a complete backup of your product database and copy it to your dev environment.
2. Restore production db in dev under a new name
3. Compare the dev and production db to note the differences (Redgate can help)
4. Change the web.config and connection strings to point to the new production duplicated db in your dev environment
[ Using the new production db copy in your dev environment]
4. Enable Entity Migrations (if necessary)
5. Run an Add-Migrations – the code generated will re-add all of the tables. Comment out all of the tables that you already have in both the up and down
6. Using the differences found in step 3, manually add code that adds the missing database fields. You shouldn’t need to add complete tables as you can leave those uncommented from those generated in step 5
7. Run update-database
8. Run your app (again pointing to the new production db copy that was just updated) and ensure everything works
9. Push to staging/qa/production as you follow your standard release processes and everything should work!

Posted in Uncategorized

Entity Framework 5 Codefirst and C# – context commit doesn’t show in the database

For those of you who are using Entity Framework codefirst and are experiencing the perplexing issue where all of the code runs without any exceptions and your context’s Commit() is called, but you look in your database and don’t see any changes or the results you’re looking for, think back if there have been any manual updates to the database. If you update a table manually and outside of “Add-Migration” and “Update-Database” then it can mess up the context and prevent any data changes.

The solution was to remove the relevant migrations for that table from the Migrations folder AND from __MigrationHistory table, remove the table from the DB and then rerun “Add-Migration” / “Update-Migration” combo. What I didn’t try, but may have worked is making some change to that table’s model running “Add-Migration” / “Upgrade-Migration” again after the manual change to the table. I was at a stage where it was a brand new table, but if you already have data in the table my solution won’t work for you. Try the second method and let me know.

A second reason for code running fine without exceptions, but no data showing is if the data being sent is “out of range” or a similar data issue. Here’s an error I received recently, “The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.” A date value as a string was all zeros and the SQL Server 2008 R2 database did not like that and rejected the entire record, so nothing showed. The solution was to put more strict checks on the data being sent to see if it was out of bounds.

For valid SQL DateTime values I use this:

Code Snippet
  1. private DateTime getValidSqlDate(DateTime date)
  2. {
  3.     if (date < (DateTime)SqlDateTime.MinValue)
  4.     {
  5.         return (DateTime)SqlDateTime.MinValue;
  6.     }
  7.     else if (date > (DateTime)SqlDateTime.MaxValue)
  8.     {
  9.         return (DateTime)SqlDateTime.MaxValue;
  10.     }
  11.     else
  12.     {
  13.         return date;
  14.     }
  15. }
Posted in api, asp.net, coding

EFMVC error updating and solution

I was attempting to update a record using EFMVCs default “Update()” function from EFMVC and came across the following error:

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

The solution was to rewrite the Update function as such:

Code Snippet
  1. publicvirtualvoid Update(T entity)
  2. {
  3.     if (entity == null)
  4.     {
  5.         thrownewArgumentException(“Cannot add a null entity.”);
  6.     }
  7.     var entry = dataContext.Entry<T>(entity);
  8.     if (entry.State == EntityState.Detached)
  9.     {
  10.         var set = dataContext.Set<T>();
  11.         string keyName = dbset.Create().GetType().GetProperties().Single(p => p.GetCustomAttributes(typeof(KeyAttribute), false).Count() > 0).Name;
  12.         var pkey = dbset.Create().GetType().GetProperty(keyName).GetValue(entity);
  13.         T attachedEntity = set.Find(pkey);  
  14.         if (attachedEntity != null)
  15.         {
  16.             var attachedEntry = dataContext.Entry(attachedEntity);
  17.             attachedEntry.CurrentValues.SetValues(entity);
  18.         }
  19.         else
  20.         {
  21.             entry.State = EntityState.Modified;
  22.         }
  23.     }
  24.     // ORIGINAL CODE
  25.     //dbset.Attach(entity);
  26.     //dataContext.Entry(entity).State = EntityState.Modified;
  27. }

I took the advice of this post:
http://stackoverflow.com/questions/12585664/an-object-with-the-same-key-already-exists-in-the-objectstatemanager-the-object

but it required changing a bit more code than I wanted (adding an interface to each entity), so I added the following code to find the primary key of an entity

Code Snippet
  1. string keyName = dbset.Create().GetType().GetProperties().Single(p => p.GetCustomAttributes(typeof(KeyAttribute), false).Count() > 0).Name;
  2. var pkey = dbset.Create().GetType().GetProperty(keyName).GetValue(entity);

In the future, I’ll add some more logic for when entities do NOT have primary keys, but for my architecture all tables will.

Posted in api, asp.net, coding

LinkedIn API authentication problems with same & different browsers

LinkedInAuthentication (C# sample application for LinkedIn OAuth2.0 – Requires you to add NewtonSoft JSON)

Quite a frustrating issue, today, but the solution is straight forward…

Problem:  When using Chrome (Firefox too?) and logging into LinkedIn directly, THEN going to your app that requests LinkedIn credentials, also in Chrome, when my app sends the user to LinkedIn’s auth URL (oAuth2) it automatically redirects back to your callback without any user login required and the authorization code is right there.  The problem is that code returned was not valid and would return a 400 bad request from LinkedIn when I tried getting an authentication token using that authorization code.

NOTE:  If you use a different browser to log into LinkedIn and using your app, that behavior doesn’t occur.  It requires the user to log in.

 

Solution:  I had to go into my LinkedIn account used for authenticating on my app and remove authorization in my applications settings.  This is done by going to your profile settings, then “Groups, Companies, & Applications” and then clicking on view applications.  I then checked my app’s name and clicked remove.  The next time I tried the scenario of being logged into LinkedIn in Chrome and then granting access to to my app, also in Chrome, the same behavior of being automatically redirected to my callback without any logging in occurred, however the authorization code was usable and did not return that 400 bad request.  Everything went well after this.

 

Take-away:  My theory is that the authorization in my account that I had to remove was an “old” authorization and the code had changed since then.  By removing it and recreating that authorization it was current with my code.  Now, if this is true, what will happen when I update my code in the future?  I can’t ask all users to remove their authentication every time I upgrade.  I’ll keep an eye on this.

Posted in api, asp.net, coding, integration

LinkedIn API and ASP.NET C# adventures

Continuing with integrating LinkedIn with my ASP.NET C# app, I came across a few difficulties.

1. Some browsers block popups differently than others.

Doing development in IE (because it’s better integrated with VS 2012) and doing so on an IIS server on “localhost” doesn’t always give you the same results as when you push to Staging or Production. Case in point, having a popup window for users to log into their LinkedIn account worked well on IE, but failed once it was on staging and with Chrome and FireFox. The solution was to take the popup window outside of the AJAX call and make it a direct “window.open” call from “onclick”.

2. Here’s how I handle whether the user clicked cancel at the LinkedIn authorization page or they actually logged in.

Code Snippet
  1.  <scripttype=”text/javascript”>
  2.      function getURLParameter(name) {
  3.          return decodeURI(
  4.              (RegExp(name + ‘=’ + ‘(.+?)(&|$)’).exec(location.search) || [, null])[1]
  5.          );
  6.      }
  7.     $(document).ready(function () {
  8.         var error = getURLParameter(‘error’);
  9.         if (error.indexOf(“null”, 0) != -1) {
  10.             window.opener.linkedInToken = getURLParameter(‘code’);
  11.         }
  12.         window.close();    
  13.     });
  14. </script>

3. When users are logged into their LinkedIn account and you send a user to the linked in auth page, it may automatically detect the user is logged in and send you back immediately to the callback URL you provided. It’s important to handle this case in your logic.

4. oAuth 2 is a million times better than oAuth 1a and storing the user’s access token in your DB makes the process of interacting with LinkedIn much more seamless for your users. If you’re struggling with how to handle JSON returned from LinkedIn, copy the json and paste it into this tool which will auto generate C# classes for your JSON. Then you can use JSON.net to convert LinkedIn JSON to your custom classes.

Convert JSON to C# classes

 

Posted in Uncategorized

Using Wufoo API with ASP.NET C#

I’ve just completed my basic Proof of Concept project for accessing the Wufoo API via ASP.NET C#.  I’m including the project here so others can hopefully get off the ground quicker with similar projects.  Here’s the basic code:

Wufoo C# Proof of Concept Source Code

Code Snippet
  1. string wufooAPIKey = "YOUR API KEY";
  2.  
  3.  
  4. // https://fishbowl.wufoo.com/api/v3/users.json
  5. StringBuilder url = new StringBuilder();
  6. url.Append("https://YOURSUBDOMAIN.wufoo.com/api/v3/users.json");
  7. HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url.ToString());
  8. string authInfo = wufooAPIKey + ":" + "footastic";
  9. authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
  10. request.Headers["Authorization"] = "Basic " + authInfo;
  11.  
  12. using (var webResponse = (HttpWebResponse)request.GetResponse())
  13. {
  14.  
  15.     using (var reader = new StreamReader(webResponse.GetResponseStream()))
  16.     {
  17.         var objText = reader.ReadToEnd();
  18.         WufooUserJSON deserializedProduct = JsonConvert.DeserializeObject<WufooUserJSON>(objText);
  19.     }
  20.  
  21. }

And the JSON classes for the User REST service:

Code Snippet
  1. public class WuFooUser
  2. {
  3.     public string User { get; set; }
  4.     public string Email { get; set; }
  5.     public string TimeZone { get; set; }
  6.     public string Company { get; set; }
  7.     public string IsAccountOwner { get; set; }
  8.     public string CreateForms { get; set; }
  9.     public string CreateReports { get; set; }
  10.     public string CreateThemes { get; set; }
  11.     public string AdminAccess { get; set; }
  12.     public string Image { get; set; }
  13.     public string ApiKey { get; set; }
  14.     public string LinkForms { get; set; }
  15.     public string LinkReports { get; set; }
  16.     public string Hash { get; set; }
  17.     public string ImageUrlBig { get; set; }
  18.     public string ImageUrlSmall { get; set; }
  19.     public string HttpsEnabled { get; set; }
  20. }
  21.  
  22. public class WufooUserJSON
  23. {
  24.     public List<WuFooUser> Users { get; set; }
  25. }

Requirements:

Newtonsoft JSON

Posted in api, asp.net, coding, integration