3

I'm facing an issue to display data after deserialization in a .net core 2.0 app. this is what I'm trying to do : 1- unzip a file sended by POST request (DONE) 2- create the data model (DONE) 3- display data (NOT OK)

this is my controller :

ValuesController

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using HelloWorld.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace HelloWorld.Controllers
{
    [Route("")]
    public class ValuesController : Controller
    {

        // POST api/<controller>

        [HttpGet]
        [Route("/Values/Index")]

    public IActionResult Index()
{
        using (StreamReader r = new StreamReader("c:\\temp\\inplay-soccer.json"))
        {
            string json = r.ReadToEnd();
            var objects = JsonConvert.DeserializeObject<Goalserve>(json);
            return View(objects);
        }
}

        [HttpPost]
        [Consumes("application/gzip")]
        public async Task<IActionResult> PostAsync(IFormFile file)
        {

                WebClient Client = new WebClient();
                Client.DownloadFile("http://inplay.goalserve.com/inplay-soccer.gz", "C:\\temp\\inplay-soccer.gz");
                using (var inputFileStream = new FileStream("c:\\temp\\inplay-soccer.gz", FileMode.Open))
                using (var gzipStream = new GZipStream(inputFileStream, CompressionMode.Decompress))
                using (var outputFileStream = new FileStream("c:\\temp\\inplay-soccer.json", FileMode.Create))
                {
                    await gzipStream.CopyToAsync(outputFileStream);
                }
                return Ok();
        }

        // PUT api/<controller>/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/<controller>/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }

        public class Value
        {
            public int Id { get; set; }
        }
    }
}

this is the model:

Goalserver class

using Newtonsoft.Json; using Newtonsoft.Json.Converters; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading.Tasks;

namespace HelloWorld.Models {
    public partial class Goalserve
    {
        [JsonProperty("updated")]
        public string Updated { get; set; }

        [JsonProperty("updated_ts")]
        public long UpdatedTs { get; set; }

        [JsonProperty("events")]
        public Events Events { get; set; }
    }

    public partial class Events
    {
        [JsonProperty("84586848")]
        public The84586848 The84586848 { get; set; }
    }

    public partial class The84586848
    {
        [JsonProperty("core")]
        public Core Core { get; set; }

        [JsonProperty("info")]
        public InfoClass Info { get; set; }

        [JsonProperty("stats")]
        public Dictionary<string, Stat> Stats { get; set; }

        [JsonProperty("odds")]
        public Dictionary<string, Odd> Odds { get; set; }
    }

    public partial class Core
    {
        [JsonProperty("safe")]
        public long Safe { get; set; }

        [JsonProperty("stopped")]
        public long Stopped { get; set; }

        [JsonProperty("blocked")]
        public long Blocked { get; set; }

        [JsonProperty("finished")]
        public long Finished { get; set; }

        [JsonProperty("updated")]
        public DateTimeOffset Updated { get; set; }

        [JsonProperty("updated_ts")]
        public long UpdatedTs { get; set; }
    }

    public partial class InfoClass
    {
        [JsonProperty("id")]
        public long Id { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("sport")]
        public string Sport { get; set; }

        [JsonProperty("league")]
        public string League { get; set; }

        [JsonProperty("start_time")]
        public string StartTime { get; set; }

        [JsonProperty("start_date")]
        public string StartDate { get; set; }

        [JsonProperty("start_ts")]
        public long StartTs { get; set; }

        [JsonProperty("period")]
        public string Period { get; set; }

