How can I fully instantiate the Photo Entity - asp.net

public class Child
{
public int Cld { get; set; }
public string ChildCode { get; set; }
public string FirstName { get; set; }
public string SurName { get; set; }
public string Sex { get; set; }
public DateTime DateOfBirth { get; set; }
public DateTime FoundRelinguished { get; set; }
public DateTime Intake { get; set; }=DateTime.Now;
public ICollection<ChildPhoto> ChildPhotos {get; set;}
}
public class ChildPhoto
{
[Key]
public int PhotocId { get; set;}
public string FileName {get; set;}
public string PhotoPath {get; set;}
public bool IsMain {get; set;}
public int ChildId {get; set;}
public Child Child {get; set;}
public DateTime UploadDate {get; set;}=DateTime.Now;
}
public interface IChildRepository
{
Task<Child> GetChildByIdAsync(int chd);
Task<Child> AddChildrenAsync(Child child);
Task<bool> SaveAllAsync();
}
The Controller method
public async Task<ActionResult> AddPhoto(int chd, [FromForm]IFormFile file)
{
// get the child througth repository
var thechild = await _childRepository.GetChildByIdAsync(chd);
if (thechild == null)
return NotFound("The Child Adding his/her Photos was not found");
var childid = thechild.Cld;
var extension = Path.GetExtension(file.FileName);
var fileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
if (file == null) return BadRequest("Please Selecet a file");
if (file.Length == 0) return BadRequest("The File Your Select is Empty");
var folderName = Path.Combine(_host.WebRootPath, "ChildImages");
if (!Directory.Exists(folderName))
{
Directory.CreateDirectory(folderName);
}
string photoPath = Path.Combine(folderName, fileName);
using (var stream = new FileStream(photoPath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
var photoPathDb = Path.Combine("ChildImages", fileName );
var photo = new ChildPhoto
{
PhotoPath = photoPathDb,
FileName = fileName,
ChildId= childid
};
if (thechild.ChildPhotos.Count == 0)
{
photo.IsMain = true;
}
thechild.ChildPhotos.Add(photo);
await _childRepository.SaveAllAsync();
var photoToReturn = _mapper.Map<ChildPhoto, ChildPhotoDto>(photo);
return CreatedAtRoute("GetPhoto", new { chd = thechild.Cld, id = photo.PhotocId }, photoToReturn);
}
{
error: "details": " at API.Controllers.ChildPhotosController.AddPhoto(Int32 chd, IFormFile file) in C:\\Users\\USER\\Project\\GhAdoptionApp\\API\\Controllers\\ChildPhotosController.cs:line 82\r\n at lambda_method32(Closure , Object )\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)\r\n at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)\r\n at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)\r\n at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)\r\n at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)\r\n at API.Middleware.ExceptionMiddleware.InvokeAsync(HttpContext context) in C:\\Users\\USER\\Project\\GhAdoptionApp\\API\\Middleware\\ExceptionMiddleware.cs:line 30",
"statusCode": 500,
"message": "Object reference not set to an instance of an object."
}
Please I have the entity for child and ChildPhotos,
In the Controller I was called the a child through interface and the childrepository. but I get the Object reference not set to an instance of an object error.

Related

Navigation Property Is Returning Null Properties

Thus project works fine in .Net Framework but now I'm trying to do it in .Net Core 3 but its not working properly.
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string ImageURL { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}
public class BasketLine
{
public int Id { get; set; }
public string BasketId { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public DateTime DateCreated { get; set; }
public Product Product { get; set; }
}
So what happens is iI can add to the BasketLine table and calculate the total of all Products, however when I load the Cart page I get a NullReferenceException
On the Cart Page if I comment out #Model.BasketLines[i].Product.Name or any navigation properties, the Cart Page works
This is the addBasket method
public void AddToBasket(int productId, int quantity)
{
var basketLine = db.BasketLines.FirstOrDefault(b => b.BasketId == BasketId &&
b.ProductId == productId);
if (basketLine == null)
{
basketLine = new BasketLine
{
ProductId = productId,
BasketId = BasketId,
Quantity = quantity,
DateCreated = DateTime.Now
};
db.BasketLines.Add(basketLine);
}
else
{
basketLine.Quantity += quantity;
}
db.SaveChanges();
}
Am I missing something because I have no clue what I'm doing wrong here
Added Include didn't change a thing, then a strange thing happened, I changed this
<a asp-area="Customer"
asp-controller="Shop"
asp-action="Details"
asp-route-id="#Model.BasketLines[i].ProductId">
#Model.BasketLines[i].Product.Name
</a>
to this
#Html.ActionLink(Model.BasketLines[i].Product.Name, "Details", "Products", new { id = Model.BasketLines[i].ProductId }, null)<br />
then the everything worked for a few tries then I got the same error all over again
AspNetCore.Areas_Customer_Views_Basket_Index.<ExecuteAsync>b__15_0() in Index.cshtml
+
#Html.ActionLink(Model.BasketLines[i].Product.Name, "Details", "Products", new { id = Model.BasketLines[i].ProductId }, null)<br />
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.GetChildContentAsync(bool useCachedResult, HtmlEncoder encoder)
Microsoft.AspNetCore.Mvc.TagHelpers.RenderAtEndOfFormTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.<RunAsync>g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, int i, int count)
AspNetCore.Areas_Customer_Views_Basket_Index.ExecuteAsync() in Index.cshtml
+
{
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, bool invokeViewStarts)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ActionContext actionContext, IView view, ViewDataDictionary viewData, ITempDataDictionary tempData, string contentType, Nullable<int> statusCode)
Have you tried Include? You can use the Include method to specify related data to be included in query results.
var basketLine = db.BasketLines
.Include(b => b.Product)
.FirstOrDefault(b => b.BasketId == BasketId && b.ProductId == productId);
[Source]

ASP.net Blazor: Display data from two or more related tables

https://www.youtube.com/watch?v=UBNRcaw1bDk&list=PL6n9fhu94yhVowClAs8-6nYnfsOTma14P&index=23
Hi I'm trying to implement project as mentioned in above link. I'm trying get data from ASP.NET WebAPI project and consume in Blazor project. I have no issue retrieving data from single table. But when I try to retrieve data from Secondary table . I'm getting error below:
"HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error)."
I tried casting the result (in API project)explicitly to 'Employee' class before sending. Didn't work. Debug on API clearly shows returning Employee with Department information but on Blazor project while receiving getting error. Thanks in advance!!
UPDATE:
Thank you all for offering help. Here is the original code.
Models:
public class Employee
{
public int EmployeeId { get; set; }
[Required]
[MinLength(2)]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string Email { get; set; }
public DateTime DateOfBrith { get; set; }
public Gender Gender { get; set; }
public int DepartmentId { get; set; }
public Department Department { get; set; }
public string PhotoPath { get; set; }
}
public class Department
{
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
}
EF:
public class EmployeeRepository : IEmployeeRepository
{
private readonly AppDbContext appDbContext;
public EmployeeRepository(AppDbContext appDbContext)
{
this.appDbContext = appDbContext;
}
public async Task<Employee> GetEmployee(int employeeId)
{
// If I don't include Department table. I'm able to retrieve employee table data fine in Blazor project
return await appDbContext.Employees
.Include(e => e.Department)
.FirstOrDefaultAsync(e => e.EmployeeId == employeeId);
}
}
API:
[Route("api/[controller]")]
[ApiController]
public class EmployeesController : ControllerBase
{
private readonly IEmployeeRepository employeeRepository;
public EmployeesController(IEmployeeRepository employeeRepository)
{
this.employeeRepository = employeeRepository;
}
[HttpGet("{id:int}")]
public async Task<ActionResult<Employee>> GetEmployee(int id)
{
try
{
var result = await employeeRepository.GetEmployee(id);
if (result == null) return NotFound();
//Breakpoint here returns data perfectly fine . With or without cast
return Ok(result);
}
catch (Exception)
{
return StatusCode(StatusCodes.Status500InternalServerError,
"Error retrieving data from the database");
}
}
}
Call API in Blazor
//Service
public interface IEmployeeService
{
Task<Employee> GetEmployee(int id);
}
public class EmployeeService : IEmployeeService
{
private readonly HttpClient httpClient;
public EmployeeService(HttpClient httpClient)
{
this.httpClient = httpClient;
}
public async Task<Employee> GetEmployee(int id)
{
//Error on receiving end
return await httpClient.GetJsonAsync<Employee>($"api/employees/{id}");
}
}
//Blazor Component Base class
namespace EmployeeManagement.Web.Pages
{
public class EmployeeDetailsBase : ComponentBase
{
public Employee Employee { get; set; } = new Employee();
[Inject]
public IEmployeeService EmployeeService { get; set; }
[Parameter]
public string Id { get; set; }
protected async override Task OnInitializedAsync()
{
Id = Id ?? "1";
Employee = await EmployeeService.GetEmployee(int.Parse(Id));
}
}
}
// configuring in startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddHttpClient<IEmployeeService, EmployeeService>(client =>
{
client.BaseAddress = new Uri("https://localhost:44379/");
});
}
Error:
HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error).
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
System.Net.Http.HttpClient.GetStringAsyncCore(Task<HttpResponseMessage> getTask)
Microsoft.AspNetCore.Components.HttpClientJsonExtensions.GetJsonAsync<T>(HttpClient httpClient, string requestUri)
XXXX.Services.EmployeeService.GetEmployee(int id) in EmployeeService.cs
+
var item = await httpClient.GetJsonAsync<Employee>($"api/Employees/{id}");
XXXX.Pages.EmployeeDetailsBase.OnInitializedAsync() in EmployeeDetailsBase.cs
+
Employee = await EmployeeService.GetEmployee(int.Parse(Id));
Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.HandleException(Exception exception)
Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessAsynchronousWork()
Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderRootComponentAsync(int componentId, ParameterView initialParameters)
Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.CreateInitialRenderAsync(Type componentType, ParameterView initialParameters)
Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.RenderComponentAsync(Type componentType, ParameterView initialParameters)
Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext+<>c__11<TResult>+<<InvokeAsync>b__11_0>d.MoveNext()
Microsoft.AspNetCore.Mvc.ViewFeatures.StaticComponentRenderer.PrerenderComponentAsync(ParameterView parameters, HttpContext httpContext, Type componentType)
Microsoft.AspNetCore.Mvc.ViewFeatures.ComponentRenderer.PrerenderedServerComponentAsync(HttpContext context, ServerComponentInvocationSequence invocationId, Type type, ParameterView parametersCollection)
Microsoft.AspNetCore.Mvc.ViewFeatures.ComponentRenderer.RenderComponentAsync(ViewContext viewContext, Type componentType, RenderMode renderMode, object parameters)
Microsoft.AspNetCore.Mvc.TagHelpers.ComponentTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.<RunAsync>g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, int i, int count)
Praxis.EGPSystemBlazor.Pages.Pages__Host.<ExecuteAsync>b__14_1() in _Host.cshtml
+
<component type="typeof(App)" render-mode="ServerPrerendered" />
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
Praxis.EGPSystemBlazor.Pages.Pages__Host.ExecuteAsync() in _Host.cshtml
+
Layout = null;
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, bool invokeViewStarts)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0<TFilter, TFilterAsync>(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultFilters>g__Awaited|27_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Update :
Thanks all for response. Department is mandatory.So there is no chance of null. This is the only solution that worked. I have created another Viewmodel in Blazor project that has all fields same as Employee and Initialized Department inside ViewModelClass. Then I was able to show Employee.Department.DepartmentName in UI.
public class EmployeeViewModel
{
public int EmployeeId { get; set; }
[Required]
[MinLength(2)]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string Email { get; set; }
public string ConfirmEmail { get; set; }
public DateTime DateOfBrith { get; set; }
public Gender Gender { get; set; }
public int DepartmentId { get; set; }
public Department Department { get; set; }= new Department();
public string PhotoPath { get; set; }
}
Is the web API project also loading as well as the client project in the web browser?
If not you may need to go to the properties of your solution from solution Explorer to launch multiple projects.
It may be a good idea to navigate to the web API and type in the following string into the address bar after the port number:
/api/employees/1
Then if the browser displays Json then all is okay. Otherwise you can set a breakpoint in your web API and further investigate where the error is occurring.
You may want to use something like Postman to test the web API.

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

Bind specified property of the WebAPI controller's model

I want to bind only specified property of the WebAPI controller's model and skip all another properties to the DefaultModelBinder.
For example I have json, which should be passed to the WebAPI controller:
{
prop1: 1,
prop2: "b",
prop3: "c",
currentTime: "Fri Feb 27 2015",
references:
[
{ name: "Name 1", type: "Info" },
{ name: "Name 2", type: "Warn" }
]
}
On the server-side there is a HttpPost action with the following signature:
[HttpPost]
public void SaveObject(ReferenceModel model)
{
...
}
Where ReferenceModel is:
public class ReferenceModel
{
public int Prop1 {get; set;}
public string Prop2 {get; set;}
public string Prop3 {get; set;}
public DateTime CurrentTime {get; set;}
public List<BaseReferenceItem> References {get; set;}
}
I need for custom bind of References property, because I want to initialize this property at the runtime by objects of derived types.
For example if I will get Prop1 with value 1 so I need to initialize this collection by objects of type DerivedReferenceType1:
Model.References = new List<BaseReferenceItem>()
{
new DerivedReferenceType1(){...},
new DerivedReferenceType1(){...}
}
If I will get Prop1 with value 2 - of type DerivedReferenceType2 and so on.
I've found potential solution in the ModelBinder, but I don't want to bind all properties at the model.
I know that it's can be easy implemented in the MVC model binders with the call of
base.BindModel(controllerContext, bindingContext);
But how to do it in WebAPI?
Thanks!
One possibility would be to write a custom JsonConverter to handle this situation:
public class MyConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ReferenceModel);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jsonObject = JObject.Load(reader);
var result = new ReferenceModel();
serializer.Populate(jsonObject.CreateReader(), result);
result.References = new List<BaseReferenceItem>();
foreach (var obj in jsonObject.GetValue("references", StringComparison.InvariantCultureIgnoreCase))
{
if (result.Prop1 == 1)
{
result.References.Add(obj.ToObject<DerivedReferenceType1>(serializer));
}
else if (result.Prop1 == 2)
{
result.References.Add(obj.ToObject<DerivedReferenceType2>(serializer));
}
else
{
throw new NotSupportedException(result.Prop1 + " is not supported value for Prop1");
}
}
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
and then you could decorate your main view model with this custom converter:
[JsonConverter(typeof(MyConverter))]
public class ReferenceModel
{
public int Prop1 { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
public DateTime CurrentTime { get; set; }
public List<BaseReferenceItem> References { get; set; }
}
or if you prefer to do this without modifying your view models you could always register your custom converter during the bootstrap process:
public static void Register(HttpConfiguration config)
{
// Web API routes
...
var jsonFormatter = config.Formatters.JsonFormatter;
jsonFormatter.SerializerSettings.Converters.Add(new MyConverter());
}

json.net deserialize an object that has a dictionary property as well as other properties

I have a JSON string representing the following object type:
public partial class Address
{
public Address()
public string Country { get; set; }
public string StreetNo { get; set; }
public string City { get; set; }
public string Zip { get; set; }
public string Complement { get; set; }
public Nullable<int> Latitude { get; set; }
public Nullable<int> Longitude { get; set; }
public Nullable<int> Altitude { get; set; }
public string Url { get; set; }
public System.DateTime LastModified { get; set; }
public byte[] Version { get; set; }
public string StateCode { get; set; }
public string Street { get; set; }
public string RecordStatus { get; set; }
public int UserId { get; set; }
public int AddressId { get; set; }
public Dictionary<string, object> OriginalValues { get; set; }
}
I am trying to create a JsonConverter to deserialize the JSON string to the above object. I am stuck on what to add to my converter to create the dictionary within my code. The code for the converter thus far looks like this:
public class AddressConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
var temp = objectType == typeof(Address);
return temp;
}
public override object ReadJson(JsonReader reader, Type objectType
, object existingValue, JsonSerializer serializer)
{
var obj = JObject.Load(reader);
var model = new Address();
model.Country = Convert.ToString(((JValue)obj["Country"]).Value);
model.StreetNo = Convert.ToString(((JValue)obj["StreetNo"]).Value);
model.City = Convert.ToString(((JValue)obj["City"]).Value);
model.Zip = Convert.ToString(((JValue)obj["Zip"]).Value);
model.Complement = Convert.ToString(((JValue)obj["Complement"]).Value);
model.Latitude = Convert.ToInt32(((JValue)obj["Latitude"]).Value);
model.Longitude = Convert.ToInt32(((JValue)obj["Longitude"]).Value);
model.Altitude = Convert.ToInt32(((JValue)obj["Altitude"]).Value);
model.Url = Convert.ToString(((JValue)obj["Url"]).Value);
model.LastModified = Convert.ToDateTime(((JValue)obj["LastModified"]).Value);
model.StateCode = Convert.ToString((((JValue)obj["Country"]).Value));
model.Street = Convert.ToString(((JValue)obj["StateCode"]).Value);
model.RecordStatus = Convert.ToString(((JValue)obj["RecordStatus"]).Value);
model.UserId = Convert.ToInt32(((JValue)obj["UserId"]).Value);
model.AddressId = Convert.ToInt32(((JValue)obj["AddressId"]).Value);
var encodedString = ((JValue) obj["Version"]).Value.ToString();
model.Version = Convert.FromBase64String(encodedString);
// add Dictionary code here
return model;
}
public override bool CanWrite
{
get
{
return false;
}
}
public override void WriteJson(JsonWriter writer, object value
, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
throw new NotImplementedException();
}
}
I dont know what you are trying to acheive with this Custom convertor. But here is what you want.
// Dictionary code here
model.OriginalValues = (Dictionary<string, object>)JsonConvert.DeserializeObject(obj["OriginalValues"].ToString(), typeof(Dictionary<string, object>));

Resources