【问题标题】:How to avoid double encoding of raw JSON output by a view如何避免视图对原始 JSON 输出进行双重编码
【发布时间】:2020-08-28 05:23:43
【问题描述】:

尝试解析从控制器获取的 JSON 时出现以下 JavaScript 错误:

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

这是序列化我的元素列表的代码(所以我可以将其作为字符串发送到前端,然后使用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");

现在我认为问题出在哪里,当我在前端获取 JSON 并将其记录到控制台时,这就是我所看到的:

{
  "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"
      }
    }
  ]
}

【问题讨论】:

  • 去掉, Formatting.Indented会有什么结果?
  • 它对你的 json 进行双重编码,例如它可以显示为 html。显示您如何在视图中输出它。我敢打赌,您正在使用类似 @ViewBag.nearbyStores 的东西,这将导致它被编码为 html 实体
  • @Daniel 同样的结果
  • @pinkfloydx33 喜欢这个var stores = '@ViewBag.nearbyStores'; var geojson = JSON.parse(stores);

标签: javascript c# json asp.net-mvc asp.net-core


【解决方案1】:

您最终会双重转义/编码 JSON。在大多数情况下,Razor Helper @ 会尝试对输入进行编码并返回 HTML 实体,例如引号、& 符号、较小/较大符号等。

您可以使用@Html.Raw 方法来指示输入已经是一个编码字符串。

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

但请注意,我会小心的。您永远不知道源变量中可能会导致某种注入攻击的内容(例如未转义的单引号)。

应该能够完全避免额外的解析:

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

但前提是 nearbyStores 实际上是有效的 JSON。

您可以使用JsonHelper.Serialize 将其作为视图的职责,而不是在您的控制器中进行序列化

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

【讨论】:

  • 或者更好的是,您可以只使用@Html.Raw(ViewBag.nearbyStores),无需进一步解析。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-14
相关资源
最近更新 更多