        [JsonProperty("minute")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long Minute { get; set; }

        [JsonProperty("secunds")]
        public string Secunds { get; set; }

        [JsonProperty("score")]
        public string Score { get; set; }

        [JsonProperty("points")]
        public string Points { get; set; }

        [JsonProperty("pitch")]
        public string Pitch { get; set; }

        [JsonProperty("ball_pos")]
        public string BallPos { get; set; }

        [JsonProperty("add_time")]
        public string AddTime { get; set; }

        [JsonProperty("player")]
        public string Player { get; set; }

        [JsonProperty("state")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long State { get; set; }
    }

    public partial class Odd
    {
        [JsonProperty("id")]
        public long Id { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("short_name")]
        public string ShortName { get; set; }

        [JsonProperty("suspend")]
        public long Suspend { get; set; }

        [JsonProperty("order")]
        public long Order { get; set; }

        [JsonProperty("info")]
        public InfoEnum Info { get; set; }

        [JsonProperty("participants")]
        public Dictionary<string, Participant> Participants { get; set; }
    }

    public partial class Participant
    {
        [JsonProperty("id")]
        public long Id { get; set; }

        [JsonProperty("order")]
        public long Order { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("short_name")]
        public string ShortName { get; set; }

        [JsonProperty("value_eu")]
        public string ValueEu { get; set; }

        [JsonProperty("value_na")]
        public string ValueNa { get; set; }

        [JsonProperty("value_us")]
        public string ValueUs { get; set; }

        [JsonProperty("handicap")]
        public string Handicap { get; set; }

        [JsonProperty("suspend")]
        public long Suspend { get; set; }
    }

    public partial class Stat
    {
        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("home")]
        public string Home { get; set; }

        [JsonProperty("away")]
        public string Away { get; set; }
    }

    public enum InfoEnum { Count070007959, CurrentCorners11, Empty };

    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                InfoEnumConverter.Singleton,
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }

    internal class ParseStringConverter : JsonConverter
    {
        public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);

        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null) return null;
            var value = serializer.Deserialize<string>(reader);
            long l;
            if (Int64.TryParse(value, out l))
            {
                return l;
            }
            throw new Exception("Cannot unmarshal type long");
        }

        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
        {
            if (untypedValue == null)
            {
                serializer.Serialize(writer, null);
                return;
            }
            var value = (long)untypedValue;
            serializer.Serialize(writer, value.ToString());
            return;
        }

        public static readonly ParseStringConverter Singleton = new ParseStringConverter();
    }

    internal class InfoEnumConverter : JsonConverter
    {
        public override bool CanConvert(Type t) => t == typeof(InfoEnum) || t == typeof(InfoEnum?);

        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null) return null;
            var value = serializer.Deserialize<string>(reader);
            switch (value)
            {
                case "":
                    return InfoEnum.Empty;
                case "Count : 0 (70:00 - 79:59)":
                    return InfoEnum.Count070007959;
                case "Current Corners : 11":
                    return InfoEnum.CurrentCorners11;
            }
            throw new Exception("Cannot unmarshal type InfoEnum");
        }

        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
        {
            if (untypedValue == null)
            {
                serializer.Serialize(writer, null);
                return;
            }
            var value = (InfoEnum)untypedValue;
            switch (value)
            {
                case InfoEnum.Empty:
                    serializer.Serialize(writer, "");
                    return;
                case InfoEnum.Count070007959:
                    serializer.Serialize(writer, "Count : 0 (70:00 - 79:59)");
                    return;
                case InfoEnum.CurrentCorners11:
                    serializer.Serialize(writer, "Current Corners : 11");
                    return;
            }
            throw new Exception("Cannot marshal type InfoEnum");
        }

        public static readonly InfoEnumConverter Singleton = new InfoEnumConverter();
    } }

Now, How can I do to display the data in a view ?

I created a corresponding View named "Index.cshtml" and trying to use ViewData but I don't know how to do. This is my View code

Index.cshtml

@page
@model HelloWorld.Models.Goalserve
@{
    var objects = ViewData["Objects"];
}
<table>
    <tr>
        test
        <td>@objects.ToString()</td>
    </tr>
</table>

I know the View code "Index" is wrong. What should I do to display the deserialized JSON feed (each info in one line for example) ? (I need to display data in [Route("/Values/Index")])

Thank you !

