0

I've been reading loads of questions about this issue but can't seem to resolve my particular issue.

I'm returning a json string from a web service function.

I have these objects:

public class WebServiceInitResult
{
    public List<Activity> Activities { get; set; }
    //rest of properties left out...
}

public class Activity
{
    public string IconCode { get; set; }
    //rest of properties left out...
}

The IconCode is the character code for a fontawesome character, any one of these:

\uf0b1
\uf274
\uf185
\uf0fa
\uf0f4
\uf015

They are stored in a database exactly as shown above.

When I set the httpReponse.Content like below, the backslash is escaped:

httpResponseMessage.Content = new StringContent(JsonConvert.SerializeObject(webServiceInitResult), Encoding.UTF8, "application/json");

The json response received by PostMan is:

"activities": [
{
  "ActivityCode": 2,
  "DisplayValue": "Shopping",
  "BackgroundColour": "E74C3C",
  "IconCode": "\\uf0b1",
  "ApplicationId": 2,
  "Application": null,
  "Id": 1,
  "Active": true,
  "DateCreated": "2016-11-25T10:15:40"
},
//rest of activities
]

As you can see, the IconCode backslash has been escaped. From reading other questions, I'm unable to confidently decide if this is happening by Json.NET when I serialize or when then response is sent.

I tried to resolve using ObjectContent instead so I could avoid Json.NET but it returned the same!

httpResponseMessage.Content = new ObjectContent(typeof(TravelTrackerWebServiceInitResult), webServiceInitResult, new JsonMediaTypeFormatter() , "application/json");

Now I am stuck!

Is there a better way to do this that will return exactly what I need? The characters are used by an app to display the appropriate icon.

Extra info: I originally had these values hardcoded and everything seemed to work ok:

webServiceInitResult.activities_TT = new List<Activity_TT>()
{
 new Activity() { ActivityCode = 2, BackgroundColour = "E74C3C", DisplayValue="Shopping", IconCode="\uf0b1" },
 new Activity() { ActivityCode = 3, BackgroundColour = "BF7AC5", DisplayValue="Running", IconCode="\uf274" },
 new Activity() { ActivityCode = 4, BackgroundColour = "AF7AC5", DisplayValue="Walking", IconCode="\uf185" },
 new Activity() { ActivityCode = 5, BackgroundColour = "3498DB", DisplayValue="Jogging", IconCode="\uf0fa"  },
 new Activity() { ActivityCode = 6, BackgroundColour = "2ECC71", DisplayValue="Resting", IconCode="\uf0f4" },
 new Activity() { ActivityCode = 7, BackgroundColour = "F39C12", DisplayValue="Skipping", IconCode="\uf015" }
};

Thanks.

Percy
  • 2,855
  • 2
  • 33
  • 56
  • 1
    *"The IconCode is the character code for a fontawesome character, any one of these: `\uf0b1` `\uf274` `\uf185` `\uf0fa` `\uf0f4` `\uf015` They are stored in a database exactly as shown above."* Then that's the problem. If they're stored as the characters `\`, `u`, `f`, `0`, `b`, `1`, then the JSON serializer is doing exactly the right thing by escaping that backslash. If you want that unicode escape processed, you need to process it before assigning it to your `IconCode` string, so the string actually contains the character, not a string for its unicode escape. – T.J. Crowder Dec 06 '16 at 13:03
  • How are you setting the `IconCode` variables? If you used C# literals, you'd get the actual Unicode character, *not* what you posted. `Debug.Assert("\uf0b1".Length ==1)` – Panagiotis Kanavos Dec 06 '16 at 13:08
  • Databases have no issues with Unicode either, you could store anything in a `nvarchar` column. If you store the escape sequence as 6 separate characters, instead of the actual character, *your code* should unescape this first. Why don't you just store the value in a Unicode column? – Panagiotis Kanavos Dec 06 '16 at 13:16
  • The string gets used by a third party and they specifically requested the data in the format \uf0b1. How can I store this in the database and return it to the third party in this format. – Percy Dec 06 '16 at 14:54
  • @T.J.Crowder so how would I process it? I'm not sure what you mean. – Percy Dec 07 '16 at 08:40

2 Answers2

0

The issue is that in C# language the string value "\uf0b1" is actually a placeholder for "render the unicode character F0B1". When the string is evaluated by the compiler/runtime, the unicode character is inserted in it's place.

This is not the same as storing a string in a database "\uf0b1" which would be the actual string, not the single character and when encoded using C# notation would be "\\uf0b1".

toadflakz
  • 7,764
  • 1
  • 27
  • 40
  • This answer isn't correct. That's not a placeholder. That *is* the character. That string should have a length of 1. A string that contains the characters `\\`, `u`, `f`,`0`, `b` and `1` is just that. 6 characters, the first of which has to be escaped – Panagiotis Kanavos Dec 06 '16 at 13:05
  • `Debug.Assert("\uf0b1".Length==1)` – Panagiotis Kanavos Dec 06 '16 at 13:06
  • Yes, but from a code standpoint it means "render the unicode char". – toadflakz Dec 06 '16 at 13:08
  • No it doesn't. It's just 6 ANSi characters with no other meaning. Only if it was an actual string literal, would it be treated as a Unicode character. It isn't a placeholder either, it *is* the character. Besides, `Debug.Assert("\uf0b1".Length==1)`. You can't argue with that – Panagiotis Kanavos Dec 06 '16 at 13:09
  • 1
    The man is confused as to why in C# language "\uf0b1" is not the same as the same string in a DB - a placeholder/rendering instructions is the best way to explain this. It's a substitution. If it were the actual character, in code, he would simply put the character not a convoluted string which is then interpreted as the character. – toadflakz Dec 06 '16 at 13:12
  • databases have no problem to store Unicode strings either. If the data isn't stored as `nvarchar` there is a conversion problem already – Panagiotis Kanavos Dec 06 '16 at 13:14
  • Yes. It's his misunderstanding of the interpreted value "\uf0b1" vs a literal string of "\\uf0b1" when he switched from hardcoding to DB-based value. – toadflakz Dec 06 '16 at 13:16
  • My front end for these codes is VERY basic - currently I just want the user to type in the code, e.g. \uf0b1. So are you saying I should convert this to unicode and then store in the database? – Percy Dec 06 '16 at 14:44
  • Yes - the issue is that the interpreted value is a single unicode character and your saved value is a 6 char string. You should probably just capture "f0b1" and do the conversion to the unicode char just before you save to the DB. – toadflakz Dec 06 '16 at 14:52
  • Thanks - I've sorted it now - your explanation helped me a lot. – Percy Dec 08 '16 at 14:53
0

Thanks to all the comments I was able to resolve this.

As suggested I needed to get the character code, e.g. "f0b1" and convert this before saving to the database. So in my Activity Controller, create and edit, I added the following using the info here:

int code = int.Parse(activity.IconCode, System.Globalization.NumberStyles.HexNumber);
activity.Icon = char.ConvertFromUtf32(code);

So I added the extra property Icon and convert the code into a character which is then saved to the database. It is this character that is returned in my json response.

Community
  • 1
  • 1
Percy
  • 2,855
  • 2
  • 33
  • 56