Detecting Scams

Scams are all around us.  I get phone calls every day from people trying to give me money, or threatening to send law enforcement after me.  My small-business has been targeted by two different scams, and each scam has been attempted a number of times.  Some are easy to spot (like the Nigerian Prince scam of years gone by), and others are harder (like when my company gets an RFP for 12 new laptops).  And, no one is not susceptible to falling for a scam.  Heck, even former CIA Director John Brennan fell victim to a social engineering hack.

Because it’s so easy to fall prey to these attacks, I wanted to provide some tips to help you avoid becoming a victim in the future.

  • The US Government does not initiate conversations via phone or email or social media
    • The US Government will always send you a letter to initiate a conversation
  • The Treasury department has not selected you to receive free money
    • While the US Government does award grants, these grants are applied for.  You’ll never receive money that you didn’t ask for first.
  • The US Government will not request money from you to receive any award
  • The US Government will never ask for, and will never accept, money through Gift Cards or Western Union.
  • The IRS will not call you to inform you that you are under investigation.  They have attorneys who will write and send you a letter.  If they are going to take you to court, then you will get served.  They will never call you.
  • If your friend on Facebook says they need money, pick up the phone and call them first.  If you don’t have their phone number, then you probably aren’t close enough for them to ask you for money.
  • Accounts on Facebook and other social networking sites are easy to hack.  But, the real value doesn’t come from hacking a social media account.  The real value is duplicating a social media account, which is extremely easy to do.
  • Microsoft is a great company, but they will never call you to discuss a virus on your computer.
  • Neither will Apple.
  • You may trust your anti-virus software, and you should, but they will never call you to discuss a virus on your computer.

At the end of the day, most scams are easy to detect if you ask yourself the right questions and don’t get too excited about the idea of free money.  If they want to give you free, unsolicited money, ask them to send you a check.  If the person on the other end of the Facebook message looks like your friend, pick up the phone and call them personally.  Talk to them on the phone about it.  Find out if it’s true.

If someone ever calls you and says they have detected anything wrong with your computer, thank them for letting you know and hang up.  Never allow someone you don’t know to remote into your computer.  If you have any suspicions that there might be something wrong, contact your local computer repair guy.

What ways have you been scammed?  What tips would you give someone to avoid falling prey to a scam?

Etymotic mc5 Earphones – Review

At the time of this writing, I’ve been using the Etymotic mc5 Earphones almost every day for 2 years, 3 months.  I wear glasses, so using over-the-ear style headphones is out of the question.  Over the years, I’ve tried many different types and styles of in-ear Earphones.  A little more than two years ago, I made the decision it was time to do some research, get some recommendations, and spend some money on a quality product.  On a friends recommendation, I turned to the Etymotic mc5.

They sell for $59 and you can purchase them from their website, or from Amazon.

What I Like

I’m a programmer.  And, like many programmers, I listen to music a lot while I work.  Because of that, comfort is a must when considering a pair of in-ear earphones.  Especially when shelling out more than $5 or $10 dollars.  These particular in-ear earphones are, by far, the most comfortable I have ever owned.  They come with a few tips to choose from,  I chose the gel tips, which themselves come in three different sizes.  Speaking of ear-tips, they also offer a service where you can get ear tips made, custom to your ear.  I have not done this.

When I purchased these, I hadn’t caught the fact that they were noise isolating, but they are.  So much so, that when I plug them into my computer, I have to turn my volume down to 4, and I still can’t hear my wife when she comes up behind me.

When I’ve had to call customer service, they have been great, every time.

What I Don’t Like

Honestly, there are only three things I don’t like about this product.  And, one of those is a small inconvenience, which I’ll start with.

They are only 4′ long.  Which isn’t all that bad, but I tend to adjust in my seat often, and for my office setup, it’s just barely long enough.  A 6′ cord would go a long way for these earphones.

The product only has a two-year warranty.  For a product as expensive as this, and one I’ve heard should last for several years, a two-year warranty just seems too small.  Which brings me to my third issue.

In my 27 months of use, I’ve had to send it in for replacement twice, so I’m already on my third pair.  The problem has been the same with each pair.  The adhesive that holds the two main pieces together, wears down.  Don’t get me wrong.  I know that earphones don’t last forever.  But, for the price-tag, and such a high-quality earphone, I would expect the quality of the construction would be the same.  It should also be noted, that both times I called Etymotic to initiate the exchange process, and they were nothing but helpful and friendly, which I find hard to find these days.

Conclusion

As company that has it’s roots in designing and manufacturing hearing products, I had high expectations for my Etymotic earphones.  And they met those expectations.  I would recommend these earphones to anyone who is looking for a quality earphone at a reasonable price.

Technical Specifications

Frequency Response: 20 Hz – 15 kHz
Accuracy Score: 85%
Transducers: High-output 8mm neodymium moving coil driver
Noise Isolation: 35-42 dB
Impedance (@1kHz): 16 Ohms
Sensitivity (@1 kHz) SPL at 0.1v: 100dB
Maximum Output (SPL): 120 dB
Cable: 4 ft.
User Replaceable ACCU-Filters: Yes
Warranty : 2 Years
Custom-Fit Option: Yes

Das Keyboard Prime 13 – Review

Das Keyboard sent me the Prime 13 about a month ago, and I’ve been using it ever since. As a software engineer, the keyboard plays in important role in the ability to complete my job functions as a software engineer.  Beyond the hours spent typing code, I also look for features to make my job easier.  I was excited to try this one.

This keyboard sells for $149.00 and is available at www.daskeyboard.com.

You can read my review below, skip to my conclusion, or visit the technical specifications.

Initial Reaction

Weighing in at nearly 3 pounds (2.9 to be exact) and featuring an anodized aluminum top panel, this keyboard is both extremely sturdy and stylish.

If you’re interested in the detailed technical specifications, click here, or just keep reading for the review.

What I Like

As I mentioned in my initial reaction, this is a hefty keyboard.  Whether intended or not, the weight is an important feature and the more I use it the more I notice it doesn’t slide around on my desk like other keyboards do.

As a coder, I use my function keys much more often than the average typist. The fact that these function keys are full-size is a major bonus. Many keyboards out there don’t have full-size function keys, making them a pain to use. Along those lines, this keyboard doesn’t have a “special key row” above the function keys, which my old keyboard had. I don’t miss this. Since using the Das Keyboard, I’ve not once opened outlook, or a chat window while trying to press a function key.

I’ve wanted to use a mechanical keyboard with Cherry switches for a while, and this was my first experience with one. Not only did I like Cherry switches much more than I thought I would, after only 5 minutes of typing I already started seeing an improvement in my typing speed and accuracy which was quite surprising to me.

As with any new keyboard, I did have to get adjusted to the new travel spacing, but it was very intuitive, and I adjusted quite nicely.

I’ve noticed that many keyboards either don’t have indicators on the actual keyboard, ordaskeyboard-logo-on-prime13-mechanical-keybaord they don’t have notifications on screen (it’s either/or). The Prime 13 has both lights for Caps/Num/Scroll Lock, and toast notifications. I like this very much. I want to have the toast notification when I get in a hurry and turn off NumLock, and I want to see that NumLock is on when I come back to my computer after walking away.

Being able to adjust the keyboard backlighting is nice, although I never do.

The aluminum plate adds a nice look to the keyboard. Just looking at the thing you know it’s going to be a good typing experience.

I don’t need keyboard backlighting, nor do I need a USB pass-through, and I like a clean desk, so I was initially disappointed that this wasn’t a wireless keyboard (though, good luck finding a decent wireless mechanical keyboard). Having said that, because the weight of the keyboard keeps it in place well, the cable doesn’t move around, which keeps my papers behind the keyboard nice and neat. Though I would still prefer a wireless keyboard for cleanliness, this isn’t a con for me since it hasn’t had any negative effect.

What I Don’t Like

As for things that I would change, there aren’t very many, but here they are.

mechanical-switches-prime13The keyboard backlighting has 7 levels of brightness, including off. This is great. However, there are some inconsistencies in the brightness level of some of the keys.  This could be by design, or it could be a small oversight.  Either way, I’m not a fan of it. Without getting into specifics of why, the end result is that the Function keys, which share media controls, have lighting for the Function and the media control, for example, “F5” and “Previous” are the same key, and both symbols have the same level of brightness.  However, the number row keys don’t share brightness with the character it represents, for example, “2” is bright, but “@” is dim.

The thing I would change the most about this keyboard is the media controls which are embedded with the Function keys.  This means simple functions like mute, volume down, volume up, etc. are accessed via two keystrokes, which is more than a little annoying. If this keyboard had designated media buttons, that would be a major bonus.

