I am receiving a bunch of ERR_HTTP2_PROTOCOL_ERROR messages in dev tools after 1 of the pages submits a form to a controller and then the controller displays a different view.
This is the sequence of events:
- OnlineEnrollmentController presents Index.cshtml.
- The View Index.cshtml displays text to the user and the user clicks a button to submit a form.
- The form is sent to OnlineEnrollmentController/Agreement where a View is returned.
- The View Agreement.cshtml is presented to the user and the user clicks a button to submit a form.
- The form is sent to OnlineEnrollmentController/Profile where the ActionResult Profile reads data from a database, populates a model and returns the model to the View Profile.cshtml.
- The View Profile.cshtml is presented to the user and the user clicks a button to submit a form.
- The form is sent to OnlineEnrollmentController/Rate where the ActionResult Rate reads data from a database, populates a model and returns the model to the View Rate.cshtml.
- The View Rate.cshtml is presented to the user and asks the user to enter a rate into a text box. The user enters a rate and clicks on the button to submit the form.
- The form is sent to OnlineEnrollmentController/Election where the ActionResult Election gets the rate that was populated and stores in a TempData field. A new list of object is created where each object contains 3 fields and is returned to the View Election.cshtml.
- The View Election.cshtml uses a foreach loop to display the contents of the list of object.
All this logic works except now I am receiving this ERR_HTTP2_PROTOCOL_ERROR when the View Election.cshtml is loaded.
Here are the specifics:
The application has a shared view called _NoMenu.cshtml. This is the contents of the file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<title>@ViewData["Title"]</title>
<link rel="stylesheet" href="~/css/site.css" />
<script src="https://use.fontawesome.com/54ec0da54f.js"></script>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous" />
<!-- font awesome -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous" />
<style>
/* Style for showing in progress bar
--------------------------------------------------*/
.submit-progress {
position: fixed;
top: 30%;
left: 50%;
height: 6em;
padding-top: 2.3em;
/* The following rules are the
ones most likely to change */
width: 20em;
/* Set 'margin-left' to a negative number
that is 1/2 of 'width' */
margin-left: -10em;
padding-left: 2.1em;
background-color: #17a2b8a8;
color: black;
-webkit-border-radius: 0.4em;
-moz-border-radius: 0.4em;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em rgba(0,0,0,0.6);
-webkit-box-shadow: 0.4em 0.4em rgba(0,0,0,0.6);
-moz-box-shadow: 0.4em 0.4em rgba(0,0,0,0.6);
}
.hidden {
visibility: hidden;
}
.submit-progress i {
margin-right: 0.5em;
}
.mb-5, .my-5 {
margin-bottom: 1.5rem !important;
}
.scrollHeight {
height: 85vh;
}
.hideit {
display: none;
}
.width95 {
width: 95%;
}
.myDIV {
height: 75%;
overflow: auto;
}
.content500 {
height: 500px;
}
.content600 {
height: 600px;
}
.content800 {
height: 800px;
}
</style>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
I use this for any page in my application where I dont want to show a standard bootstrap menu structure.
Here is the contents of the view Rate.schtml:
@model AccuRecordV3.Models.OnlineEnrollment_Indicative_Verify
@{
ViewData["Title"] = "Online Enrollment - Rate";
Layout = "~/Views/Shared/_NoMenu.cshtml";
}
@using (Html.BeginForm("Election", "OnlineEnrollment", FormMethod.Post))
{
<section id="rate" class="vh-100" style="background-color: #508bfc;">
<div class="container py-5 h-100">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col-12 col-md-8 col-lg-6 col-xl-5">
<div class="card shadow-2-strong" style="border-radius: 1rem;">
<div class="card-body p-5 text-center scrollHeight">
<h3 class="mb-5">Online Enrollment</h3>
<h5 class="mb-5">Step 1 of 3</h5>
<div id="rateDIV" class="myDIV">
<div id="ratecontent" class="content500">
<div class="form-outline mb-4">
<label class="form-label text-left width95">
@Model.messageLiteral
</label>
</div>
<div class="form-outline mb-4">
<label class="form-label text-left width95">
The minimum contribution rate allowed by your plan is @Model.outputMinPct and the
maximum contribution rate allowed by your plan is @Model.outputMaxPct
</label>
</div>
<div class="form-outline mb-4">
<label class="form-label text-left">
How much would you like to contribute?
</label>
</div>
<div class="form-outline mb-4">
<input type="number" id="electedRate" asp-for="electedRate" class="form-control form-control-lg rate" value="@Model.electedRate" placeholder="0" min="@Model.ss_CtrbKMinPct" step="1" max="@Model.ss_CtrbKMaxPct" />
<label class="form-label text-danger" for="electedRate" id="rateerrorLabel"> </label>
</div>
<button class="btn btn-primary btn-lg btn-block" type="button" id="rateButton" disabled onclick="return DisplayProgressMessage(this, 'rate');">Next</button>
<button class="btn btn-outline-primary btn-lg btn-block" type="button" id="cancelRateButton" onclick="return Cancel(this, 'rate');">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
}
<script>
$(function () {
var rate = 0;
$('.rate').each(function () {
rate += parseInt($(this).val());
});
var minRate = parseInt("@Model.ss_CtrbKMinPct");
var maxRate = parseInt("@Model.ss_CtrbKMaxPct");
if (rate < minRate || rate > maxRate) {
$("#rateButton").prop("disabled", true);
} else {
$("#rateButton").prop("disabled", false);
}
$('.rate').change(function () {
var rate = 0;
$('.rate').each(function () {
rate += parseInt($(this).val());
});
var minRate = parseInt("@Model.ss_CtrbKMinPct");
var maxRate = parseInt("@Model.ss_CtrbKMaxPct");
if (rate < minRate || rate > maxRate) {
$("#rateButton").prop("disabled", true);
} else {
$("#rateButton").prop("disabled", false);
}
})
})
function DisplayProgressMessage(ctl, msg) {
$(ctl).prop("disabled", true).text(msg);
$("#submitButton").prop("disabled", true);
$(".submit-progress").removeClass("hidden");
const myTimeout = setTimeout(function () {
$("form").submit();
}, 5);
}
</script>
The view Rate.schtml works correctly, using jquery to validate the rate the user enters and then submits the form back to the controller.
This is the contents of Election.cshtml:
@model AccuRecordV3.Models.OnlineEnrollment_Indicative_Verify
@{
ViewData["Title"] = "Online Enrollment - Rate";
Layout = "~/Views/Shared/_NoMenu.cshtml";
}
@using (Html.BeginForm("Summary", "OnlineEnrollment", FormMethod.Post))
{
<section id="elections" class="vh-100" style="background-color: #508bfc;">
<div class="container py-5 h-100">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col-12 col-md-8 col-lg-6 col-xl-5">
<div class="card shadow-2-strong" style="border-radius: 1rem;">
<div class="card-body p-3 text-center scrollHeight">
<h3 class="mb-5">Online Enrollment</h3>
<h5 class="mb-5">Step 2 of 3</h5>
<div id="electionsDIV" class="myDIV">
<div id="electionscontent" class="content600">
<div class="form-outline mb-4">
<label class="form-label text-left width95">
These are the funds that are available to you. You can allocate your contribution to any/all of these funds. Remember, you wont be able to submit your elections all your total elections added together equal 100%.
</label>
</div>
@foreach (var localRecord in Model.electionData)
{
<div class="row width95">
<label for="NewPct" class="col-sm-9 col-form-label text-left">@localRecord.FundName</label>
<div class="col-sm-3">
<input type="number" class="form-control election" id="NewPct" name="NewPct" min="@localRecord.MinPct" max="@localRecord.MaxPct" value="0">
<input type="number" id="HostFID" name="HostFID" hidden value="@localRecord.HostFID" />
</div>
</div>
}
<div class="row width95">
<label class="col-sm-9 col-form-label text-left">Total</label>
<label id="ElectionTotal" name="ElectionTotal" class="col-sm-3 col-form-label text-right">0%</label>
</div>
<button class="btn btn-primary btn-lg btn-block" type="button" id="electionButton" disabled onclick="return DisplayProgressMessage(this, 'elections');">Next</button>
<button class="btn btn-outline-primary btn-lg btn-block" type="button" id="cancelElectionButton" onclick="return Cancel(this, 'elections');">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
}
<script>
$(function () {
$('.election').change(function () {
var sum = 0;
$('.election').each(function () {
sum += parseInt($(this).val());
});
var totalElection = sum + "%";
$("#ElectionTotal").text(totalElection)
if (sum == 100) {
$("#electionButton").prop("disabled", false);
} else {
$("#electionButton").prop("disabled", true);
}
})
})
function DisplayProgressMessage(ctl, msg) {
$(ctl).prop("disabled", true).text(msg);
$("#submitButton").prop("disabled", true);
$(".submit-progress").removeClass("hidden");
const myTimeout = setTimeout(function () {
$("form").submit();
}, 5);
}
</script>
When this view loads, and I look at dev tools, this is what I see:
and
So, for some reason, this error is preventing jquery.min.js from loading which in turn causes the '$' not defined error.
It looks like this error is also preventing the style sheet from loading properly as well.
Some research into this says it's a CORS issue but I dont see how I could have a CORS issue on one page (Elections.schtml) and not on the others (Index.schtml, Agreement.schtml, Profile.schtml, and Rate.schtml).
Any idea how to resolve this?
Thanks.