简体   繁体   中英

Problem to display json data in .NET core 2.0

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()

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. 在此处输入图片说明

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 eg,

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 }
        },
    };
}

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": {
          //...
      }
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM