Friday, December 28, 2012

Getting Started With Entity Framework 4.3.1

Introduction
Entity Framework (EF) has evolved quite a bit and as it has evolved it has become more and more confusing to keep up with its changes which have been introduced a series of addons in the form of libraries. You can sit down and read pages of documentation to understand what has happened, but when you just need to dive into something because of time constraints it is frustrating. That has led me to ask the question "How do I install and use EF 4.3.1?" Well unfortunately it is not a one click install, it is a multi-step installation.

Assumptions
  • You are using Visual Studio 2010
  • You are using the .Net 4.0 Framework
  • You need to either create a new EDMX or you have an existing EDMX using the stock version of EF that comes with .Net 4.0 and VS2010 which is EF 4.0
  • You are using the database first method (versus code first method)
  • You have NuGet installed (this is required)
  • You have made a backup of your project before continuing (just in case things go sideways)
Can I used EF 5.0 instead?
If you are using Visual Studio 2010 (VS2010), then the answer is NO. EF 5.0 is supported in Visual Studio 2012 (VS2012) for .Net 4.5, if you have access to VS2012 then I say go for it. I haven't had a chance to move on yet myself.

Part A: Setting up a Project with an EDMX file
  1. If you don't already have an EDMX file, then either create a new project or use an existing one, and add a new item to your project (Right click on project file > Add > New Item...)
  2. Under "Installed Templates" (left hand side) select "Data" and then select ADO.Net Entity Data Model - name it however you see fit. Example: InventoryModel.edmx
  3. Follow the wizard and setup your edmx as you would normally - add which ever tables you need etc...
  4. After you have finished adding your edmx, it is time to install EF 4.3.1
Step 1

Step 2-4

Part B: Installing EF 4.3.1
Reminder: You must have NuGet installed to perform these steps
  1. Open up the NuGet Package Manager Console: Tools > Library Package Manager > Package Manager Console
  2. Make sure you have the correct project selected and at the command prompt enter the following command sans soft quotes: "Install-Package EntityFramework -Version 4.3.1" Where did you find this command? After pressing the enter key a bunch of stuff happens. Some of that stuff is a dll named "EntityFramework" is added a dll reference to your project. If you haven't used NuGet before then don't be alarmed by the config file named "packages.config", that is added when adding packages using NuGet.

Step 1

Step 2

Verification 1

Verification 2
Part C: Using EF 4.3.1 and a DBConext Generator of your Choosing
Say hello to the System.Data.Entity.DBContext Pattern, this is essentially what you have enabled yourself to use by installing EF 4.3.1, there are a number of new properties and awesome methods that have been added to the DBContext pattern. You are switching over from the System.Data.Objects.ObjectContext pattern which comes stock with EF 4.0 in VS2010.

Context Generators
You should use the right context generator for the job and each context generator has its own quirks. Really the defining line in my opinion on which context generator to use is by asking yourself, "Do I need to have an SOA or am I going to use WCF?" If the answer is yes, then you want to use a context generator with WCF support. If the answer is no, or you don't mind writing your own translation layer (converting your entities to POCO manually) then you can just use the regular DbContext Generator.

For argument's sake, we are going to use the DbContext Generator since it is basically the next step up from the original ObjectContext generator. It will not generate serializable objects, so don't bother with it for WCF.
  1. Add a new Code Generation Item by opening your EDMX file > right click on blank space > select "Add Code Generation Item..."
  2. Click on Online Templates located on the lower left hand side of the left pane.
  3. Click on "EF 4.x DbContext Generator for C#"
  4. Name it something different from your EDMX, like "DummyDBCModel.tt"
  5. Press the Add button - automatically this model will generate one file per entity and your old ObjectContext will no longer be valid. You will now have to use the new DbContext for any existing code (if you had any).

Step 1

Step 2-5
What Now?
You are probably thinking, "Okay great, I upgraded from 4.0 to 4.3.1, but what can I do that I couldn't do before?", well right off the bat there are two very useful things that I can name. There is now a Database Property, that will easily allow you to get your connection string, not too exciting, but not bad either. The second and most valuable thing in my opinion is the ability to selectively update fields/properties/columns when making an update to an entity.

I Upgraded and Everything is Broken Now!
If you were upgrading an existing project from EF 4.0 to 4.3.1, then yes, there is a good chance a lot of your code will be broken because the 4.0 syntax is different from the 4.3.1 syntax, but the idea remains the same it is still an ORM. For example in 4.0 using the ObjectContext to do an insert into a collection of Books you would write: context.Books.AddObject(book); but in 4.3.1 using the DBContext you will write context.Books.Add(book); - not a major difference, just syntactically different.

Useful Code Snippets
Here are some useful code snippets, specifically extension methods, for stuff you are probably going to do one way or another.

Code
using System.Data.Entity;
using System.Data.Entity.Infrastructure;

/// <summary>
/// Get the connection string from the provided DbContext
/// </summary>
/// <param name="context">the target context</param>
/// <returns>the connection string this context is using</returns>
public static string GetConnectionString(this DbContext context)
{
 return context.Database.Connection.ConnectionString;
}

/// <summary>
/// Insert the entity of type T into the appropriate entity collection of type T
/// </summary>
/// <typeparam name="T">an entity of type T</typeparam>
/// <param name="context"></param>
/// <param name="entityObject">an entity of type T</param>
public static void Insert<T>(this DbContext context, T entityObject) where T : class
{
 context.Set<T>().Add(entityObject);
 context.SaveChanges();
}

/// <summary>
/// Update an entity of type T and only update the specified properties
/// </summary>
/// <typeparam name="T">an entity of type T</typeparam>
/// <param name="context"></param>
/// <param name="entityObject">an entity of type T</param>
/// <param name="properties">a strict list of properties to update</param>
public static void Update<T>(this DbContext context, T entityObject, params string[] properties) where T : class
{
 context.Set<T>().Attach(entityObject); //Attach to the context

 var entry = context.Entry(entityObject); //Get the Entry for this entity

 //Mark each property provided as modified. All properties are initially 
 //assumed to be false - further more properties cannot be marked as false, 
 //this is sadly a limitation of EF 4.3.1
 foreach (string name in properties)
  entry.Property(name).IsModified = true;

 context.SaveChanges();
}

/// <summary>
/// Mark an entity of type T as deleted. This is lazy deletion aka soft deletion. This method should only be used
/// if the entity has a Boolean Property named "Deleted".
/// </summary>
/// <typeparam name="T">an entity of type T</typeparam>
/// <param name="context"></param>
/// <param name="entityObject">an entity of type T</param>
public static void SoftDelete<T>(this DbContext context, T entityObject) where T : class
{
 //This method is the equivalent of setting the "Deleted" property to true and saving changes. 
 //Essentially this is a single property update.
 context.Set<T>().Attach(entityObject);

 var entry = context.Entry(entityObject);
 
 DbPropertyEntry p = entry.Property("Deleted");

 p.CurrentValue = true; //Mark this as deleted
 p.IsModified = true; //Mark this as modified

 context.SaveChanges();
}

/// <summary>
/// Permanently delete/remove an entity of Type T from it's corresponding entity collection.
/// </summary>
/// <typeparam name="T">an entity of type T</typeparam>
/// <param name="context"></param>
/// <param name="entityObject">an entity of type T</param>
public static void HardDelete<T>(this DbContext context, T entityObject) where T : class
{
 context.Set<T>().Attach(entityObject);
 context.Set<T>().Remove(entityObject);
 context.SaveChanges();
}