It’s not a big factor for me because I don’t use the USB Pass-through, however it is a little disappointing that a keyboard as new as the Prime 13 has USB 2.0 instead of 3.0.

I was also disappointed that not all keys sound the same. As I got used to typing on the keyboard, it became less noticeable to me and it hasn’t affected my typing any, but it was still an initial disappoint that a keyboard with this quality would have those inconsistencies. The following keys have a different sound than the main keys:

  • The spacebar is more “hollow”
  • The backspace key has a “tinny” sound
  • The enter key has a “blunt” sound
  • The shift key has a “tinny” sound, though not as noticeable as the backspace

Conclusion

It has been an absolute joy to type on this keyboard over the last several weeks, and it lives up to the reputation that comes with the Das Keyboard brand.  I would recommend this keyboard to anyone who is looking for a quality mechanical keyboard.

Technical Specifications

Keyboard Layout

  • Standard 104-Key: US layout with n-key rollover
  • Standard 105-Key: UK, DE, and NO layouts with n-key rollover

Switches

  • Cherry MX Brown (Soft Tactile) mechanical key switches
    • Feel: Soft Tactile
    • Actuation Force: 45g
    • Tactile Force: 55g
    • Lifetime: 50 million actuations
    • Total travel distance: 4mm
    • Pre-travel distance: 2mm
    • Operating Point: 2mm
    • Reset point: 2mm
    • Keycap stem: MX (Cross)

Key Caps

  • Black thermoplastic key caps with white laser-marked inscriptions

Interface and Connectivity

  • One USB 2.0 pass-through
  • 2m (6.5ft) USB braided Y cable with dual USB type-A connectors, gold plated (fixed, not detachable)

Backlighting

  • 1 Zone: entire keyboard
  • Color modes: 1 color, White
  • Brightness: 7 modes/levels which include off
  • Lighting Mode Memory
    • When keyboard is plugged into the computer and upon a power down/powering off of the computer, the keyboard will remember and return to the last used lighting mode/brightness level.
    • Default brightness level: 3
  • Keyboard will auto-dim after 10 minutes of inactivity

Compatibility

  • Compatible with Windows, Mac OS, ChromeOS, and Linux Operating Systems
  • Compatible with USB 1.1 and 2.0 standards
  • Compatible with USB KVM switches

System Requirements

  • One USB 1.1 or 2.0 port (for keyboard)
  • One USB 2.0 port (for USB pass-through port)
  • No custom driver required

Product Dimensions

  • Length: 45.80 cm (18.03 in)
  • Width: 17.20 cm (6.77 in)
  • Height: 3.11 cm (1.22 in)
  • Weight: 1.32 KG (2.9 lbs)

Wildcard Subdomains in MVC5 and Azure WebApp

If you’re here, I’m going to assume you already know what Wildcard Subdomains are.  The point of this post is to teach you how to get them to work in your MVC application, both on your dev machine, and on Azure WebApps.

First step is to get it working on your local machine.  Ben Cull does a great job of getting this working over at his blog: http://benjii.me/2015/02/subdomain-routing-in-asp-net-mvc/  I highly recommend watching his short video on the topic also: https://youtu.be/dMFOo0__rm0

The only problem I ran into at this point was that I would get an exception that the controller wasn’t defined if the URL looked like “subdomain.localhost:4353”.  So, I just added an IF blocks to his SubdomainRoute class to make ‘controller’ “Home” if it is an empty string, and an IF block to make ‘action’ “Index” if it is an empty string.

After this, everything works perfect locally.

To get this to work in Azure WebApps, however; you need to complete a couple more steps.

First, you’ll need to go to your domains DNS management and add the following CNAME record:

*.YourDomain.Com

This gets a Value which looks something like this (Azure will tell you what it needs to be)

YourDomain.azurewebsites.net

Next, in Azure, go to your WebApp and click “Configure” and then scroll down and click “Manage Domains”.  Here, you’ll add the following domain name:

*.YourDomain.com

Note: This is where Azure will tell you what to put in your CNAME record.

You’re all set.  Now you can go to “AnySubdomainThatYouWant.YourDomain.Com” and it should work!

 

MVC 5 T4 Templates and View Model Property Attributes


