Youssef
Youssef

Reputation: 33

How to avoid double encoding of raw JSON output by a view

I'm getting the following JavaScript error when trying to parse JSON that I'm getting from my controller:

Uncaught SyntaxError: Unexpected token & in JSON at position 1 at JSON.parse () at stores:76

Here is the code that serializes my list of elements (so i can send it to frontend as string then parse it with JSON.parse())

FeatureCollection mapFeatureCollection = new FeatureCollection(mapFeatures); // this is my object

// FeatureCollection instances provides the method ToJson which converts them to Json strings, use it before sending the FeatureCollection to the frontend
string nearbyStoresAsGeoJSON = JsonConvert.SerializeObject(mapFeatureCollection, Formatting.Indented);

// pass the json to view to mark them
ViewBag.nearbyStores = nearbyStoresAsGeoJSON;
return View("Stores");

Now I think where the problem lies is when i get the JSON in the frontend and I log it to the console, this is what i see:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.6350367,
          33.5841643
        ]
      },
      "properties": {
        "address": "Bigstone, 48 Rue Abou Salt Andaloussi, Casablanca 20250, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.631687,
          33.584392
        ]
      },
      "properties": {
        "address": "Rue Ibnou Al Arif, Casablanca, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.636013,
          33.5838827
        ]
      },
      "properties": {
        "address": "62 Rue Abou Ishak Al Marouni, Maarif, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.635459,
          33.584367
        ]
      },
      "properties": {
        "address": "79 Rue Abou Salt Andaloussi, Casablanca 20300, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.6336024,
          33.5834623
        ]
      },
      "properties": {
        "address": "33 Rue Ahmed Barakat, Casablanca 20250, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.633257,
          33.583944
        ]
      },
      "properties": {
        "address": "39 Rue Ahmed Barakat, Casablanca 20000, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.631826,
          33.5845488
        ]
      },
      "properties": {
        "address": "10 Rue Ibnou Al Arif, Casablanca 20330, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.6334731,
          33.5834792
        ]
      },
      "properties": {
        "address": "Rue Ahmed Barakat, Casablanca, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.6393279,
          33.5791312
        ]
      },
      "properties": {
        "address": "Rue Al Fourate, Casablanca, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.634933,
          33.58392
        ]
      },
      "properties": {
        "address": "51 Maârif Rue Abou Salt Andaloussi, Casablanca 20000, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.6357673,
          33.5820976
        ]
      },
      "properties": {
        "address": "14 Rue Ibnou Nafiss, Maarif, Morocco"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -7.6367801,
          33.5830291
        ]
      },
      "properties": {
        "address": "146 Rue Abou Zaid Addadoussi, Casablanca 20330, Morocco"
      }
    }
  ]
}

Upvotes: 1

Views: 824

Answers (1)

pinkfloydx33
pinkfloydx33

Reputation: 12799

You end up double-escaping/encoding the JSON. The Razor Helper @ under most circumstances is going to try and encode the input and return HTML entities for things like quotes, ampersands, less/greater signs etc.

You can use the @Html.Raw method to indicate that the input is already an encoded string.

var stores = '@Html.Raw(ViewBag.nearbyStores)';
var geojson = JSON.parse(stores);

But note I'd be careful. You never know what might be in the source variable that could cause some sort of injection attack (an unescaped single quote for example).

You should be able to avoid the extra parsing altogether:

var stores = @Html.Raw(ViewBag.nearbyStores);

But that's with the understanding the nearbyStores is in fact valid JSON.

Rather than serializing in your controller, you could make this the responsibility of the view using JsonHelper.Serialize

//controller 
ViewBag.nearbyStores = mapFeatureCollection;
// view
var stores = @Html.Raw(Json.Serialize(ViewBag.nearbyStores));

Upvotes: 1

Related Questions