Usage Examples
using (TestDumpEntities context = new TestDumpEntities())
{
 Book obj = new Book();

 context.Insert(obj);

 obj.AuthorID = 10;
 obj.BookName = "A Walk in the Life of Foo";

 //Only update BookName, even though AuthorID was modified too.
 context.Update(obj, "BookName");

 context.SoftDelete(obj); //Set obj.Delete = true and update in the DB

 context.HardDelete(obj); //Complete remove this entity from the DB

 Console.WriteLine(context.GetConnectionString()); //Print out the connection string
}

DbContext Generator with WCF Support
If you require WCF support, then I strongly suggest using the DBContext Generator with WCF Support as opposed to the POCO generator. The classes that are generated are lightweight, so much so that you lose a little bit of functionality unfortunately. With the regular DbContext Generator when you load an entity, any relational properties (collections of other entities related by Foreign Key), those relational properties are loaded for you. With the DbContext Generator with WCF Support, those relational properties are not loaded for you, you have to explicitly state that you want them loaded in your lambda expressions or linq queries.

How to Explicitly Load a Relational Property
For demonstration purposes, let's say we have a Author and Book entities. Authors write multiple Books and therefore the Author Entity has a List<Book> property named Books. (Author.Books) - this is done in the database by taking the Author's Primary Key (PK) AuthorID and placing it as a Foreign Key (FK) in the Book table, also named AuthorID. An explicit FK relationship is created in the DB. This is construed as a Relational Property automatically by EF when generating the entities for the model. If you do not explicitly load the this property it will be empty. Therefore to achieve this do the following:

using System.Data.Entity;
using System.Linq;

//Example of returning a list of Author and loading each Author's Books property with their Books
using (TestDumpEntities context = new TestDumpEntities())
{
 return context.Authors
      .Where(x => x.AuthorID == 1)
      .Include(x => x.Books) //This will load your books for you
      .ToList();
}

Enjoy

Saturday, December 8, 2012

Sprinkler System Pump Assembly Demystified

Background
You are probably wondering to yourself - why the hell are you posting this? Trust me - there are like no articles about this on the net that I could find when I needed them, so I am going to fix that right now. Putting in a sprinkler system pump is not nearly as easy as it sounds, especially when every guide you find on the net assumes that you are using a lake or a city line as your water supply. Well I have a well, that is my water source, I couldn't find any info on this. Now that I have the experience I want to share it with who ever is looking for it.

Assumptions
  • I am assuming you have trenched your sprinkler system's lines already, you just need to install your sprinkler pump next to the well's spigot (outlet or water source). For this example, I am going to assume two zones, if you have more zones, that's fine - you just need to get yourself the appropriate indexing valve.
  • I am assuming you are using a centrifugal pump.
  • I am assuming you are using a well or body of water as your water source and not a city connection. City connections do not generally require pumps since they have enough pressure - they usually only require a relay/solenoid assembly.
  • I am assuming that you have had an electrician connect your timer at the appropriate voltage and amperage specifications. Pumps generally run at 120 VAC @ 20 A or 220 VAC @ 10 A. You must choose which configuration you want so that you can purchase a timer that can support it. Remember your timer must support the peak amperes specified by the pump otherwise you will burn out the timer.
Considerations
Make sure to draw out your design and take measurements between all points. That means measure between your well spigot and the pump and measure between the pump and where the indexing valve is or will end up.

Two Zone Cam for Four Zone Indexing Valve Gotcha
If you are going to use a four zone indexing valve for only two zones, make sure to purchase the indexing valve before placing the zone pipes so you can plan where those pipes will go; because the configuration of the two zone cam for the indexing valve will assume two of the exit points on the indexing valve (gotcha!). You are stuck with it unless you modify the cam (like I did) which I do not recommend! It is a total pain in the ass and I learned this the hard way. Planning is key here!

Part's List
This is the list of parts I needed, depending on your configuration, you might need something different - but most of these are necessary for all installations.
  1. PVC pipe typically 1-1/2" Schedule 40
  2. Check Flow Valve that has threads to fit 1-1/2" threaded couplers
  3. Threaded couplers 1-1/2" for all points that are not going to be glued.
  4. Teflon Tape (Blue Cap for liquid such as water - NOT THE RED ONE THAT IS FOR GASES ONLY)
  5. Pipe Thread Sealant (Tube of Yellow Goo)
  6. PVC Primer (bad smelling purple stuff)
  7. PVC Cement (clear goo that melts/fuses PVC together)
  8. Gloves (Latex, Nitryle etc...thin enough for grip) for when dealing with the PVC Primer and Cement, you do NOT want this shit on your hands, trust me. It is quite corrosive and will stain your skin and anything else it touches.
  9. Pressure Gauge for your pump and any sizing (up or down) adapters required
  10. Ball or Gate Valve for maintenance and for switching zones on the fly
  11. Indexing valve (4 zones in this example) which is not 100% required, this is only if you are going to use a timer or if you want to change zones a little easier. The alternative is to make a solid connection using a Tee fitting. You can control your zones manually using additional ball/gate valves.
  12. Two 3/4" Valve, one for the well and one for the pump. This is for priming your well and your pump.
  13. Any other parts to get the job done, couplers etc... Maybe some concrete blocks (8x4x16) for the pump to sit on.
  14. Tools you will need:
    • A. Hack Saw, fine tooth blade (metal blade)
    • B. Reciprocating Saw or equivalent - fine tooth blade (metal blade)
    • C. Pipe wrench (and a rag to cover the PVC with to avoid scratching it)
    • D. Knife or box knife
    • E. Crescent Wrench  
    • F. PVC Pipe Cutter (Not necessary - hack saw works just fine)
    • G. Reamer (Not necessary - you can use an old T-Shirt or Rag to remove the rough edges of the pipe after cutting it)
    • H. Other tools to get the job done that you might require.
General Instructions
I could bother with how to assemble everything, but I am not going to because every configuration is different. Instead I am going to just describe general dos and don'ts.
  • Use Teflon tape and pipe sealer on top of the Teflon tape for all threaded ends. If you don't, you will have air leaks which really will just ruin the whole assembly as air leaks will kill your water pressure.
  • Use Teflon tape and pipe sealer on the PVC threaded fittings also. It isn't just for the metal threads.
  • Take extra special care when tightening PVC threaded fittings (male end) into metal threaded openings (female end). If you over tighten it, you will crack it and you will want to kill yourself...
  • When cutting your PVC, it is better to go longer, than shorter if you are not sure. You can trim as needed with a hack saw or a PVC pipe cutter.
  • Make sure you buy the right size check valve - if you are decreasing the size of your pipe with a coupler so that your check valve will fit, then you have the wrong size check valve.
  • Keep your pipe sizes consistent - do not decrease or increase sizes unless you absolutely need to. Your system should utilize the same size everywhere.
  • Make 100% sure the check valve is pointing in the correct direction. The angled/beveled end should pointing towards the pump - there are arrows indicating the direction of the flow. You want it to flow into the pump. The check valve prevents back flow so you do not have to prime your pump or the well more than once if everything is done correctly.
  • Make sure to close all valves during operation and cap them off with valve caps to prevent contamination or air from leaking into the line.
  • You can use the gate/ball valve to change zones while the pump is running. To do this, just close the gate valve and open it again. This action will change zones.
  • If when you turn on your pump - no water is flowing - make sure you have the correct cam installed in the indexing valve and that you have connected your zone pipes to the correct zone outlets of the indexing valve. THE ZONE OUTLETS ON THE INDEXING VALVE ARE NOT ARBITRARY THEY ARE FIXED! I made this mistake and I had to hack/retrofit my 2 zone cam to force it to use zones 3 and 4 instead of zones 1 and 2 as the cam and indexer intended. Do not make this mistake!
  • When ready - build a box/home for your pump assembly to keep it out of the sun. The sun (and other weather) will destroy your assembly quickly because plastic does not like heat. I built mine out of 2"x2"x10' pieces of wood for framing and 3/4" pressure treated plywood for the paneling. Make sure to leave your box out in the elements unpainted for about 60-90 days. Then sand, prime and paint it to avoid cracking.