Yesterday, I published a blog post demonstrating how to modify your T4 templates for your single project.  Today, I’m going to show you how to access an attribute from your Model in your T4 template.  Beginning with MVC 5, the T4 templates no longer use ModelProperty class to iterate over the properties in your Model.  ModelProperty has direct access to Attributes, and there are plenty of resources on the web on how to read the attributes in your T4 using that.  In MVC 5, however, ModelProperty has been replaced with PropertyMetaData, which does not have access to the attributes of your properties.  Further, I found it very difficult to find a solution for MVC5 on the web, until finally I came across an old MSDN Magazine article, which was only helpful because I could download the sample project and take a look inside.  The article itself is missing referenced images and code samples.  So, I’m taking what I learned, and am creating this, hopefully simple, post to demonstrate.

For our purposes today, we will be extending our project from yesterday to make the Biography property on the Person model a RichText field.  So, for a reminder, here is our Person model:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
 
namespace CustomViewTemplate.Models
{     
     [Table("Person")]
     public class Person
     {
         [Key]
         public int PersonId { get; set;}

         [MaxLength(5)]
         public string Salutation { get; set; }

         [MaxLength(50)]
         public string FirstName { get; set; }

         [MaxLength(50)]
         public string LastName { get; set; }

         [MaxLength(50)]
         public string Title { get; set; }

         [DataType(DataType.EmailAddress)]
         [MaxLength(254)]
         public string EmailAddress { get; set; }

         [DataType(DataType.MultilineText)]
         public string Biography { get; set; }     
     }
}

To demonstrate that we can also use a custom attribute, let’s create one.  Create a class called RichTextAttribute in the project root directory:

namespace CustomViewTemplate
{
     [AttributeUsage(AttributeTargets.Property)]
     public class RichTextAttribute : Attribute
     {
         public RichTextAttribute() { }
     }
}

Then, back to PersonModel, add the RichText attribute to the Biography property:

[RichText]
[DataType(DataType.MultilineText)]
public string Biography { get; set; }

Now, copy the following global template files from

C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates\MvcView\

to a folder called

CodeTemplates\MvcView\

  • Create.cs.t4 (OR Create.vb.t4)
  • Imports.include.t4
  • ModelMetaDataFunctions.cs.include.t4 (OR ModelMetaDataFunctions.vb.t4)

Now, remember the PropertyMetaData, doesn’t have access to the attributes, so we need to create a new class with a function that does the work for us, so let’s create a class called T4Helpers, with a public function called IsRichText.

using System; 

namespace CustomViewTemplate
{
     public static class T4Helpers
     {
         public static bool IsRichText(string viewDataTypeName, string propertyName)
         {
             bool isRichText = false;
             Attribute richText = null;
             Type typeModel = Type.GetType(viewDataTypeName);

             if (typeModel != null)
             {
                 richText = (RichTextAttribute)Attribute.GetCustomAttribute(typeModel.GetProperty(propertyName), typeof(RichTextAttribute));
                 return richText != null;
             }

             return isRichText;
         }
     }
}

We are using our custom RichTextAttribute here, but you could use any Attribute you would like.  What we are doing is returning true or false; indicating that the given property either does or does not have the attribute we are checking for.

Before we can use this function in our T4 template, we’ll need to Build our project and then add a reference to our assembly in the imports file.

Open your projects copy of Imports.include.t4 and add a reference to your assembly as line 4.  For me, it looks like this:

<#@ assembly name="C:\My Applications\Playground\CustomViewTemplate\CustomViewTemplate\bin\CustomViewTemplate.dll" #>

As you are typing the line of code above, if you are using tangible T4 Editor, you might see an inellisense option like so:

image

and you might be tempted to use it, but there is a bug that will prevent this form working.

Okay, now we can modify our T4 template.  Open Create.cs.t4 and look for the foreach loop that iterates over our list of properties.  You’ll find this around like 96:

<# foreach (PropertyMetadata property in ModelMetadata.Properties) {      if (property.Scaffold && !property.IsAutoGenerated && !property.IsReadOnly && !property.IsAssociation) {          // If the property is a primary key and Guid, then the Guid is generated in the controller. Hence, this property is not displayed on the view.          if (property.IsPrimaryKey && IsPropertyGuid(property)) {              continue;          } #>

To avoid unnecessary calls to our new method, we’ll only check for the RichText attribute against properties that we will actually be rendering, so after the inner If statement (the one that checks for primary key’s and Guid’s), we can add this line:

bool isRichText = CustomViewTemplate.T4Helpers.IsRichText(ViewDataTypeName, property.PropertyName);

Now, the tricky part is using our new variable and finding the correct place for it.  For our purposes, we will put it inside the nested if statement that is checking for a checkbox.  So, that entire if block would look like this with our new code added:

             if (isCheckbox) {
#>


<div class="checkbox">
<#                  PushIndent("    "); #>
                 @Html.EditorFor(model => model.<#= property.PropertyName #>)
<#              } else if (property.IsEnum && !property.IsEnumFlags) { #>
                 @Html.EnumDropDownListFor(model => model.<#= property.PropertyName #>, htmlAttributes: new { @class = "form-control" })
<#              } else if (isRichText) { #>
                 // TODO: Place RichTextBox HTML here
<# } else { #>
                 @Html.EditorFor(model =>; model.<#= property.PropertyName #>, new { htmlAttributes = new { @class = "form-control" } })
<#              }           } else { #>
                 @Html.EditorFor(model => model.<#= property.PropertyName #>) 
<#          } #>

Now, you can see that I just put some generic text instead of an @Html helper, because the implementation details of RichText aren’t important for the purposes of this tutorial.

To verify everything is working properly, we can save changes, go to our PersonController and add a Create action, Right-Click inside to Add View, and add a Create view.

Inside the generated Create.cshtml, you can scroll down and see that our Biography field has our placeholder text, instead of a @Html helper function.



<div class="form-group">
    @Html.LabelFor(model => model.Biography, htmlAttributes: new { @class = "control-label col-md-2" })


<div class="col-md-10">
        // TODO: Place RichTextBox HTML here
        @Html.ValidationMessageFor(model => model.Biography, "", new { @class = "text-danger" })
    </div>


</div>


If you’ve found this tutorial helpful, please leave a comment below!

MVC 5 Custom View Templates

The out-of-the-box template that comes with Visual Studio has improved a great deal since I first started building ASP.Net Web Pages several years ago. But, as nice as the new template is, it’s still nice to be able to adjust the T4 templates that are used to generate the Views. I’ve known for a long time that I could modify these templates globally, by modifying them directly in the Visual Studio folder, but, it wasn’t until earlier this week that I learned you can customize them for just your single project. This post will demonstrate how to do that. In my next post, I’ll demonstrate how to access the attributes on your Model’s properties, from inside the T4 templates.

For the purpose of this demo, I will be using Visual Studio 2013, MVC 5, EF 6, and .net 4.5.1.

For our sample, we will create a simple application that allows for basic CRUD of a person object. So, fire up NuGet and install EF 6 and add a calls called PersonModel to Models folder:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace CustomViewTemplate.Models
{
    [Table("Person")]
    public class Person
    {
        [Key]
        public int PersonId { get; set;}

        [MaxLength(5)]
        public string Salutation { get; set; }
        
        [MaxLength(50)]
        public string FirstName { get; set; }
        
        [MaxLength(50)]
        public string LastName { get; set; }
        
        [MaxLength(50)]
        public string Title { get; set; }
        
        [DataType(DataType.EmailAddress)]
        [MaxLength(254)]
        public string EmailAddress { get; set; }
        
        [DataType(DataType.MultilineText)]
        public string Biography { get; set; }
    }
}

Now, add a basic Person controller, an Empty one so that only the Index Get method is created:

image

namespace CustomViewTemplate.Controllers
{
    public class PersonController : Controller
    {
        // GET: Person
        public ActionResult Index()
        {
            return View();
        }
    }
}

If you right-click inside Index() and choose Add View, use scaffolding to add a List view.

image

Now, the view will open and you’ll see the default List view, which just happens to be a table.

Take special notice to lines 9-11:

<p>
    @Html.ActionLink("Create New", "Create")
</p>

Now, of course this will create a standard issue hyperlink, but what if, for the sake of this example, we want it to be a button instead. Well, we could just change the HTML, but if we wanted this to be a button by default, we would have to change the button. So, first things first, we need to identify the location of the global template files. That location is

C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates\

Now, you can modify the .t4 files in this directory, but ONLY do that if you want the changes to be global. To make changes only to the project you are working in, copy the direct to a new folder in your project’s root, called “CodeTemplates”. You only need to copy down the files you will want to change, but it is important that you copy the folder structure down. That is, we want to modify a file called List.cs.t4, so we need to copy our file to “~ProjectFolder~\CodeTemplates\MvcView\List.cs.t4”. So for me, that looks like this:

C:\My Applications\Playground\CustomViewTemplate\CustomViewTemplate\CodeTemplates\MvcView\List.cs.t4

Note, if you are using VB, you’ll want List.vb.t4.

IMPORTANT NOTE
You also need to copy over MvcView\Imports.include.t4 and MvcView\ModelMetadataFunctions.cs.include.t4

Back in Visual Studio, in Solution Explorer, you’ll need to “Show all files”, and do a refresh, but you should see your CodeTemplates folder now. Of course, you won’t need the templates for deployment, but if you are modifying them, you should add to source control, so go ahead and right-click and “Include in project”.

Now, you can open the t4 file, but beware, VS doesn’t come with a T4 editor out-of-the-box. That means, no styling and no intellisense. There are, however, some good T4 editor’s in the VS extensions. I use tangible T4 Editor 2.2.5 plus modeling tools for VS 2013 (free edition). Of course, you’ll need Visual Studio to be closed before you can run the installer.

Remember our hyperlink we want to change to a button, well, there’s no special t4 stuff going on with that, and this isn’t a tutorial on the basics of t4, so with List.cs.t4 open, look for our HTML snippet above and change it to:

<p>
    <button type="button" onclick="addNewPerson();">Create New Person</button>
</p>

Now save the file. Now, back to the controller and right-click inside the Index method, and select AddView and add a new List View, but overwrite the existing one.

Now, when you look at the new version of Index.cshtml, you’ll see that instead of a hyperlink, you now have a button!

Happy Templating!

Serializing a Dictionary

For better or for worse, dictionaries are not allowed in .net Web API’s.  List’s are allowed, and what’s a dictionary, if not a list of key, value pairs?  So, I wrote this extension method to “serialize” a dictionary.

public static class ExtensionMethods
{
     public static List<KeyValuePair<T1, T2>> Serialize<T1, T2> (this Dictionary<T1, T2>)
     {
          List<KeyValuePair<T1, T2>> list = new List<KeyValuePair<T1, T2>>();
          list.AddRange(dictionary);
          return list;
     }
}

Then, you call it like this:

Dictionary<int, string> wordsThatStartWithB = new Dictionary<int, string>()
{
     { 1, "Bob" },
     { 2, "Blue" },
     { 3, "Bone" },
     { 4, "Bow" }
};

return wordsThatStartWithB.Serialize();

Of course, there are probably better ways of doing this, which is why I will be open sourcing my extensions library in the coming weeks, and will have a blog post about each one. Do you have any recommendations on improving this?

Windows Phone Error code: 85010014

The Short Version

My phone suddenly began reporting Error Code: 85010014 when attempting to sync my work email.

The Fix

It turns out I had a calendar event with a status of “Meeting Elsewhere”.  Changing the status to “Free/Busy/Tentative/Out Of Office” fixed the problem immediately.

The Long Story

Four days ago, my work email suddenly refused to sync on my phone, giving me error code 85010014.  I searched the web, over and over and over and over, to no avail (which is why I’m posting this), so figuring it out was up to me.

What made it look like a device issue:

Because my Outlook and my Web Access functioned properly, from the business side anyway, it looked as though the problem was on my device somehow.  The first thing I attempted was to change my password, but that didn’t fix the problem.

Why a device issue just didn’t feel right:

There were several reasons why I was sure it wasn’t a problem on my device.  I observed the following:

  • Restarting device didn’t fix
  • Removing and Re-Adding the account didn’t fix
  • Removing and Restarting and Re-Adding the account didn’t fix
  • Outlook.com address was working
  • School email (exchange also) was working

Then, I started reading a forum post I came across, which linked to another post, which linked to another post….anyway, I eventually made my way to a post from a problem someone experienced several years ago on their WP7 device with similar symptoms.  They fixed it by unchecking all the boxes for “Content to sync”, then syncing, then adding “Email”, then syncing, then “Contacts”, sync, “Calendar”, sync, “Tasks”, sync.  He observed that by adding the services back one-by-one, the sync was successful and his problem went away.  So I did the same thing, and noticed the same thing…until I checked the box next to Calendar.  The sync failed.  So, I was able to observe that my account would sync, as long as I didn’t attempt to sync the calendar.  So, I pulled out my old WP 7 device and sure enough, I was able to duplicate this behavior.  So, this helped me narrow down the problem, and eliminate my device. 

I kept reading about “try refreshing your cache”, and I wasn’t sure if that was IE cache, or some special device cache or what, but the Microsoft support folks in the forums kept saying, “contact your device manufacture for instructions to clear the cache”.  So, I updated to Windows Phone 8.1.  I’ve been wanting it anyway, and it was released to developers that day, so I downloaded it.  I assumed it would clear my cache, but whether it did or not, the problem persisted.

So, I added my account to my co-workers phone (another WP8, different manufacturer), and was able to duplicate the behavior.  All the while, his account continued to function properly.

So, now I’m convinced that there is a problem with my account, or my calendar or something, but no one knows what to do, and officially, my employer doesn’t support email on devices.  So, I’ve been dealing with this for four days, and tonight I decided to really dig in and try to get this figured out.

I started by looking at the properties of my calendar in Outlook.  I noticed that I’ve never cleaned my calendar since I started with the company two years ago, so it had well over 400 items.  I thought surely not, but maybe-just-maybe, I’ve reached some sort of threshold and the sync process can’t handle so many calendar items.  So, I performed an archive and removed all events older than 90 days.  Still nothing.

So, I started looking through my upcoming events and found one that had my status as “Meeting Elsewhere”, because I’m trying anything and everything I can think of at this point, I change it to “Free” and try syncing on my phone, success!  I thought maybe it just took a while for the clean-up to take effect, so I changed the status back to “Meeting Elsewhere” and sure enough, it broke again, and to fix it, just switch it back to “Free”.

Configuration Specific Reference Location

Sometimes there is the need to have references dependent upon the configuration you are currently in.  You may have a dependencies folder that all your applications can access, and you have an assembly per configuration.  So when you are debugging your application, you want to use the project reference for your API, but when you deploy to your testing server, you want to use the testing version of the API, or Staging, or Release, or…well, you get the idea.

The solution to this is quite easy.

The details of our example will be as follows:

  • One solution with two projects
    • Consumer (Console application)
    • ServiceAPI
  • Our solution will have four configurations
    • Debug
    • Test
    • Stage
    • Release
  • Debug will use a project reference
  • Test, Stage, and Release will reference C:\Dependencies\Test, (Or \Stage or \Release)

Once you have your solution set up and configured, add a reference to your ServiceAPI inside your Consumer project.  Now we have the basics setup and are ready to modify our project file to have different API paths depending on our current configuration.

First, right-click on the Consumer project and select, edit project file.  If prompted to save changes to your solution, click Yes.

image

Inside your project file you will see a series of PropertyGroups and ItemGroups.  If you notice, you have one PropertyGroup for each configuration of your project, and an ItemGroup for reference items, one for compile items, and one for project references.

We want our project reference to only be a project reference if we are in Debug mode.  If you look through your project file, you will find something like this:

<ItemGroup>
  <ProjectReference Include="..\ServiceAPI\ServiceAPI.csproj">
    <Project>{94c972f3-2724-4258-a16f-b121d8502a27}</Project>
    <Name>ServiceAPI</Name>
  </ProjectReference>
</ItemGroup>

Add the following Condition attribute to the ItemGroup tag.  One thing to note here is that the Condition argument syntax is the same in both Visual Basic and C#.  The comparison operator used is the C# one and you would use the same even if this is a Visual Basic project.

<ItemGroup Condition="'$(Configuration)' == 'Debug'">
  <ProjectReference Include="..\ServiceAPI\ServiceAPI.csproj">
    <Project>{94c972f3-2724-4258-a16f-b121d8502a27}</Project>
    <Name>ServiceAPI</Name>
  </ProjectReference>
</ItemGroup>

Now, we want the ServiceAPI to have a specific folder based on it’s configuration, so add the following ItemGroup to the XML file:

<ItemGroup Condition="'$(Configuration)' != 'Debug'">
  <Reference Include="ServiceAPI">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>C:\Dependencies\$(Configuration)\ServiceAPI.dll</HintPath>
  </Reference>
</ItemGroup>

The HintPath is the location Visual Studio should look for the dll, and you can use the environment variables there, so you notice the hint path includes $(Configuration).  Now you can reload the project (Right click the project and select “Reload Project”.  If prompted to save, click “Yes”.

In Debug mode, you will notice the ServiceAPI is using the project reference, but as we switch between configurations, the path changes:

Debug Mode:

image

Release Mode:

image

Test Mode:

image

Stage Mode:

image

One thing to note as you cycle through the configurations.  The properties grid doesn’t update as you change configurations, but the project does.  That means if you switch from Test to Stage, the properties window will still stay Test, but the project will be using Stage.  If you click another reference and then click back to ServiceAPI, it will update the properties window and you will see the path is actually changed.

Feel free to leave any questions or comments in the comments section below!

Happy Coding!

Send a text message using .net

Sometimes, we want to send text messages from our application.  Whether it’s for sending out a secret code for two-tiered authentication, or sending out messages to subscribed members, it’s a feature that is occasionally needed, and one that I’ve recently needed.  There are many services out there that charge a fee, either monthly or per message, but the services are out there.  I’ve also seen several open-source applications that act as an instant messaging type service, in that they have a GUI and do not provide an API.  What I was unable to find was an API that handled all carriers, and was free.  So I built one, and here is how to use it.

Your first step is to download the single DLL, which is needed to use the API.  It’s open source, so you can get the code and make any changes you want and compile the DLL yourself, if you so desire.  You can get the DLL here, and the code here.

After adding the DLL as a reference to your project, it’s actually quite simple to use.  First, add the appropriate using:

using SMSOverEmail;

After the using statement is added, we are ready to start using the API.  The first step is to instantiate a new SMSOverEmail object.

SMSOverEmail.SMSOverEmail sms = new SMSOverEmail.SMSOverEmail

With our object instantiated, we need to set up the “From” part of our text message.  We are using SMTP to send the actual text message, so this is similar to setting up a SMTP client.

sms.EnableSsl = true;
sms.SMTPUserName = "userName@gmail.com";
sms.SMTPPassword = "password";
sms.Host = "smtp.gmail.com";
sms.Port = 587;
sms.From = new System.Net.Mail.MailAddress("userName@gmail.com");

These settings are correct if you are using Gmail, but you can use any email provider you wish, as long as you know the settings Smile

Once the “From” part is set up, we can set up the “To” part.  This is a text message, so we are delivering to a mobile device.  So, for the purpose of this API, you just need to know the 10 digit phone number, and the carrier it belongs to.  The API does the rest.

sms.PhoneNumber = "2345678901"; //a ten digit phone number
sms.RecipientCarrier = Carrier.SprintPCS;

The phone number is a string, and must be the 10 digit phone number belonging to the phone.  The Carrier enumerator has over 60 carriers to choose from.  In our example, we are sending a text message to (234)567-8901 which is held by a Sprint customer.

Now that the recipient and the sender are setup, we can send our text message.

sms.SendTextMessage("test message");

The SendTextMessage function has many different overloads, they are all documented inline, but you can see the full list on the projects CodePlex documentation page.

No tutorial would be complete without showing all of the code put together in a complete console application:

namespace SSMSTest
{
    using System;
    using SMSOverEmail;

    class Program
    {
        static void Main(string[] args)
        {
            SMSOverEmail.SMSOverEmail sms = new SMSOverEmail.SMSOverEmail();
            sms.EnableSsl = true;
            sms.SMTPUserName = "userName@gmail.com";
            sms.SMTPPassword = "password";
            sms.Host = "smtp.gmail.com";
            sms.Port = 587;
            sms.From = new System.Net.Mail.MailAddress("userName@gmail.com");

            sms.PhoneNumber = "2345678901"; //a ten digit phone number
            sms.RecipientCarrier = Carrier.SprintPCS;

            sms.SendTextMessage("test message");
        }
    }
}

The API also comes with a dictionary containing the actual carrier name, along with the enumerator.  For example, Carrier.ATT is AT&T.  Each enumerator is simple to understand, but I threw it in in case you needed a user-friendly list of carriers.  Assuming sms is the name of your SMSOverEmail object, then sms.CarrierNames is the dictionary.  It’s in the form of Dictionary, where Carrier is the enumerator, and string is the user-friendly name.

As always, I would love to hear from you.  Please leave your thoughts about this post below, especially if this post has helped you Smile  If you have any questions, I’ll be sure to do my best to answer those as well.