EDIT : ERROR -> AspNetCore.Views_Values_Index+<ExecuteAsync>d__0.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Razor.RazorView+<RenderPageCoreAsync>d__20.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Razor.RazorView+<RenderPageAsync>d__19.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Razor.RazorView+<RenderAsync>d__18.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor+<ExecuteAsync>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor+<ExecuteAsync>d__21.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor+<ExecuteAsync>d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.ViewResult+<ExecuteResultAsync>d__26.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeResultAsync>d__20.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResultFilterAsync>d__28.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeResultFilters>d__26.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResourceFilter>d__23.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeFilterPipelineAsync>d__18.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeAsync>d__16.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()

Show raw exception details
System.NullReferenceException: Object reference not set to an instance of an object.
   at AspNetCore.Views_Values_Index.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.<RenderPageCoreAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.<RenderPageAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.<RenderAsync>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.<ExecuteAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.<ExecuteAsync>d__21.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.<ExecuteAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.ViewResult.<ExecuteResultAsync>d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeResultAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextResultFilterAsync>d__28`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeResultFilters>d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextResourceFilter>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__16.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
amin89
  • 558
  • 1
  • 8
  • 26
  • 1
    Could you post your Goalserve class definition as well? Thank you. – sam Dec 16 '19 at 14:04
  • Sorry it was a mistake. Feed class is actually goalserve class. – amin89 Dec 16 '19 at 14:06
  • I made an EDIT. ty. – amin89 Dec 16 '19 at 14:07
  • 1
    If you want to display JSON, why are you deserialising it in the first place? – DavidG Dec 16 '19 at 14:09
  • I want to display the deserialized data not json data. Another mistake made in the topic sorry. – amin89 Dec 16 '19 at 14:10
  • You did not assign anything to ViewData and that is the reason why view is not displaying any data. Since you are using strongly-typed object, in your view, you can directly access it via Model (try to type @ and you will get help from IDE. The properties of Goalserve can be accessed via Model.Updated..etc) Or if you wanted to display or access via ViewData, please modify your controller like ViewData["objects"] = objects. – sam Dec 16 '19 at 14:18

2 Answers2

1

Please modify your index.cshtml as below:

@model HelloWorld.Models.Goalserve
@{
    var objects = Model; //ViewData["Objects"];
}
<table>
    <tr>
        test
        <td>@objects.ToString()</td>
    </tr>

Please modify your Goalserve and Events as below:

public partial class Goalserve
{
    [JsonProperty("updated")]
    public string Updated { get; set; }

    [JsonProperty("updated_ts")]
    public long UpdatedTs { get; set; }

    [JsonProperty("events")]
    //public Events Events { get; set; }
    public Dictionary<string, Events> Events { get; set; }

    public override string ToString()
    {
        return string.Format($"Updated={this.Updated} and UpdatedTs={this.UpdatedTs} and EventsCount={this.Events.Count}");
    }
}

public partial class Events
{
    //[JsonProperty("84586848")]
    public The84586848 The84586848 { get; set; }
}

Please modify your Converter to include ParseStringConverter as well:

internal static class Converter
{
    public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        DateParseHandling = DateParseHandling.None,
        Converters =
        {
            InfoEnumConverter.Singleton,
            ParseStringConverter.Singleton,
            new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
        },
    };
}

Then finally modify your Controller Action to use your custom settings as below:

using (StreamReader r = new StreamReader("c:\\temp\\inplay-soccer.json"))
{
    string json = r.ReadToEnd();
    objects = JsonConvert.DeserializeObject<Goalserve>(json, Converter.Settings);
    return View(objects);
}

The above code working fine with the sample json (text file) that you have attached. Your attached json does not have object under events collection matching to key 84586848. enter image description here

Side but related note: if you want to let NewtonSoft Json to use camelCase, then you can use ContractResolver = new CamelCasePropertyNamesContractResolver() instead of adding [JsonProperty] annotation to properties. For e.g.,

internal static class Converter
{
    public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        DateParseHandling = DateParseHandling.None,
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        Converters =
        {
            InfoEnumConverter.Singleton,
            ParseStringConverter.Singleton,
            new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
        },
    };
}
sam
  • 1,937
  • 1
  • 8
  • 14
  • I have this error : NullReferenceException: Object reference not set to an instance of an object. When I do a debug, I can see there's a breakpoint which is by-passed in visual studio. it concerns this line : var objects = JsonConvert.DeserializeObject(json) I think "return View(objects) return "null" More details in Topic EDIT – amin89 Dec 16 '19 at 14:38
  • 1
    without having sample json, we can not do much help here. – sam Dec 16 '19 at 14:57
  • 1
    Unable to open the link. It says "Something went wrong" and page is redirected to home page – sam Dec 16 '19 at 16:07
  • Sorry. https://filebin.net/k5enw2wn4f5bc89m/inplay-soccer.json?t=84y0df94 – amin89 Dec 16 '19 at 17:00
  • 1
    Yes, please include your custom convert settings (Converter.Settings) while deserializing. I updaetd my post with the same. – sam Dec 16 '19 at 21:56
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/204373/discussion-between-amin89-and-sam). – amin89 Dec 16 '19 at 23:42
  • I changed the code and there's always the same problem null pointer exception : https://filebin.net/45ankop7wut68nyu/error.png?t=lc3xvbjj – amin89 Dec 16 '19 at 23:46
  • I think The problem is with stream reader https://filebin.net/sydou895xqfgcqw4/streamreader_error.png?t=nzstv99u – amin89 Dec 17 '19 at 00:05
  • If you think, StreamReader is causing the issue, I would first verify whether inplay-soccer.json exists in c:\temp directory or not. Also, have a break point in your controller action and note the exact exception because your stack trace is not helping and tells me that the issue is with your view while displaying data rather than controller action. Please see the attachment of working copy of my code – sam Dec 17 '19 at 05:09
  • OK now it's better. Actually, it's not the .json file the problem. I added this in my controller : Goalserve objects = new Goalserve(); before it was this : dynamic objects = JsonConvert.DeserializeObject(json, Converter.Settings); PS: it could be interesting to explain to me why dynamic object is not fine here. Now I have my Goalserve Objects (in debugger mode) but in the view "index" I have this error : https://filebin.net/cgt5ny58nqoymt91/error.txt?t=v8nn464c – amin89 Dec 17 '19 at 10:33
  • 1
    Thank you Sam. It was another mistake from my side ...... there was @page in my "index.cshtml ...... a Razor page into .NET Core app .... logically it will fail. – amin89 Dec 17 '19 at 12:01
  • 1
    Please refer the link https://stackoverflow.com/questions/31859016/is-the-use-of-dynamic-considered-a-bad-practice – sam Dec 17 '19 at 13:46
  • Hi @Sam, my feed provider provide me the json file each 1-3 seconds through POST request. I want to display "ball position" info in realtime in my view "Index" for each match. How can I display "easily" this info ? I need to make a refresh of this page each time I receive a new json file and treat it -> A new line will be created with ball position info each time I receive a new json file. I only need a simple example to do it. thanks ! PS : I only need an idea of how I can implement it – amin89 Dec 17 '19 at 20:14
  • 1
    You will need to do it via polling... Idea is, have a javascript timer in the page and poll your MVC action via ajax and update the section of your page. Since you will need to poll, I would move your MVC VIEW as partial view so its easy to refresh the view continuously. – sam Dec 17 '19 at 20:27
  • Hi @Sam, I'm facing a huge problem to deserialize my json feed ! Like you can see here https://filebin.net/k5enw2wn4f5bc89m/inplay-soccer.json?t=84y0df94, the json file received by my provider is huge (even 2000ko sometimes) Do you have an idea how I can optimize the deserialization ? I'm pretty sure the problem is at this point of code : objects = JsonConvert.DeserializeObject(json, Converter.Settings); When I do something after this part of code, it can't process ... So how can I optimize the json deserialization (after deserialize, I put all data in sql server db ...) – amin89 Dec 22 '19 at 17:07
  • this is my problem now: https://stackoverflow.com/questions/59454040/problem-of-performance-optimize-json-deserialization-speed-in-c-sharp – amin89 Dec 23 '19 at 10:52
1

For you json file:

  • You have a model property named 84586848 with JsonProperty,but your json does not contain such property.
  • You have switch-case statement in InfoEnumConverter.It has three possibilities and it would throw exception if it has the other type.You need to set the default return value instead of throwing exception.(Note:You need to add [JsonConverter(typeof(InfoEnumConverter))] to your InfoEnum Info property )

To fit with your json file,you need to change the model like below:

public partial class Goalserve
{
    [JsonProperty("updated")]
    public string Updated { get; set; }
    [JsonProperty("updated_ts")]
    public long UpdatedTs { get; set; }
    [JsonProperty("events")]
    public Dictionary<string, The84586848> Events { get; set; }
}

//public partial class Events
//{
//    [JsonProperty("84586848")]
//    public The84586848 The84586848 { get; set; }
//}

public partial class The84586848
{
    [JsonProperty("core")]
    public Core Core { get; set; }
    [JsonProperty("info")]
    public InfoClass Info { get; set; }
    [JsonProperty("stats")]
    public Dictionary<string, Stat> Stats { get; set; }
    [JsonProperty("odds")]
    public Dictionary<string, Odd> Odds { get; set; }
}

public partial class Core
{
    [JsonProperty("safe")]
    public long Safe { get; set; }
    [JsonProperty("stopped")]
    public long Stopped { get; set; }
    [JsonProperty("blocked")]
    public long Blocked { get; set; }
    [JsonProperty("finished")]
    public long Finished { get; set; }
    [JsonProperty("updated")]
    public DateTimeOffset Updated { get; set; }
    [JsonProperty("updated_ts")]
    public long UpdatedTs { get; set; }
}
public partial class InfoClass
{
    [JsonProperty("id")]
    public long Id { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("sport")]
    public string Sport { get; set; }
    [JsonProperty("league")]
    public string League { get; set; }
    [JsonProperty("start_time")]
    public string StartTime { get; set; }
    [JsonProperty("start_date")]
    public string StartDate { get; set; }
    [JsonProperty("start_ts")]
    public long StartTs { get; set; }
    [JsonProperty("period")]
    public string Period { get; set; }

    [JsonConverter(typeof(ParseStringConverter))]
    [JsonProperty("minute")]
    public long Minute { get; set; }

    [JsonProperty("secunds")]
    public string Secunds { get; set; }
    [JsonProperty("score")]
    public string Score { get; set; }
    [JsonProperty("points")]
    public string Points { get; set; }
    [JsonProperty("pitch")]
    public string Pitch { get; set; }
    [JsonProperty("ball_pos")]
    public string BallPos { get; set; }
    [JsonProperty("add_time")]
    public string AddTime { get; set; }
    [JsonProperty("player")]
    public string Player { get; set; }

    [JsonConverter(typeof(ParseStringConverter))]
    [JsonProperty("state")]
    public long State { get; set; }
}

public partial class Odd
{
    [JsonProperty("id")]
    public long Id { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("short_name")]
    public string ShortName { get; set; }
    [JsonProperty("suspend")]
    public long Suspend { get; set; }
    [JsonProperty("order")]
    public long Order { get; set; }

    [JsonProperty("info")]
    [JsonConverter(typeof(InfoEnumConverter))]
    public InfoEnum Info { get; set; }

    [JsonProperty("participants")]
    public Dictionary<string, Participant> Participants { get; set; }
}

public partial class Participant
{
    [JsonProperty("id")]
    public long Id { get; set; }

    [JsonProperty("order")]
    public long Order { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("short_name")]
    public string ShortName { get; set; }

    [JsonProperty("value_eu")]
    public string ValueEu { get; set; }

    [JsonProperty("value_na")]
    public string ValueNa { get; set; }

    [JsonProperty("value_us")]
    public string ValueUs { get; set; }

    [JsonProperty("handicap")]
    public string Handicap { get; set; }

    [JsonProperty("suspend")]
    public long Suspend { get; set; }
}

public partial class Stat
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("home")]
    public string Home { get; set; }

    [JsonProperty("away")]
    public string Away { get; set; }
}

public enum InfoEnum { Count070007959, CurrentCorners11, Empty,OtherType };

public class ParseStringConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null) return null;
        var value = serializer.Deserialize<string>(reader);
        long l;
        if (Int64.TryParse(value, out l))
        {
            return l;
        }
        throw new Exception("Cannot unmarshal type long");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
    {
        if (untypedValue == null)
        {
            serializer.Serialize(writer, null);
            return;
        }
        var value = (long)untypedValue;
        serializer.Serialize(writer, value.ToString());
        return;
    }

    public static readonly ParseStringConverter Singleton = new ParseStringConverter();
}

public class InfoEnumConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(InfoEnum) || t == typeof(InfoEnum?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null) return null;
        var value = serializer.Deserialize<string>(reader);
        switch (value)
        {
            case "":
                return InfoEnum.Empty;
            case "Count : 0 (70:00 - 79:59)":
                return InfoEnum.Count070007959;
            case "Current Corners : 10":
                return InfoEnum.CurrentCorners11;
            default:
                return InfoEnum.OtherType;
        }
        //throw new Exception("Cannot unmarshal type InfoEnum");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
    {
        if (untypedValue == null)
        {
            serializer.Serialize(writer, null);
            return;
        }
        var value = (InfoEnum)untypedValue;
        switch (value)
        {
            case InfoEnum.Empty:
                serializer.Serialize(writer, "");
                return;
            case InfoEnum.Count070007959:
                serializer.Serialize(writer, "Count : 0 (70:00 - 79:59)");
                return;
            case InfoEnum.CurrentCorners11:
                serializer.Serialize(writer, "Current Corners : 11");
                return;
        }
        throw new Exception("Cannot marshal type InfoEnum");
    }

    public static readonly InfoEnumConverter Singleton = new InfoEnumConverter();
}

For your View:

You do not store data to ViewData["objects"],so you make the error,you could modify like below:

1.Controller:

[HttpGet]
public IActionResult Index()
{
    using (StreamReader r = new StreamReader("c:\\temp\\inplay-soccer.json"))
    {
        string json = r.ReadToEnd();
        var objects = JsonConvert.DeserializeObject<Goalserve>(json);              
        return View(objects);
    }
}

2.View:

@model Goalserve
@{ 
    var data = Model.Events.Keys.ToArray();
}
<table class="table">

    <tr>
        <td>@Model.Updated</td>
    </tr>
    <tr>
        <td>@Model.UpdatedTs</td>
    </tr>
    <tr>
        @for (var i = 0; i < data.Count(); i++)
        {
            <td>@Model.Events[data[i].ToString()].Core.Updated</td>
            <td>@Model.Events[data[i].ToString()].Core.UpdatedTs</td>
            <td>@Model.Events[data[i].ToString()].Info.Points</td>
            <td>@Model.Events[data[i].ToString()].Info.Score</td>
            //more property...
        }
    </tr>  
</table>

Note:This way is not easy and complex to display the data to the view.If you do not want to change your model.I suggest that you could also generate the json file like below,due to you only have one Event(public Events Events { get; set; } ) in your Goalserve Model:

{
  "updated": "15.12.2019 23:30:52",
  "updated_ts": 1576449052,
  "events": {
    "84586848": {
      "core": {
        "safe": 0,
        "stopped": 0,
        "blocked": 0,
        "finished": 0,
        "updated": "2019-12-15 23:31:02",
        "updated_ts": 1576452662
      },
      "info": {
        //...
      },
      "stats": {
        "0": {
          "name": "ITeam",
          "home": "Five Islands",
          "away": "Pigotts Bullets FC"
        },
        "1": {
          "name": "IGoal",
          "home": "0",
          "away": "0"
        }
      },
      "odds": {
        "0": {
         // ...
          }
        },
        "1": {
          //...
      }
    }
  }
}
Rena
  • 30,832
  • 6
  • 37
  • 72