Pictures
This is the most important part - it is the visual aid which I could not find anywhere online. Depicted below is my pump's configuration. These are only the highlights, but I do have more pictures located in my picasa web album. The pictures are large, I did that on purpose for detail.

Plenty of pictures in this album - all large pictures.
Sprinkler System Centrifugal Pump Configuration

System break down

Make sure that check valve is going in the right direction

Pressure gauge with 2 adapters to make it work.

Make shift plugs for the unused zones

Showing my screw up with the indexing
valve configuration and the  zone cams

Tuesday, November 13, 2012

How to Uninstall CollabNet Desktop Version 3.1.2.0

What is CollabNet?
CollabNet is a site that has a lot of nice almost free tools for you to use in a variety of places. I happen to use AnkSVN which is a plug in for Visual Studio that allows you to use the Pending Changes window to submit (check-in) recent changes and notes directly into your SVN instance. CollabNet also has their own Subversion (SVN) instance which I have been using at home and it is very nice. All of this stuff is free if you sign up for an account and basically deal with the spam that you get from them in your inbox. Not a big deal.

There is one program in particular that I don't use called CollabNet Desktop, there is nothing wrong with it I just don't need to use it.

The Gotcha
I had CollabNet Desktop Version 3.1.2.0 installed and I couldn't uninstall it. I tried using the regular old "Control Panel\Programs\Programs and Features" to try to uninstall it and it didn't show up in the list. I wanted to just delete the files (which isn't a good idea), but I wasn't too sure where they were living because I use AnkSVN too, so I didn't want to damage that installation. Visual Studio didn't have any way to disable it or uninstall it either. What do you do now?

The Work Around (Fix?)
This is going to sound stupid but:

  1. Install the latest version
  2. Then uninstall what you just installed

I have done this before for similar situations. This will usually work because you can hope that the next version will put an entry into your "Programs and Features" list. Now you never have to see this box pop up ever again:
Every time I would load Visual Studio this would pop up

Well that was easy...

Thursday, November 8, 2012

SSRS Report Viewer Control Broken Image Below Lines - Missing URL parameter: IterationId

I know it is unreasonable for me to say this but AXD files and anything that has to do with them scares me. I say this because if something goes wrong with them usually you can't do anything about it, it is part of the magic of Ajax and ASP.Net that you are not supposed to concern yourself with and you can't usually fix even if you wanted to. It is like a black box that always works, and when said black box stops working you are just left in a state of utter helplessness asking yourself "Well what do I do now?!"

Well this is the first time I have been able to find a work around for an AXD related issue.

The Setup
You run a report in a web application using the SSRS Report Viewer Control and unexpectedly to you you see a broken image icon under a horizontal line in your report (if you put one there, not sure if this happens any other time).

I originally thought this was because of my Sub Report, but it is the line I placed above it.

The Investigation
What was particularly irritating about this, is this only happens when I use Chrome! I am not sure why. So I right clicked on the broken image icon and selected Open image in a new tab.


I was presented with a nice Yellow Screen of Death as shown below.


The Experiment
I am a big believer in playing around with things that are broken already, it's not like you are going to make it worse especially when it is the black box that is blowing up. So it is complaining that it doesn't have an IterationId as a parameter in its QSP (Query String Parameters) right? Okay well add the #@$@ thing then. Why the hell isn't it there to begin with, damn you black box must I do everything around here?

If it is missing, then add it!
So I simply added "&IterationId=0" to the end of the URL's QSP

Yahtzee!
I pressed enter to refresh the page and blammo blank page which is what we want, we don't want that stupid broken image icon (why the hell is that there anyhow?).

Here is what the URL looks like:
http://localhost/CMApp2/Reserved.ReportViewerWebControl.axd?ReportSession=3jix0j33jora41z330kzhw45&Culture=1033&CultureOverrides=True&UICulture=1033&UICultureOverrides=True&ReportStack=1&ControlID=8daa5ebd5e88473bbeab2fbf71ac40af&OpType=ReportImage&ResourceStreamID=Blank.gif

Notice it is missing the IterationId parameter

The Stupid Fix to the Stupid Problem
Okay well we just proved that this can be fixed just by giving the beast what it wants, it wants its binky, so we gave it its binky. "But how do we do that programmatically without causing issues?" Well it is easy actually, I was searching for all of this nonsense on google and I couldn't find an answer to my problem in particular, I kept finding a similar issue about a "Blue Coat" which had a decent solution or a work around rather that I am using to fix this problem too (all credits and resources at the bottom).

In order to fix this problem we want to re-write the request every time, but only for chrome browsers and only in this particular case. Here are the steps:

  1. Go to your Global.asax code behind
  2. Add the following code snippet and add any other customization you might want to add.

void Application_BeginRequest(object sender, EventArgs e)
{
 //The following code is a hack for stopping a broken image from magically appearing on SSRS reports in chrome
 //where ever a line is used in the report.
 Uri u = HttpContext.Current.Request.Url;

 //If the request is from a Chrome browser 
 //AND a report is being generated 
 //AND there is no QSP entry named "IterationId"
 if (HttpContext.Current.Request.Browser.Browser.ToLower().Contains("chrome") &&
  u.AbsolutePath.ToLower().Contains("reserved.reportviewerwebcontrol.axd") &&
  !u.Query.ToLower().Contains("iterationid"))
  HttpContext.Current.RewritePath(u.PathAndQuery + "&IterationId=0");
}

Run your code and viola, the broken image icon goes the hell away. Warning: I can't guarantee this won't introduce problems because I just solved this today, but hey, this is a good place to start.

Google Fu Results
https://www.google.com/search?q=Missing+URL+parameter%3A+IterationId - main search result
http://www.networksteve.com/enterprise/topic.php?TopicId=37516 - this exact article's complaint!
http://stackoverflow.com/questions/705359/reportviewer-missing-url-parameter-name - a similar complaint
http://forums.asp.net/t/1118527.aspx - a similar complaint
http://csharp-matt.blogspot.com/2010/06/effects-of-bluecoat-proxy-on-aspnet.html - blue coat stuff
http://social.msdn.microsoft.com/Forums/en-HK/sqlreportingservices/thread/b44a0452-d71a-4e69-b7e0-af74b9f6bde7 - this exact article's complaint with no answer
http://support.microsoft.com/kb/2120979 - the KB article with a supposed fix (I doubt it will work)
http://www.webdeveloper.com/forum/showthread.php?154780-Application_BeginRequest-in-Global.asax-not-working - URL Rewrite example

Wednesday, November 7, 2012

SSRS Logical Flaws of IIF

Déjà Vu
It isn't very often when I have to build reports for SSRS, it usually happens in bursts. I will write like 2-5 reports (sometimes more) and you always tend to find a bunch of shitty problems along the way, you tell yourself "Argh!!! I keep forgetting that it does that! I need to remember this!" Well I am having one of those moments again and this time I am writing it down. There is plenty of documentation on this, but I want to explicitly state the following:

IIF Is Logically Flawed
The IIF function is logically flawed in that it will evaluate both return conditions regardless of which path is chosen (true vs. false). Therefore if you are trying to prevent an exception from happening, usually arithmetic errors IE: Divide by Zero Errors or using a null value (Nothing in VB) for something that cannot take null, well IIF will screw you in this respect. This is best explained with an example:

Dividing by Zero Example
Let's say you are trying to compute the following simple equation: (x - y)/x, well right away we can see that if x is zero, then you have just earned yourself a divide by zero error. In SSRS that results in a #Error where you are expecting to see a value instead. Not very helpful, however, if it didn't pop-up already - your Error List at the bottom of your screen should pop-up and show you a warning.

More useful than #Error
This error reads:
Warning 1 [rsRuntimeErrorInExpression] The Value expression for the textrun ‘LatestCost2.Paragraphs[0].TextRuns[0]’ contains an error: Attempted to divide by zero.

Well the first thing you are thinking is "@#*&^$ the if statement failed! WTF!", well that is partially true pejorative remark. It did fail because it didn't meet your expectations, but it isn't an if statement, it is IIF statement which will evaluate both outcomes and choose the right path. I am sure there was a use for this at one point, but I would imagine by today's standards this is just a wasteful statement. It is great for constants! Just not so much on statements that have the potential to throw exceptions.

The Gotcha
Let's re-use the above equation (x - y)/x and let's say that expression looks like this:

'This will evaluate both outcomes and therefore will result in an exception
=IIF(Fields!x.Value) = 0, 0, (Fields!x.Value - Fields!y.Value)/Fields!x.Value)

