Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C# / MVC / WebApi] Verwijderen van [ en ]

Pagina: 1
Acties:

  • diabolofan
  • Registratie: Mei 2009
  • Laatst online: 13-11 08:57
Hallo luitjes,

Ben een WebApi aan het maken die JSON en XML kan teruggeven. Lijkt simpel, en dat hoort het naar mijn idee ook te zijn.

Momenteel laat de api gewoon (een lijst met) objecten teruggeven, en de WebApi kijkt dan zelf naar de Accept-header van de request, om te bepalen wat die er van moet maken. Bij XML werkt het allemaal prima, maar JSON geeft toch net wat meer problemen. Er wordt JSON teruggegeven, maar aan het begin wordt een [ en aan het einde wordt een ] toegevoegd aan de JSON-string. Hierdoor gaat het deserializen naar objecten fout. Ik maak gebruik van de Newtonsoft.NET library om te deserializen, met de function JObject.Parse(string). In verband met de [ en ] (een array) dient dit dus met JArray.Parse te gebeuren. Dit is alleen niet gewenst, omdat WebApi voor mijn gevoel heus wel in staat moet zijn om nette correct JSON terug te geven.

Mogelijke oplossingen voor dit probleem:
  • Zelf handmatig met een string replace de [ en ] verwijderen. Niet wenselijk uiteraard, dus geen oplossing
  • Schijnt volgens Google: XML formatter uitzetten. Dit heb ik niet uitgeprobeerd, maar is onwenselijk, want de Api moet ook XML kunnen teruggeven
Nu is mijn inspiratie daarom dus een beetje op. In het kort gezegd doet de WebApi dus te bijhand door er een array van te willen maken.

Voor de beeldvorming nog wat code voorbeelden.
API
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
        [HttpGet]
        [CacheOutput(ClientTimeSpan = 30, ServerTimeSpan = 30)]
        public List<Song> Psalms()
        {
            using (ContextService contextService = new ContextService())
            {
                SongService songService = new SongService(contextService);

                List<Song> songs = songService.Get(SongType.Psalm);

                return songs;
            }
        }

Aanroep
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
        public void CreateRequest(String path, RequestType requestType)
        {
            this.httpWebRequest = (HttpWebRequest)WebRequest.Create(Business.Properties.Resources.BaseUrl + path);
            this.httpWebRequest.ContentType = "application/json";
            this.httpWebRequest.Accept = "application/json";

            this.httpWebRequest.Method = requestType.GetText();
        }


        public JObject ExecuteRequest()
        {
            _ready.Reset();

            this.httpWebRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);

            _ready.WaitOne();

            return this.ReadStreamFromResponse(this.webResponse);
        }

        private void FinishWebRequest(IAsyncResult result)
        {
            webResponse = this.httpWebRequest.EndGetResponse(result);

            _ready.Set();
        }

        private JObject ReadStreamFromResponse(WebResponse response)
        {
            using (Stream responseStream = response.GetResponseStream())
            {
                using (StreamReader streamReader = new StreamReader(responseStream))
                {
                    return JObject.Parse(streamReader.ReadToEnd());
                }
            }
        }


Bij de return van ReadStreamFromResponse faalt hij hun dus.

Mocht iemand een mooie oplossing hebben, dan hoor ik het graag!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
C#:
1
public List<Song> Psalms() 

Je geeft toch ook een List terug :? (Wat in JSON gewoon een array is, en **dus** [ en ] eromheen).

Wat is de JSON waar 't op mis gaat? Want het is wel handig om die erbij te zien ;)

