2016-05-16 13 views
3

Ich brauche eine Microsoft.AspNet.Mvc.Controller.JsonResult in eine Zeichenfolge konvertieren mit ASP.NET CoreJSON konvertieren JsonResult zu JavaScript-String ohne Anführungszeichen kodieren

Hier ist mein Code in ASP.NET MVC

public async Task<string> GetJsonData() 
{ 
    //... 
    var result = GetMyComplexObject(); 

    //using Newtonsoft.Json.JsonConvert method 
    var jsonString = JsonConvert.SerializeObject(Json(result)); 
    return jsonString; 
} 

public async Task<IActionResult> Index() 
{ 
    var myViewModel= new MyViewModel(); 
    myViewModel.JsonString = GetJsonData(); 
    return View(myViewModel); 
} 

public class MyViewModel 
{ 
    //... 
    public string JsonString { get; set; } 
} 

und in meinem cshtml

var dataSet = {@(Model.JsonString))}; 

Jedoch in der generierten Quelle anstelle der Felder in Zitaten sind sie HTML-codiert z. B. &quot;field1&quot;

Statt Laufstrang ersetzt ist es keine ordentliche Art und Weise einen JsonResult zu string

+0

in Debugger es auf diese Weise zeigt –

+0

Sie könnten JIL versuchen (Disclaimer dies war ein Tool von SO gemacht) https://github.com/kevin-montrose/Jil – Pseudonym

Antwort

8

In ASP.Net 5 befindet sich eine JsonHelper direkt in den Rasierer Ansichten über @Json.Serialize, so dass Sie in Ihren Rasierer Blick so etwas schreiben:

var foo = @Json.Serialize(model); 

Dies ist sehr ähnlich zu tun manuell:

Das Problem in beiden Fällen ist, dass JSON.Net standardmäßig serialisiert, aber nicht XSS-die Ausgabe bereinigt. Dies bedeutet, dass der Inhalt von Modell nicht maskiert ist, sodass der Code für XSS attacks offen bleibt, wenn das Modell von Benutzereingaben abhängig ist. Zum Beispiel:

@{ 
    var model = new 
    { 
     prop1 = 1, 
     prop2 = "</script><script>alert('o hai');</script>", 
     prop3 = false 
    }; 
} 
var foo = @Json.Serialize(model); 

könnten Sie verwenden die Json.Serialize Überlastung, die Sie JsonSerializerSettings angeben können, so können Sie StringEscapeHandling als escape gesetzt:

HTML (<,>, &‘,„) und Kontrolle Zeichen (zB newline) sind entkommen.

var foo = @Json.Serialize(model, new JsonSerializerSettings { StringEscapeHandling = StringEscapeHandling.EscapeHtml }); 

PS. ich habe angehoben ein Problem auf github zu Standard-HTML-Escaping in der JsonHelper enthalten.

Ansätze in früheren Versionen verwendet

Wenn Sie diese gleiche Frage auf Stack-Überlauf, finden Sie dort gebraucht ein Json.Encode Helfer in früheren Versionen von MVC zu sein, so dass Sie like this serialisiert konnten, manuell durchführen die JS Serialisierung. Dies scheint durch Json.Serialize ersetzt, die standardmäßig nicht sicher ist.

Dort war auch ein Helfer HttpUtility.JavaScriptStringEncode, der verwendet werden könnte, um json-Literale manuell zu kodieren. Dies scheint in ASP.Net 5 als IJavaScriptStringEncoder zu sein. Das einzige Problem ist, dass es, wenn es mit Newtonsoft.Json (dem Standard-Json-Formatierer in ASP.Net 5) kombiniert wird, zu viel für ein gültiges Json-Literal codiert (wie die doppelten Anführungszeichen in Eigenschaftsnamen). Allerdings wird es eine gültige Zeichenfolge produzieren, die auf dem Browser mit JSON.parse analysiert werden können (also wahrscheinlich this approach sollte auch funktionieren):

@inject Microsoft.Extensions.WebEncoders.IJavaScriptStringEncoder encoder; 
... 
var foo = JSON.parse("@encoder.JavaScriptStringEncode(JsonConvert.SerializeObject(model))"); 

auch bewusst sein, dass auf dem neuesten Quellcode sucht, wird die IJavaScriptStringEncoder sein ersetzt durch System.Text.Encodings.Web.JavaScriptEncoder in RC2.

+0

Dies ist, was ich suchte nach @ Json.Serialize (Model); ', große Antwort auch. Vielen Dank!! –

+0

Danke für diese großartige Antwort! Bei der Verwendung der ASP.Net 5-Version mit JsonSerializerSettings kann es erforderlich sein, dass der Entwickler der Ansicht '@ using Newtonsoft.Json' hinzufügt, um den JasonSerializerSettings-Namespace in den Gültigkeitsbereich zu bringen. –

1

String zu konvertieren - JavaScriptSerializer: (Nicht in ASP.NET-Core verwenden)

var json = new JavaScriptSerializer().Serialize(jsonResult.Data); 

Objekt - Newtonsoft.Json:

var json = JsonConvert.SerializeObject(jsonResult.Data, Formatting.Indented, new KeysJsonConverter(typeof(OBJECT))); 

KeysJsonConverter

using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 
using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace TestApp.Helpers 
{ 
    // Creates a custom JsonConverter that overrides serialization to add a keys property. 

    public class KeysJsonConverter : JsonConverter 
    { 
     private readonly Type[] _types; 

     public KeysJsonConverter(params Type[] types) 
     { 
      _types = types; 
     } 

     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
     { 
      JToken t = JToken.FromObject(value); 

      if (t.Type != JTokenType.Object) 
      { 
       t.WriteTo(writer); 
      } 
      else 
      { 
       JObject o = (JObject)t; 
       IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList(); 

       o.AddFirst(new JProperty("Keys", new JArray(propertyNames))); 

       o.WriteTo(writer); 
      } 
     } 

     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
     { 
      throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter."); 
     } 

     public override bool CanRead 
     { 
      get { return false; } 
     } 

     public override bool CanConvert(Type objectType) 
     { 
      return _types.Any(t => t == objectType); 
     } 
    } 
} 

.cshtml

var model = @Html.Raw(Json.Encode(Model)); 

nicht sicher, wo ich KeysJsonConverter bekam aus, aber ich habe es in einigen Projekten eingesetzt ich gebaut habe und es funktioniert sehr gut, Kredit an denjenigen, der es ursprünglich geschrieben hat.

+0

JavaScriptSerializer von dem, was ich weiß, kann nicht in ASP.NET Core verwendet werden, da es Teil des System-Namespace ist – greay

+0

Er serialisiert ein Objekt trotzdem mit Newtonsoft.Json.JsonConvert-Methode, die ich oben gezeigt habe :) Sie haben Recht, Sie können ' Verwenden Sie JavaScriptSerializer in ASP.NET Core. Sie können Newtonsoft.Json jedoch als eine Abhängigkeit von Microsoft.AspNet.Mvc.ModelBinding verwenden. – David

1

könnten Sie Newtonsoft verwenden

"Newtonsoft.Json": "6.0.8", 

und dann auf Ihrem JsonResult Objekt in der Controller

using Newtonsoft.Json; 

und

var jsonResult = Json(myObject); 

string jsonString= JsonConvert.SerializeObject(jsonResult.Value); 
Verwandte Themen