As explained before this will result in an error if x is zero. The most straight forward (and more efficient) fix in my opinion is as follows:

The Fix
Write a function for your report. If you are unfamiliar with how to do so then follow these steps it is easy:
  1. Right click on a blank area of your report, NOT the report body (page) and select the Report Properties menu option. (Figure 1)
  2. Click on Code (Figure 2)
  3. Enter your Function using VB.Net syntax (I am not sure if everything is supported, play around).
  4. Press OK to save
  5. Go back to the expression that was giving you trouble and utilize your function like shown below:

Figure 1
Figure 2

Code Example
'Writing a function to take care of this annoyance
Public Function MyFunction(x As Decimal, y As Decimal) As Decimal
   If x = 0D Then
      Return 0D
   Else
      Return (x - y)/x
   End If
End Function

'Using the function in an expression
=Code.MyFunction(Fields!x.Value, Fields!y.Value)

Bonus Tip: If after changing your expression, your report generates without seeing #Error, but the stupid warning won't go away, even after a re-compile, close Visual Studio completely and open it again. That should fix it.

Sources
Like I said before, this has been solved and posted several times before. I just wanted to give a more in depth answer and explicit instructions on how to embed code in your report.

Enjoy

Friday, November 2, 2012

The attempt to connect to the report server failed. Check your connection information and that the report server is a compatible version. The request failed with HTTP status 404: Not Found.

Screenshot of Error in the Report Viewer
This error reads:
  • The attempt to connect to the report server failed. Check your connection information and that the report server is a compatible version.
    • The request failed with HTTP status 404: Not Found.

When I was searching for the cause of this error I was confused by the answer that I kept finding everywhere which was to start messing with host headers and the reporting server's configuration file. I found this to be a bit extreme since I knew that our (at work) SSRS instance is already in use by a report viewer in a desktop application. I am just trying to view the same set of reports in a web application instead.

Well it turns out I made a silly mistake, a gotcha if you will.

Gotcha
Make sure you are using the Web Service URL and not the Report Manager URL from your SSRS instance. Pretty obvious huh, but those URLs look similar at times. The next question is how do I find out what they are named if I don't know what they are called or I just want to double check? In order to answer this, you need access to the host machine where SSRS lives and you need to open up SQL Server 2008 R2 Reporting Services Configuration Manager.

Report Manager URL
You do not want to use this for your report viewer!

Web Service URL
You want to use this for your report viewer!
If this didn't answer your question, then maybe it really does have something to do with the host header and the reporting server's configuration.
http://social.msdn.microsoft.com/forums/en-US/sqlreportingservices/thread/530ed56d-7c84-4d13-8998-80a8bf142197/

I found my answer here for the record:
http://www.networksteve.com/enterprise/topic.php?TopicId=40367

Bonus Tip
If you add the ReportViewer control to your page and when you load the page it doesn't show up, then make sure you have set the Height and the Width of the control explicitly. By default it is as small as possible which makes it appear to be invisible (which is stupid in my opinion and not very helpful).

Using the control is pretty straight forward as you can see here.

Wednesday, October 24, 2012

How to Kill all Processes for a Specific Database

Usually you would just use the Activity Monitor like shown below...

The mundane repetition of right click each process and selecting
Kill Process becomes annoying after the n_th process. 
...buuuuut if you need to restore your Dev Database with fresh data, you need to kill all of the individual connections/processes before attempting a restore. Well when you are doing development work you can have over 10+ connections and using the Activity Monitor is very annoying to close all of them. Therefore I have come up with the following tSQL query:

SELECT
 dbid, 
 db_name(dbid) as DatabaseName,
 spid,
 KillStatement = 'KILL ' + CAST(spid AS varchar(10)) + '; '
FROM sys.sysprocesses
WHERE dbid = 15 -- Put your Databases ID here

The idea behind this query is to first find out what you database's ID is, enter the ID in the where clause and generate the KILL statements. Copy and paste the KILL statements and execute all of them at once. You will be warned about killing your own connection though like this:

Msg 6104, Level 16, State 1, Line 1
Cannot use KILL to kill your own process.

No worries though you can just kill that process in the Activity Monitor or just close the query window.

Enjoy

Friday, October 12, 2012

Worst Visual Studio 2010 Bug I Have Ever Seen

The Background
This bug was so bad I had to post about it. This is by far the WORST Visual Studio 2010 (VS2010, VS) bug I have ever seen in my life. No one likes bugs, but we can arguably say that some bugs are preferred over other if given the choice. So there are bugs that pretty much everyone has encountered such as random program shut downs. You are using it and then *poof* it is gone. Visual Studio 2003, 2008 and 2010 have all done that to me for one reason or another - it is just irritating, but much more than "#@$@% now I have to open all my crap up again!"

Well, I have found the mother of all visual studio bugs - the worst part is I don't know if it is limited to just my system or if anyone else can reproduce it. I know I can reproduce it, but trust me I don't want to. What I am about to uncover is going to sound ridiculous, but it is what happened:

Perfect Storm Conditions
My Conditions:
  • Visual Studio 2010
  • Web Application 
  • Web Application is hosted in IIS7 locally for testing
  • HTML Editor is Open for an ASPX file
Awakening the Beast
All I did, I kid you not, is write the following statement (click to view):


This reads:
<ItemTemplate>
 <asp:HyperLink ID="lnkAllocation" 
       NavigateUrl='<%# Bind("ClientID", "~/AllocationDetails.aspx?clientID={0}") Bind("AllocationID"), "&allocationID={0}" %>'
       runat="server"
       Text="Details" />
</ItemTemplate>

I don't want to get into what I was trying to accomplish because that is no excuse for what happens next.

The Horrific Symptoms
After copying and pasting that information in, Visual Studio 2010 froze for about 5 solid minutes. After that delightful event, I thought VS was just taking a crap like it does so often. No, it was much worse - after the 5 minutes it came back. "Okay..." I thought - that was weird. I try loading my site in my browser and nothing - just kept spinning. I thought maybe my cached IIS files were corrupted, so I cleared them out. Tried again.

This time I noticed that my whole PC was freezing up. I checked CPU usage, w3wp.exe (IIS7 Worker Process) was using 50% CPU on my 8 core machine. One of the cores was being maxed out, thrashed! That is horrifically bad. Still not understanding what happened. I restarted IIS, tried again, same problem.

I tried using IIS Express (formerly known as Casini). Same exactly behavior - the process named WebDev.WebServer40.EXE was now using 50% CPU, yay for CPU Thrashin!

What ever the hell it was that was causing this had everything to do with what I just pasted in. This partially makes sense - but holy shit - WHAT A BUG!