[ Voor 23% gewijzigd door RobIII op 01-03-2014 15:24 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • diabolofan
  • Registratie: Mei 2009
  • Laatst online: 13-11 08:57
Uumh, ja, dat is waar... |:( Die [ en ] zijn dus gewoon terecht, en ik moet dus gewoon beter eerst de syntax doornemen voordat ik onzin praat :D

Bedankt in ieder geval. Ik ga me even schamen ergen.s 8)7

  • Lethalis
  • Registratie: April 2002
  • Niet online
Lol :D

Ask yourself if you are happy and then you cease to be.


  • maxtz0r
  • Registratie: Februari 2007
  • Laatst online: 17-12-2022
Sorry dat ik op dit topic inhaak maar mijn probleem heeft wel wat vergelijking en dacht dat het beter was hierop te reageren dan een nieuw topic te maken, mocht ik een nieuw topic moeten maken hoor ik dat wel.

Mijn probleem is in zoverre vergelijkbaar dat de API(extern geen invloed op) in de documentatie aangeeft een JSON array terug te geven maar dit alleen doet indien het resultaat groter is dan 1. De json heeft dan gewoon netjes [ ] eromheen. Bij 1 resultaat wordt het niet in een array gezet en gaat mijn code over de zeik:

code:
1
dynamic result = JsonConvert.DeserializeObject<TestObject>(await task.Content.ReadAsStringAsync());


Dit geeft mij de melding "Cannot deserialize the current JSON..." wat heel logisch is gezien de array weg is. Het probleem is dat mijn JSON er ongeveer zo uit ziet(let op, uit de losse vingers):

JSON:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{{
    "ObjectX": {
        "AttrA": "Lorem",
        "AttrB": "Ipsum",
        "AttrC": "X-man",
        "Objects": {
            "@size": "2",
            "Object": [
                {
                    "String": "Plaap"
                },
                {
                    "String": "Plaap2"
                }
            ]
        }
    }
}


en mijn classes:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Objects
{
    public string size { get; set; }
    public List<Object> Object{ get; set; }
}
public class Object
{
    public string Object{ get; set; }
}
public class ObjectX
{
    public string AttrA { get; set; }
    public string AttrB { get; set; }
    public string AttrC { get; set; }
    public Objects Objects { get; set; }
}


De vraag is eigenlijk hoe kan ik hiermee omgaan. Het resultaat van Objects kan dus een array bevatten maar indien het resultaat 1 is vind de API het een goed idee om dit niet te doen. Eigenlijk zoek ik naar een generieke methode omdat dit door de hele API consistent is.

Dying is God's way of telling you, you've been FIRED.


Verwijderd

Zo op het eerste zicht adhv je voorbeeldjson

Moet
code:
1
2
3
4
public class Object
{
    public string Object{ get; set; }
}

niet public string String { get; set; } zijn?

  • Soundless
  • Registratie: November 2008
  • Laatst online: 29-10 16:54
Als er geen betere oplossing is, kun je een custom media type formatter schrijven die ervor zorgt dat als je geen array hebt, je er toch een array van maakt en hier vervolgens JSON.Net overheen gooit.

Zie bv http://www.asp.net/web-ap...-binding/media-formatters

  • maxtz0r
  • Registratie: Februari 2007
  • Laatst online: 17-12-2022
Verwijderd schreef op maandag 12 januari 2015 @ 14:05:
Zo op het eerste zicht adhv je voorbeeldjson

Moet
code:
1
2
3
4
public class Object
{
    public string Object{ get; set; }
}

niet public string String { get; set; } zijn?
Ja, je hebt gelijk. Niet goed overgenomen van de daadwerkelijke class.


Soundless schreef op maandag 12 januari 2015 @ 14:15:

Als er geen betere oplossing is, kun je een custom media type formatter schrijven die ervor zorgt dat als je geen array hebt, je er toch een array van maakt en hier vervolgens JSON.Net overheen gooit.

Zie bv http://www.asp.net/web-ap...-binding/media-formatters
Ik zal hier eens induiken. Het lijkt er namelijk op dat er geen "makkelijke" oplossing is.

Wellicht dan toch een lelijke "hack" door aan de hand van @size(@size = 1) een andere deserialize methode gebruiken.

Dying is God's way of telling you, you've been FIRED.

Pagina: 1