I haven't programmed in 15 years. I am trying to encode a model with System.Text.Json and send the encoded output to a javascript function, where I want to parse it with JSON.parse.
I would like to use System.Text.Json instead of Newtonsoft.Json because it is faster, more memory efficient, and I have always gravitated toward stricter structures. So I was disappointed when System.Text.Json put out what jsonlint.com says is invalid json.
The relevant line of code in Index.cshtml is:
else { <button title="Existing visit today" name="visitBtn" id="existingVisitBtn" method="post" onclick="openExistingVisitModal(@JsonSerializer.Serialize(Model.Patients[j].VisitsToday))">Visit</button> }
It is about halfway down the whole Index.cshtml:
@using DataLibrary.Models;
@using System.Text.Json;
@model PatientsPlusVisitTypes
@{
ViewData["Title"] = "Patient List";
int i = 0;
int patientIDint = 0;
}
<div >
<h1 >SSRounds - Patient List</h1>
</div>
<h6 >Inpatient Rounds Tracking for Surgical Services</h6>
<br />
<table >
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Patients[0].Seen)
</th>
<th>
@Html.DisplayNameFor(model => model.Patients[0].UA)
</th>
<th>
@Html.DisplayNameFor(model => model.Patients[0].Surgicalist)
</th>
<th>
@Html.DisplayNameFor(model => model.Patients[0].Location)
</th>
<th>
@Html.DisplayNameFor(model => model.Patients[0].Hospital)
</th>
<th>
@Html.DisplayNameFor(model => model.Patients[0].LastName)
</th>
<th>
@Html.DisplayNameFor(model => model.Patients[0].FirstName)
</th>
<th>
@Html.DisplayNameFor(model => model.Patients[0].MD)
</th>
<th>
@Html.DisplayNameFor(model => model.Patients[0].Priority)
</th>
<th>
@Html.DisplayNameFor(model => model.Patients[0].Diagnosis)
</th>
<th>
@Html.DisplayNameFor(model => model.Patients[0].Details)
</th>
<th></th>
</tr>
</thead>
<tbody>
@for (int j = 0; j < Model.Patients.Count; j )
{
patientIDint = Model.Patients[j].PatientID;
<tr>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].Seen)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].UA)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].Surgicalist)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].Hospital)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].Location)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].LastName)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].MD)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].Priority)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].Diagnosis)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Patients[j].Details)
</td>
<td>
@{
if (Model.Patients[j].VisitsToday.Count == 0)
{
<button name="visitBtn" id="visitBtn" method="post" onclick="addID('@Model.Visits.Count', '@patientIDint')">Visit</button>
}
else
{
<button title="Existing visit today" name="visitBtn" id="existingVisitBtn" method="post" onclick="openExistingVisitModal(@JsonSerializer.Serialize(Model.Patients[j].VisitsToday))">Visit</button>
}
}
<form asp-controller="Home" asp-action="HidePatient">
<button name="patientID" method="post" value=@(Model.Patients[j].PatientID) >Remove</button>
</form>
</td>
</tr>
}
</tbody>
</table>
<div id="visitModal">
<div class = "modalContent">
<div class = "modalHeader">
<span class = "closeBtn">×</span>
<h2>Add a Visit</h2>
</div>
<div class = "modalBody">
<table >
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Visits[0].CPT)
</th>
<th>
@Html.DisplayNameFor(model => model.Visits[0].Description)
</th>
<th></th>
</tr>
</thead>
<tbody>
@{
foreach (VisitTypeModel cptItem in Model.Visits)
{
<tr>
@using (Html.BeginForm("SaveVisit", "Home", FormMethod.Post, new { name = "CPTForm", id = $"CPTEntry{i}" }))
{
<td>
<button type="submit" method="post" name="CPT" [email protected] >@cptItem.CPT</button>
</td>
<td>
<label>@cptItem.Description</label>
</td>
i ;
}
</tr>
}
}
</tbody>
</table>
</div>
<div class = "modalFooter">
</div>
</div>
</div>
<div id="existingVisitModal">
<div >
<div >
<div >
<span >×</span>
<h2>Existing Visit Today</h2>
</div>
<div >
<table >
<thead>
<tr>
<th>
Time
</th>
<th>
Entered By
</th>
<th>
Visit Level
</th>
<th></th>
</tr>
</thead>
<tbody>
@{
}
</tbody>
</table>
</div>
<div >
<button type="button" data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
Console logging jsonVisitsToday (passed from @JsonSerializer.Serialize(Model.Patients[j].VisitsToday)) produces this:
'{PatientID: 19509, WhenSeen: '2022-08-10T09:56:50', SeenBy: '[email protected]', VisitLevel: '99024', Legit: true}'
No quotes on the property names! Everything I have read says valid JSON requires quotes on the property names. And to get jsonlint.com to call it valid JSON I have to put double quotes around the property names and the values.
**My questions:
- Is that valid JSON output (I don't think so)
- If it is, how do I parse it?**
The javascript that is giving me fits:
function openExistingVisitModal(jsonVisitsToday) {
existingVisitModal = document.getElementById("existingVisitModal");
console.log(jsonVisitsToday);
//jsonParsed = JSON.parse(jsonVisitsToday); //commented out because it generates an error
//add elements and data to the modal form here
existingVisitModal.style.display = 'block';
}
Models:
using System;
using System.ComponentModel.DataAnnotations;
namespace DataLibrary.Models
{
public class VisitModelSQL
{
[Key]
public int PatientID { get; set; }
public DateTime WhenSeen { get; set; }
public string SeenBy { get; set; }
public string VisitLevel { get; set; }
public bool Legit { get; set; }
}
}
namespace SSRoundsMVC.Models
{
public class VisitModel
{
public int PatientID { get; set; }
public DateTime WhenSeen { get; set; }
public string SeenBy { get; set; }
public string VisitLevel { get; set; }
public bool Legit { get; set; }
}
}
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
namespace SSRoundsMVC.Models
{
public class PtDisplayModel
{
[Key]
[HiddenInput(DisplayValue = false)]
public int PatientID { get; set; }
public bool Seen { get; set; }
public bool UA { get; set; }
[Display(Name = "S")]
public bool Surgicalist { get; set; }
[Display(Name = "Hosp")]
public string? Hospital { get; set; }
[Display(Name = "Loc")]
public string? Location { get; set; }
[Display(Name = "Last Name")]
public string? LastName { get; set; }
[Display(Name = "First Name")]
public string? FirstName { get; set; }
[Display(Name = "Doc")]
public string? MD { get; set; }
[Display(Name = "#")]
public int Priority { get; set; }
public string? Diagnosis { get; set; }
[Display(Name = "Details and Instructions")]
public string? Details { get; set; }
[HiddenInput(DisplayValue = false)]
public List<DataLibrary.Models.VisitModelSQL>? VisitsToday { get; set; }
}
}
namespace DataLibrary.Models
{
public class VisitTypeModel
{
public string CPT { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public int PatientID { get; set; }
}
}
using System;
using DataLibrary.Models;
using SSRoundsMVC.Models;
namespace SSRoundsMVC.Models
{
public class PatientsPlusVisitTypes
{
public List<PtDisplayModel> Patients { get; set; }
public List<VisitTypeModel> Visits { get; set; }
}
}
CodePudding user response:
JLq I should have paid more attention to your comments about the output being an object. I can't JSON.parse it because it is already an object. All I need to do is access it with dot notation - as in jsonVisitsToday.WhenSeen. Thanks for your quick responses - I had no idea stackoverflow was so active!
CodePudding user response:
If you manage to remove the outer single quotes, yes, it is valid JSON that will be parsed by the JSON.parse(x) statement.
I would try to modify the view (index.cshtml) to make it output the value with @Html.Raw(x) as in:
onclick="openExistingVisitModal(@Htm.Raw(JsonSerializer.Serialize(Model.Patients[j].VisitsToday)))"
This should produce a direct JSON object as input of your openExistingVisitModal function, and it should not give any errors when it is executed in the parsed view by the browser.
as in onclick="openExistingVisitModal({PatientID: 19509, WhenSeen: '2022-08-10T09:56:50', SeenBy: '[email protected]', VisitLevel: '99024', Legit: true})"