The Stupid Fix to the Stupid Problem
I deleted the code. The problem psudo went away. Every time I would paste something into VS, the whole IDE would hang for 5 minutes or more. I restarted VS and all was well at that point. Sadly, I could reproduce this behavior, because I needed to make sure what I just witnessed was real. I spent about 2 hours figuring this out because I couldn't get any work done until it was fixed. Talk about incentive.

The Gotcha
I have to do more research as to why this happened, but for now, all I can say is NEVER EVER try to bind two values to a single control's property! Microsoft should really fix this, but they probably won't - they are working on VS2012 - much like 2K won't fix the audio bugs for Bio Shock 2 because they are too busy working on DLC and new games. Not cool.

Thursday, October 11, 2012

The Bestest Office Chair Evar

My Ass Hurts
Are you looking for a new office chair because you hate how the one you sit in now hurts your ass after about 4 hours because the spongy crap they use in the chair is completely flattened out and is useless after about 6 months? Yeah me too!

My Ass No Longer Hurts
That's why I just spent too much money on an awesome office chair I use at work. My office chair doesn't have a cushion, it uses bungee cords to suspend my rear and my back.

I highly super strongly recommend this chair: http://www.cb2.com/studio-office-chair/f1138 (Euro Style Link: http://www.gotoeurostyle.com/prod_detail.asp?product_id=310)

UPDATE 2013.06.07: You can get this chair much much cheaper on Amazon - search for CB2 Bungee Chair, I bought another chair for me at work for $177. The company that manufacturers this chair is named Euro Style. Here is an example on Amazon.

CB2 Studio Office Chair
Two Hundred Dollars?!
Trust me it is worth the 200 bucks you are going to spend on it. I kid you not, I usually refuse to spend more than 25-50 dollars tops on an office chair, but the cheaper chairs all have the same problem, nice sturdy frame, but they are all usually very uncomfortable to sit in for about 10 hours.

Why do you sit in your chair for 10 hours? Are you crazy?
Why yes, I am crazy, I am what is called a programmer or developer and we are crazy. We sit for a living and we only use the muscles in our fingers and eyes for 8-20+ hours at a time non stop. Our brains fizzle out from time to time which is why it is nice to have a nice chair to sit on while we go into our brain dead states as we sip coffee. All joking aside, this chair rocks - it feels like you are sitting on nothing for the most part.

Monday, October 8, 2012

Simple Class Creator Published on Google Code

05/25/2014 UPDATE: I moved the code to a different project. I have made a number of changes since 2012.

11/14/2015 UPDATE: I moved my whole repository from GoogleCode to GitHub because GoogleCode shut down.

My Simple Class Creator is now available for download via SVN, click on the following link:
https://github.com/dyslexicanaboko/dyslexic-code/tree/master/SimpleClassCreator

Let Me Reiterate

Like I have explained before, this program is NOT intended to replace an ORM - the purpose of this program is to help people quickly model tables or queries (virtual tables) in a database. You can quickly create classes/objects for something you want to work with or manipulate without having to work with DataTables directly.

Realistically - who wants to write the basics of a class anymore - it is mundane annoying work. Hence why I wrote this program, I no longer write classes from scratch if they already exist in a table or as a query in the database.

Feel free to download or browse the code here:
https://github.com/dyslexicanaboko/dyslexic-code/tree/master/SimpleClassCreator

Features

  • Use either a Table Name or a Query to generate your code
  • Supports C# and VB.Net code generation
  • Supports WCF Attribute Tags
  • Choice of building out or using short hand for Properties - C# only
  • Choice of including a prefix for private class members - IE: _name vs. m_name
  • If you are generating this class from a single table then full starter CRUD is generated, otherwise just a generation method is created where a DataTable can be passed in and a List of your object is returned.

Why would I want to use this?

Well I don't know about you - but I hate writing class definitions, it is boring work. I also have to work in two languages, I use C# and VB.Net simultaneously so it helps to be able to generate either type of object from the same database without having to be dependent on a strict ORM. My templates are over simplified so nothing crazy is happening in the background, no contexts, the class generated is single tier POCO.

For the Potential Haters

For the people who want to tear apart my code because of my approach - don't bother me with your opinion because I don't care - I am serious. This is very simply for MODELING. So in other words if you don't like the approach DON'T USE IT. I will be upfront and say it is not efficient, but I don't care because this program is not running in a loop, it is running for less than a second to generate a class. I have saved hours of work by using this program and I am not tied down to an ORM.

Sunday, September 30, 2012

ObjectDataSource has no values to insert. Check that the 'values' dictionary contains values

The Gripe
"ObjectDataSource 'odsNameHere' has no values to insert. Check that the 'values' dictionary contains values"
This runtime error is quite confusing and obnoxious to say the least. You can't debug it the normal way because your code behind will not hit any breakpoints at all (or at least any relevant ones). At this point anyone would be quite upset, because the next question to yourself is, "@#$! Great! What the hell do I do now?"

The Gotcha
Unfortunately this error could have happened for any number of reasons, but the culprit that I find normally is that my aspx file where the Object Data Source's (ODS) target control (GridView, DetailView etc...) is located has an inappropriately used Bind(...) or Eval(...) method, or a Bound Field that must be turned into a Template Field for any variety of reasons.

The Short Answer
I can't say this will always be the solution, but the worst case scenario fix is to fully implement a Template Field for all fields and use Bind(...) for all of the sub templates.

Example:
<asp:TemplateField HeaderText="Name">
 <ItemTemplate>
  <asp:Label ID="lblName" runat="server" Text='<%# Bind("Name") %>'></asp:Label>
 </ItemTemplate>
 <EditItemTemplate>
  <asp:TextBox ID="txtName" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
 </EditItemTemplate>
 <InsertItemTemplate>
  <asp:TextBox ID="txtName" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
 </InsertItemTemplate>
</asp:TemplateField>

I would like to guarantee that this will always fix this problem, but I can't. So far in my experience though, this has worked. My ODS is linked directly to a business object and I let it handle all CRUD operations.

The Long Answer
This is a big can of worms to get into, essentially the problem is the usage of Bind(...), Eval(...) and missing template tags (Item, Edit, Insert, Footer, Header).

Bound Fields
Before jumping into all of this, I would just like to say that Bound Fields are great - but they are very limited. I like using Bound Fields initially when implementing something and later I generally turn them into Template Fields (using the WYSIWYG editor). Bound Fields are nice because they encapsulate all of the basic template views (Item, Edit, Insert). This is convenient until you decide you need to add formatting to your fields. So really, Bound Fields are only really good for Read Only data or very plain data - if everything is a text field for example.

Template Fields
Template Fields are great because they give you a lot of flexibility to design exactly how you want your fields to look in all scenarios. They do have very silly limitations, such as adding formatting to a field. Let's use an example to explain this - think of a Template Field that is supposed to represent a currency and you format it using "c0" which will make your field look like this: "$1,000". Now as long as you don't intend on editing or inserting this data, you are fine - there is nothing more you have to do - in fact you might as well use a Bound Field. The problem occurs when you need to edit and insert data. Now you cannot have that formatting for your Edit or Insert fields (or Modes).

//This will only work in Read Only situations - if you intend on this field existing
//along with Edit and Insert modes while using an ODS - expect problems
<asp:TemplateField HeaderText="Price" HeaderStyle-HorizontalAlign="Right">
 <ItemTemplate>
  <asp:Label ID="lblPrice" runat="server" Text='<%# Bind("Price", "{0:c0}") %>' style="float:right;"></asp:Label>
 </ItemTemplate>
        //Notice the lack of Edit and Insert templates
</asp:TemplateField>

Let's assume that same field is read only - you won't allow it to be edited or inserted - this is a derived field of some kind. Well ASP.Net doesn't care, if you don't provide an Edit or Insert Template, but you intend on using Edit and Insert modes for your control - then you will get conversion errors (which are annoying). Going back to the same example, during an Edit "$1,000" cannot be converted to a decimal value of "1000M" (or "1000D" for VB.Net) you will get an error because of the "$" sign being part of the string. The same problem will happen in the Insert Scenario, blank cannot be converted to a decimal using the stock methods. Convert.ToDecimal("") will throw an exception.
//If this field is intended to be read only, but the control is going to use 
//Edit and Insert modes - then in some cases you have to populate the field 
//for each of the modes or risk running into problems.
<asp:TemplateField HeaderText="Price" HeaderStyle-HorizontalAlign="Right">
        <ItemTemplate>
  <asp:Label ID="lblPrice" runat="server" Text='<%# Bind("Price", "{0:c0}") %>' style="float:right;"></asp:Label>
 </ItemTemplate>
        //During Edit Populate it - but hide it
 <EditItemTemplate>
  <asp:TextBox ID="txtPrice" runat="server" Text='<%# Bind("Price") %>' Visible="false"></asp:TextBox>
 </EditItemTemplate>
        //During Insert Populate it - but hide it
 <InsertItemTemplate>
  <asp:TextBox ID="txtPrice" runat="server" Text='<%# Bind("Price") %>' Visible="false"></asp:TextBox>
 </InsertItemTemplate>
</asp:TemplateField>

The most ridiculous part of all of this is the above is not always true. It is the safest thing you can do though to avoid the error of topic. To reiterate, you should be able to avoid the error of topic if you fully implement your template field. This is (mostly) true for all cases. If your field is supposed to be hidden, read only or fully malleable. I have had this problem show up, what I would consider, randomly. It is not consistent.

I have some controls, in the same project, that share the same types of fields, but I have to template those fields differently depending on the control for some reason. I think most of these problems arise because an ODS is being used. If this was separate from an ODS, then most of these problems could probably be avoided.

Saturday, September 29, 2012

Common Base Class Work Around for Page and UserControl

The Gotcha
This is a really sore subject for me because I have tried finding a unifying factor for both sets of objects, but the answer I have come up with is - there is no unifying factor. I have read posts of people coming up with ways to have a single base class for both pages and controls - but it was a very over complicated approach and they didn't post how to do it anyhow.

http://stackoverflow.com/questions/7840706/how-to-make-a-base-class-for-both-page-and-usercontrol

I followed the advice in the above link and I have decided it is the best approach (at least for me) to follow.

The Approach
When creating a new web app from scratch, I highly recommend almost all of your page and control code behinds inheriting from a base class. The problem obviously is when you need to have code available to both base classes to do something rudimentary and basic. I recommend having the following components:
  1. Page Base Class
  2. Control Base Class
  3. Static Class that has extension and static methods in it that both Base Classes will be using. This way you don't duplicate any code.
  4. Interface for the above classes. It is not fun to maintain, but it guarantees that the implementations and signatures being used are identical for both classes.
The following is an example of the implementation. These are methods I use because they make my life easier for doing redirects and constructing URIs in the code behind. Feel free to use them.

Pages
//PageBase - The base class for all aspx pages
//ICommonPageMethods - The interface that must be implemented 
//                     in order to use the common methods safely
public class PageBase : System.Web.UI.Page, ICommonPageMethods 
{
 #region ICommonPageMethods Members
 public void RedirectToPage(string uri, bool endResponse = false)
 {
  Response.RedirectToPage(uri, endResponse);
 }

 public void RedirectToPage(string uri, string queryStringParameters, bool endResponse = false)
 {
  Response.RedirectToPage(uri, queryStringParameters, endResponse);
 }

 public string AddQSP(string key, object value)
 {
  return PageExtensions.AddQSP(Server, key, value);
 }

 public string AddQSP(params object[] values)
 {
  return PageExtensions.AddQSP(Server, values);
 }
 #endregion
}

Controls
//ControlBase - The base class for all ascx controls
//ICommonPageMethods - The interface that must be implemented 
//                     in order to use the common methods safely
public class ControlBase : System.Web.UI.UserControl, ICommonPageMethods 
{ 
 #region ICommonPageMethods Members
 public void RedirectToPage(string uri, bool endResponse = false)
 {
  Response.RedirectToPage(uri, endResponse);
 }

 public void RedirectToPage(string uri, string queryStringParameters, bool endResponse = false)
 {
  Response.RedirectToPage(uri, queryStringParameters, endResponse);
 }

 public string AddQSP(string key, object value)
 {
  return PageExtensions.AddQSP(Server, key, value);
 }

 public string AddQSP(params object[] values)
 {
  return PageExtensions.AddQSP(Server, values);
 }
 #endregion
}

Static Class
/// 
/// All of the methods here are meant to be used in conjunction with a Page Base or a Control Base.
/// Common methods for both Pages (aspx) and Controls (ascx).
/// 
public static class PageExtensions
{
 public static void RedirectToPage(this HttpResponse r, string uri, bool endResponse = false)
 {
  r.Redirect(uri, endResponse);
 }

 public static void RedirectToPage(this HttpResponse r, string uri, string queryStringParameters, bool endResponse = false)
 {
  if (!string.IsNullOrEmpty(queryStringParameters))
  {
   if (!uri.EndsWith("?") && !queryStringParameters.StartsWith("?"))
    uri += "?";

   uri += queryStringParameters;
  }

  r.Redirect(uri, endResponse);
 }

 public static string AddQSP(HttpServerUtility s, string key, object value)
 {
  return key + "=" + s.UrlEncode(Convert.ToString(value));
 }

 public static string AddQSP(HttpServerUtility s, params object[] values)
 {
  if (values.Length.IsOdd())
   throw new Exception("Parameters provided must be an even number! Key Value Pairs.");

  StringBuilder sb = new StringBuilder();

  for (int i = 0; i < values.Length; i++)
  {
   sb.Append(values[i]);
   sb.Append("=");

   i++;

   sb.Append(s.UrlEncode(Convert.ToString(values[i])));
   sb.Append("&");
  }

  sb.TrimEnd("&");

  return sb.ToString();
 }        
}

Interface
//This interface will ensure that you keep your method definitions/signatures the same.
//I can't say that this is absolutely necessary - but it is more for discipline to
//make sure that you don't alter the method for one base class versus the other.
//It is easier to just play it safe and implement this interface.
public interface ICommonPageMethods
{
 void RedirectToPage(string uri, bool endResponse = false);
 
 void RedirectToPage(string uri, string queryStringParameters, bool endResponse = false);
 
 string AddQSP(string key, object value);
 
 string AddQSP(params object[] values);
}

Wednesday, September 26, 2012

Flottery: Florida Lottery Checker

I finally published my first Android Application... It was not easy to do, it was actually quite torturous. This experience started off as a fun and what I thought would be a delightful project, into a very disheartening, taxing and confusing experience. There will be another post to follow soon explaining the difficulties.

Anyhow, here is a link to my app for those that are interested just click on the giant icon:


I am building a support page which can be seen on the top right of my blog for all DyslexicApps (this is a play on my handle) that will be published.

Saturday, September 22, 2012

How to Make Your Recycled Printer Cartridge Work Flawlessly

