Enums in C# can make you code easier to read:

private enum Status
{
    Awesome = 1,
    Cool = 2
};

public void Sample()
{
    var lego = new Lego();

    lego.Everything = Status.Awesome;
    if (lego.PartOfTeam == true)
    {
        lego.Everything = Status.Cool;
    }
}

But enums don't cross in and out of C# easily. 

Have you ever tried to save an enum to SQL?  It becomes an int and you're right back to, "Wait, what does a Status of 2 mean again?".

It's easy convert the enum to a string before sending it to SQL, but then you have to convert it back to an enum in C# when you read it in, and that code is gross:

public string ConvertEnumToString(Status status)
{
   return status.ToString();
}

public Status ConvertStringToEnum(string status)
{
    return (Status) Enum.Parse(typeof (Status), status);
}

What about sending the value down to the client in JSON with Web API?  Again, by default you get an int that looses the point of having the enum in the first place. 

That is, unless you want to add enum converters from Json.NET to your JsonSerializer to turn them into strings:

serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());

That's not so bad.  Plus, what's the alternative?

The simplest alternatives are primitive types that convert across all layers, like ints and strings.  I prefer strings so I can immediately know what the value represents and code around that (e.g., the Status is "Cool" instead of 2).

"But this is using magic strings, and those are bad."  Maybe.  But 1) everyone likes magic, and 2) what's the risk? 

That you mistype the string? There is type-safety risk, but it's a mild one and only applies to C#.  Let's say you're in JavaScript and looking for that status of "Coll" instead of "Cool".  That code will fail.  How long until you figure that out?  Seconds?  Minutes?  You'll have tests and/or run the code yourself and see it doesn't work, right? 

Also, if you work with a dynamic language, you know you can type in any nonsense and your compiler won't help you.  It's up to you to test it.  I see magic strings the same way.  Yes, you might make a mistake the compiler doesn't catch, but that's why we test our code.

What about the risk that the value changes in the future.  Let's say management decides that statuses of "Awesome" are too strong.  They want you to change all occurrences of "Awesome" to "Good" throughout the app.  What's the damage here?

Well if you have C# enums, you change Status.Awesome to Status.Good everywhere, then you update you SQL data so old records are correct (only needed if you converted the enum values to strings before storing them), then you update your JavaScript so it doesn't look for or branch on the wrong string (again, only needed if you serialized your C# enums to strings).

If you didn't use enums at all, and just used strings in C#, you would have the same SQL and JavaScript updating to do, but maybe more C# strings to find/replace throughout the project.  But I don't think you can reasonably say that's a lot more work.  Maybe a few seconds more?

On top of that, what's the risk that enums change in the future like this.  It's not zero, but it's really low.  Enum values usually represent the type or state of something, so enum values don't their meanings very often. 

So why go to the trouble to store C# values in a special type that SQL and JavaScript can't work with?  A magic string is just as easy to read as the enum, and it works up and down the stack. 

Here's the original code, but with magic strings instead of enums.  I don't think it loses any clarity:

public void Sample()
{
    var lego = new Lego();

    lego.Everything = "Awesome";
    if (lego.PartOfTeam == true)
    {
        lego.Everything = "Cool";
    }
}