Here are some very easy to follow steps to make ANY Recycled Printer Cartridge work flawlessly:
  1. If you took the newly purchased Recycled Cartridge out of its box, then neatly put it back in the box as you found it upon opening it.
  2. Find your receipt. If you can't find it don't worry it won't matter.
  3. Go back to the store where you bought it (I went back to Office Depot).
  4. Go to the person in charge of ink and tell them you want to exchange your Recycled Cartridge for a Brand New Brand Name Cartridge because when you tried to use their Recycled Cartridge it stopped working after 1 print job and didn't even complete the job.
  5. The person behind the counter will mutter behind their breath that you have to remember these are recycled blah blah blah - just ignore the guilt trip.
  6. Pay the extra money you should have paid before for the name brand cartridges.
  7. Go back home and install the name brand cartridge that will not fail after the first print.
  8. Your Recycled Cartridge now works FLAWLESSLY.
The Gotcha
I made this mistake the other day again. I waited about 10 years to see if these recycled cartridges would get any better, but guess what? Even though the cartridge has ink in it and they don't seem to leak like they used to, the contact pads on the cartridge are not replaced and are worn out to hell. I think that is the epitome of the problems with Recycled Cartridges.

Think I am making it up? Take a peek at the review of the cartridge I bought for a client:
http://www.officedepot.com/a/products/324945/Office-Depot-Brand-OD222-HP-22/#reviewTab

I wish I would have read that first before buying it and having to follow the steps I outlined above.

Screen shot from Office Depot Website
But... What about the Environment?
Okay, think about it this way. Which is worse? People going to the store to buy cartridges once or going to the store to buy cartridges twice because you have to return the crappy recycled cartridge? I wasted time and gas to go help a client with her printer because of this twice. I drove 12.4 miles twice because of this cartridge. That is a total of 24.8 miles to change a printer cartridge? Is that worth the emissions?

So what I am saying ultimately is, until they fix these defects, don't bother with these recycled cartridges, they are a waste.

Lastly, I am sure there are some recycled cartridges that are better than others; for example I have used recycled toner cartridges and I have never had a problem.

Friday, September 21, 2012

ASUS Com Service (atkexComSvc.exe) Memory Leak Work Around

The Problem
So I have noticed after leaving my fairly new PC on (only about 6-9 months old now) for about a week, I was losing a tremendous amount of memory and I couldn't account for where it was going. I currently have 8GB of RAM - which I will soon be upgrading to 24 GB purely for vanity reasons - and I noticed my system was using 6/8 GB of RAM! This is shocking because all I have been doing was development work, nothing major. So even after killing all of my development related programs (VS, SSMS, SQL Server, Millions of Chrome Windows, Snaggit etc...) I was still up to about 4-5GB which is incredibly unusual.

After some investigating in the task manager, I realized I wasn't showing all processes from all users. After ticking that box I found my culprit, a Com Service that talks to the BIOS, provided by ASUS for my ASUS P8Z68-V GEN3 Motherboard.

The Gotcha
There is a process named atkexComSvc.exe that has a very bad memory leak. The memory leak is so bad that after a week of my computer being on it racked up about 3GB of memory. That is horrific. Still not really knowing exactly what the problem is, I restarted my computer and problem solved. However restarting your computer isn't something you want to realistically do every day so I have a temporary work around for this minor annoyance.

Currently only using about 6.7 MB, wait about 20 minutes and it will be 12 MB...
The Solution
Well since this process is running and you know you didn't start it, that means it runs automatically at start up and since it ends in Svc, we can assume it is a Windows Service, of course not all windows services end in Svc... Anyhow, open up your Windows Services (Control Panel > System and Security > Administrative Tools > Services Shortcut) and search for what you see in the image below:

Highlighted in blue is the name of our Concern "ASUS Com Service"
If you are currently suffering from System Memory Loss from this service, go ahead and restart it. You can right click and select restart or use the menu on the left shown in the image above.

To verify that we have the right windows service (and process), right click on it and select "Properties".

Found the culprit process's Windows Service
So as you can see this service is automatically started and it spins up the process named "atkexComSvc.exe" as shown before in the Windows Task Manager. Well since all we can do right now to alleviate the memory leak is to restart the service, let's just do this every day automatically at about 5 AM. Sound good to you?

Notice the path to the service is conveniently shown, you can go there to do the next few steps.

Creating a Windows Task in Task Scheduler
So this is going to require a batch file, there are a number of ways of doing this, I just like using batch files for their simplicity.

Batch File Code
ECHO Stopping atkexComSvc.exe - ASUS Com Service
NET STOP "ASUS Com Service"
ECHO.
ECHO Starting atkexComSvc.exe - ASUS Com Service
NET START "ASUS Com Service"
REM PAUSE

Go ahead and throw that code into a file, name it whatever you want as long as the file extension ends in ".bat" so for example, I named my file "Restart Com Service.bat". You can double click on the file to execute it which is convenient at times for quick execution. The last line of the code is commented out by using the keyword REM. Only enable PAUSE (by removing the word REM) if you are debugging the script, otherwise your batch file's console window will show up at 5 AM and stay there until you press any key to make it go away.

I put this file into the same folder as the Com Service, not necessary, but I think it makes the most sense so you know where it is.


The location of the process (for me anyhow) is located here: C:\Program Files (x86)\ASUS\AXSP\1.00.14


Open up Task Scheduler (Control Panel > System and Security > Administrative Tools > Task Scheduler Shortcut) and you should see an ASUS folder. If you don't it doesn't matter, but just for organization I would add you task there. Right click on empty space and select Create Basic Task. Follow the prompts and when it asks you for the program/script, browse to the batch file we created earlier.

If you want to test your task after creating it, right click on it and select "run" from the context menu.

Don't worry if the service complains that it can't stop or anything - it might be in the middle of something OR if you already restarted it once and you are trying to restart it again, it might refuse you the second time. I encountered that problem. Either way the goal was to just make it empty out its memory allocations, so it could start filling up all over again.

Enjoy.

PS: If ASUS doesn't fix this soon, I think I am going to decompile the service and look for the problem myself. This is just ridiculous. Hopefully they fix this soon.
UPDATE: 01/13/2013 - I couldn't decompile this executable. It is not written in .Net because when I used Just Decompile from Telerik it wouldn't work and I tried a C/C++ decompiler but it blew up when I tried to use it. So I guess I will just try the old fashioned way, I will make a support ticket for this when I get around to it. If anyone knows how to decompile this executable I'd appreciate a clue.

Thursday, September 13, 2012

How to get rid of the black border on HDMI output on your AMD Radeon HD 7850

This was more of a pain in the ass than it was Obscure, more of a Gotcha, but not really since there is indeed a solution, you just need to dig for it and it isn't too obvious due to wording.

I have the AMD Radeon HD 7850 and it is a really good card, although discontinued recently. I used HDMI for my second monitor, I don't game on it so it is great for just viewing normal things. I use DVI for my primary monitor. Anyhow, setting up the HDMI monitor was harder than it needed to be. I swore my card was dead for a while when I tried getting it to work because all I got was a black screen. Unfortunately I don't remember the specifics of it, otherwise I would post about it.

HDMI Output Gotcha
All I can say is, if you intend on using an HDMI monitor with your PC, plug it in AFTER windows has booted and you are logged in! Otherwise you might just get a black screen when you get to windows. Your mouse might be active, but that's it.

How do I get rid of that damn black border around my screen?
This is ridiculous, but believe it or not it is a setting. I am sure there is a good reason for it, but why not make the default fill up the screen, not the reverse? So that black border around your screen has everything to do with your "Scaling Options".

Here is a screenshot of what I am talking about:


  1. You have to open up the Catalyst Control Center. You do so by right clicking on an empty spot on your desktop and clicking on "Catalyst Control Center" in the context menu (should be at the top).
  2. Go to the "My Digital Flat-Panels" section
  3. Click on "Scaling Options (Digital Flat-Panel)"
  4. Move the Slider over to the right completely until it says 0% (Overscan max I suppose). You will see your screen size change as you do this.
  5. Apply your changes and exit.
Enjoy!

Changed Blog Background

I changed the background of the blog because I think it is easier on the eyes. I have a problem staring at lines that are too close together like the last background. I apologize if that was hard on the eyes for anyone - this new background should even things out nicely.

I will be writing an article soon about office lighting, backgrounds, color and your eyes. Things people take very lightly, but should be more serious about. A preview of what I am referring to is - stop using white backgrounds especially if you wear glasses with a crappy prescription like mine.

Tuesday, September 11, 2012

How do I consolidate my student loans?

This is an unclear and scary subject for most people exiting college and being thrown into the woes of the work force. I say woes because after my first 4 months on my first job out of school I was laid off - that is hardly fair - but I survived even with my loans on my back.

The Debt you Earned
If you were like me when you were in college you probably racked up a nice chunk of change in student loans because you had no choice. The government told you that your parents were supposed to contribute an impossible amount of money to your education and when you showed your parents your EFC they just laughed at you. So while you were in school, every semester you took out more loans, those loans were never consolidated because of faulty reasoning in my opinion, but hey, beggars can't be choosers. Those loans were all accruing interest with the exception of your Federal Subsidized loans if you had any. Do not be fooled though Subsidized loans begin to accrue interest as soon as you reach your repayment period after your 6 month grace period.

The Shocker
Now you are out of college and it is time to pay back. What's this? An unspeakable amount of money you are expected to pay every month after your 6 month grace period?! Oh jimeney Christmas! You knew you had to pay, but not this much!

Consolidation to the Rescue
Well that is where consolidation comes into play. You really don't want to pay off 10 or 20 small loans, you want to pay off 1 or 2 consolidated big loans. Why not just 1 loan? Ah, you see that would be too easy, there are different loan types that prevent that from being a reality, which in my opinion doesn't make much sense depending on the loan.

Loan Types and Consolidation
As you will quickly learn, the different types of loans that you have can or cannot be consolidated. The basic rule seems that Loans of the same type can be consolidated and nothing more.
  • Private Education loans cannot be consolidated together with Federal Loans - this makes sense to me. I have a Private Education loan that has a variable interest rate, it cannot be consolidated together with my fixed rate Federal Loans. The main reason (I think) they can't be consolidated is because one of my loans was from the Private sector and the others are from the Public sector.
  • Federal Subsidized loans cannot be consolidated together with Federal Unsubsidized loans - this makes little to no sense to me. Both my Subsidized and Unsubsidized loans have the same interest rate and are both Federal loans, in my opinion they should be consolidated, but they aren't, even though my Subsidized loan is now accruing interest just like my Unsubsidized loan. Why not just consolidate them then? No idea why they don't...
Unfortunately sense plays no part here, now it is time to pay back your borrowed money - that's all that is clear.

Interest Rates
As mentioned before, you can have different types of Interest Rates, there are two main types:
  • Fixed Rate - Fixed Rate loans have the same interest all year until they are recalculated. They can be changed when Ben Bernake farts or when congress hates you because they think cutting spending really means to raise rates on people repaying their student loans.
  • Variable Rate - These rates fluctuate often, the recalculation depends on your loan, but most of the time it is quarterly (I need to verify this). Usually these are the worst kind, but right now, since the US economy has the pulse of a Clam - you can actually rejoice a little - your interest rates are probably lower than the Federal Rates as of right now (09/11/2012) and they have been like that for a while. However, when the economy is revitalized expect your rates to shoot back up, but there is luckily a cap on how high they can go.
Okay... So How do I Consolidate my Loans?
You can attempt to go to a variety of places for your student loan consolidation. For example you can try to consolidate your loans with the people you have your loan with. However prepare yourself for them to possibly stonewall you and say something to the effect of, "We are not accepting any new applications for Loan Consolidation at this time.", which is a banks way of saying, "Sit and Spin". I had this happen to me with Sallie Mae, therefore I will shamelessly say, NEVER USE SALLIE MAE THEY SUCK. So I found myself in this predicament until I found only one place on the face on the planet that would consolidate my loans and they are named "Direct Loans" or at least they were, they recently changed their name to EdFinancial. I highly recommend EdFinancial for your Federal Loans, they do not take Private Loans, but do not fear there is another company that you can use for your Private Education Loans named American Education Services. Truth be told I didn't actually seek AES out, they found me and bought my loan from JP Morgan Chase because, just like Sallie Mae told me to sit and spin, JP Morgan Chase had me at an alarming 11% variable interest rate.

Recap: People you can consolidate with and what for
  • EdFinancial - http://www.edfinancial.com - they will mostly take your Federal Loans ONLY - They will NOT take Private Education Loans.
  • American Education Services (AES) - http://www.aessuccess.org/ - they will take your Private Loans and possibly others.
I trust both of those companies because they are Government run or backed.

My Real Federal Loan Example
I took my 10 or so small loans from Sallie Mae which was a monthly payment of $425 at a different interest rate per loan over to what was known as Direct Loans at the time and they consolidated me down into two Loans, both at 6% initially. I was then paying $230 per month. Big $195 dollar difference there huh? If you sign up for automatic bill pay, it drops the interest down to 5.75% which is indeed significant (-0.25%). I now have two main Loans, one Subsidized and one Unsubsidized, but don't be fooled by the names they both accrue interest. The government just refuses to consolidate them together even though they have the same interest rate...

My Real Private Education Loan Example
So I didn't actually refinance this loan myself, it was done for me without my permission, but you know what - I am very glad it happened. AES lowered my interest rate from a horrific 11% down to 4.00-4.25%. It does fluctuate, but not too much.

Pay Off Strategies
If you are capable of doing so, enroll in the aggressive payoff schedule. This means your payments are higher, but you pay off more principal each month. You want to attack your principal as much as possible. If you go for the lowest payment you not only have more payments up until the end of your scheduled loan Payment Period (10 years typically from the time you start paying not including forbearance or deferment), but you also risk paying more unnecessarily due to interest rate hikes, policy changes, your loans being sold to a crappy company etc... In other words - the faster the better. I currently pay about $300 total each month in loans, I would like to not have to do that anymore.

Advanced Payments
If you want to send in an extra amount towards your principal, DO NOT use the regular payment system they have online. You need to call your loan owner/servicer and get instructions on how to do this. If you do not call and get the specific instructions, then the payment you sent in is going to be treated as a PRE-PAYMENT which is not the same thing as paying down your loan.

The best way to look at your loans (in my opinion) is in $5,000 chunks (5K Chunks). You want to strive to pay off those chunks. Let's say you have a $30K loan, 30/5 = 6 - 5K Chunks. It doesn't change anything, but it makes the loan a little less scary because you only have to pay down six 5K loans. So if you save up some money to do this, then you will be doing double duty on your payments because between your savings and the monthly payments that you are making you will wear down those chunks to zero.

Don't go broke paying down your loans though, it isn't smart to take all of your savings and throw it at your loans, you want to have a cushion for those rainy days. It is easier to make those monthly payments, rather than pay it all off and then possibly lose your job unexpectedly with no money to fall back on.

What are Pre-Payments
Pre-payments are just like they sound, you just paid in advance so you don't have to pay later. Basically there is a credit on the books, so your following monthly balance will be paid off and you will most likely receive a bill of zero dollars for that month. This can be confusing for a lot of people, it was confusing to me because I made this mistake. It isn't very intuitive, just like companies not consolidating Sub and Unsub loans after entering the payment term...

Conclusion
Loans, much like credit cards, are not that scary if you understand them. Remember you got this loan for a reason, so now you have to pay it back that was the agreement. The faster you pay it down the better because you will pay less in interest and you can get your disposable income back into your pocket.