<br>
<p>Edited: I have now included ALL the code.</p><br>
<p>It is probably very straight forward, but I have not been able to google this, probably because I'm new to Razor, and I don't know the term to search for.</p><br>
<p>It is a simple page with at dropdownlist for teams, and when you have selected the team, it shows the players for that team.</p><br>
<ol><br>
<li>The ddl with teams renders fine </li><li>The table with the players renders fine, when called from OnGetAsync() </li><li>But when I try to do it on the OnPost(), I get a result from the database, and the player list gets populated,
and in the view in the foreach
loop I can see the values being assigend, but the browser does not show this change,&nbsp;<br>
</li><li>I noticed that all the examples for OnPost usually redirects to another page, instead of &quot;reloading&quot; the same page, -have I missed something here?<br><br>
<br><br>
In the view:&nbsp; </li></ol><br>
<pre class="default prettyprint prettyprinted"><code><span class="pln"></span></code></pre><br>
<pre class="prettyprint lang-auto">@page<br>
@model rd.Pages.p2.p2Model<br>
@{<br>
ViewData[&quot;Title&quot;] = &quot;p2&quot;;<br>
}<br>
<br>
&lt;h1&gt;Index&lt;/h1&gt;<br>
<br>
&lt;form&gt;<br>
@Html.AntiForgeryToken()<br>
&lt;p&gt;<br>
<br>
&lt;select id=&quot;myDropdown&quot; asp-for=&quot;selectedFilter&quot; asp-items=&quot;Model.team&quot; onchange=&quot;sendData()&quot;&gt;<br>
&lt;option value=&quot;&quot;&gt;Choose a team&lt;/option&gt;<br>
&lt;/select&gt;<br>
<br>
&lt;/p&gt;<br>
<br>
@if (Model.player != null)<br>
{<br>
&lt;table class=&quot;table&quot;&gt;<br>
&lt;thead&gt;<br>
&lt;tr&gt;<br>
&lt;th&gt;<br>
@Html.DisplayNameFor(model =&gt; model.player[0].PlayerName)<br>
&lt;/th&gt;<br>
&lt;th&gt;<br>
@Html.DisplayNameFor(model =&gt; model.player[0].PlayerNumber)<br>
&lt;/th&gt;<br>
&lt;th&gt;<br>
@Html.DisplayNameFor(model =&gt; model.player[0].PlayerActive)<br>
&lt;/th&gt;<br>
&lt;th&gt;<br>
@Html.DisplayNameFor(model =&gt; model.player[0].SortOrder)<br>
&lt;/th&gt;<br>
&lt;th&gt;<br>
@Html.DisplayNameFor(model =&gt; model.player[0].Team)<br>
&lt;/th&gt;<br>
&lt;th&gt;&lt;/th&gt;<br>
&lt;/tr&gt;<br>
&lt;/thead&gt;<br>
&lt;tbody&gt;<br>
@foreach (var item in Model.player)<br>
{<br>
&lt;tr&gt;<br>
&lt;td&gt;<br> @*This is being hit on both the OnGet and the OnPost and is assigned value both times but only seen in browser on OnGet*@<br>
@Html.DisplayFor(modelItem =&gt; item.PlayerName)<br>
&lt;/td&gt;<br>
&lt;td&gt;<br>
@Html.DisplayFor(modelItem =&gt; item.PlayerNumber)<br>
&lt;/td&gt;<br>
&lt;td&gt;<br>
@Html.DisplayFor(modelItem =&gt; item.PlayerActive)<br>
&lt;/td&gt;<br>
&lt;td&gt;<br>
@Html.DisplayFor(modelItem =&gt; item.SortOrder)<br>
&lt;/td&gt;<br>
&lt;td&gt;<br>
@Html.DisplayFor(modelItem =&gt; item.Team.TeamName)<br>
&lt;/td&gt;<br>
&lt;td&gt;<br>
&lt;a asp-page=&quot;./Edit&quot; asp-route-id=&quot;@item.Id&quot;&gt;Edit&lt;/a&gt; |<br>
&lt;a asp-page=&quot;./Details&quot; asp-route-id=&quot;@item.Id&quot;&gt;Details&lt;/a&gt; |<br>
&lt;a asp-page=&quot;./Delete&quot; asp-route-id=&quot;@item.Id&quot;&gt;Delete&lt;/a&gt;<br>
&lt;/td&gt;<br>
&lt;/tr&gt;<br>
}<br>
<br>
&lt;/tbody&gt;<br>
<br>
&lt;/table&gt;<br>
}<br>
<br>
&lt;/form&gt;<br>
<br>
<br>
@section Scripts{ <br>
&lt;script&gt;<br>
function sendData() {<br>
var selectedFilter = &#36;(&quot;#myDropdown&quot;).val();<br>
&#36;.ajax({<br>
type: &quot;POST&quot;,<br>
url: &quot;/p2/p2&quot;,<br>
data: { selectedFilter: selectedFilter },<br>
headers: {<br>
RequestVerificationToken: &#36;('input:hidden[name=&quot;__RequestVerificationToken&quot;]').val()<br>
},<br>
<br>
error: function() {<br>
alert(&quot;there was an error&quot;);<br>
}<br>
});<br>
}<br>
&lt;/script&gt;<br>
}<br>
</pre><br>
<pre class="default prettyprint prettyprinted"><code><span class="pln">&nbsp;</span></code></pre><br>
<p><code></code><code><span class="pln"></span></code></p><br>
<p>In the controller</p><br>
<pre class="prettyprint lang-auto">using System;<br>
using System.Collections.Generic;<br>
using System.Linq;<br>
using System.Security.Cryptography.Xml;<br>
using System.Threading.Tasks;<br>
using Microsoft.AspNetCore.Mvc;<br>
using Microsoft.AspNetCore.Mvc.RazorPages;<br>
using Microsoft.AspNetCore.Mvc.Rendering;<br>
using Microsoft.EntityFrameworkCore;<br>
using rd.Models;<br>
<br>
namespace rd.Pages.p2<br>
{<br>
public class p2Model : PageModel<br>
{<br>
public List&lt;Models.Player&gt; player { get; set; }<br>
public List&lt;SelectListItem&gt; team { get; set; }<br>
<br>
<br>
private readonly rd.Models.rdnewContext _context;<br>
<br>
public p2Model(rd.Models.rdnewContext context)<br>
{<br>
_context = context;<br>
}<br>
<br>
public async Task OnGetAsync()<br>
<br>
{<br>
team = await _context.Team.Select(a =&gt;<br>
new SelectListItem<br>
{<br>
Text = a.TeamName.ToString(),<br>
Value = a.Id.ToString()<br>
}).ToListAsync();<br> //Should not really be bound here, just to prove that it CAN be bound<br>
player = (from pl in _context.Player where pl.TeamId == 2 select pl).ToList();<br>
<br>
<br>
}<br>
<br>
[BindProperty] public string selectedFilter { get; set; }<br>
<br>
public async Task OnPost()<br>
{<br>
int teamid = int.Parse(selectedFilter);<br>
<br>
//This works in the sense that player IS populated with the desired data<br>
player = await (from pl in _context.Player where pl.TeamId == teamid select pl).ToListAsync();<br>
<br>
}<br>
}<br>
}</pre><br>
<p><br><br>
<br><br>
</p><br>
We cannot see all the code. Are you making an AJAX request? Also, the way the code is written it should cause an error because you do not repopulate the team select.
All code is included, yes I'm using AJAX, and that part works just fine.
Actually good point regarding the dropdownlist, after the post, I would expect the dropdownlist to be empty, but it is unchanged, -as in the entire page is unchanged.
There is now more comments in the code where I have put breakpoints, and where I can see that I do get the desired values and it is assigned where it should, except the only time I can see data in the table in the browser is on the OnGet, even if I can see
that data is assigend in the view on both the OnGet AND OnPost, it is ONLY the values from the OnGet I can see in the browser
It is like the assignment on the OnPost, does not "take", or have any effect
The Razor page is rendered by the razor engine, but the ajax request doesn't make razor re-render it, so one way to do this is to render the page in jquery as an ajax request to the data.
<form>
@Html.AntiForgeryToken()
<p>
<select id="myDropdown" asp-items="Model.team" data-bind="@Model.selectedFilter" onchange="sendData()">
<option value="">Choose a team</option>
</select>
@Model.player.Count
</p>
<div id="playershow">
</div>
@if (Model.player != null)
{
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.player[0].PlayerName)
</th>
<th>
@Html.DisplayNameFor(model => model.player[0].PlayerNumber)
</th>
@*<th>
@Html.DisplayNameFor(model => model.player[0].PlayerActive)
</th>
<th>
@Html.DisplayNameFor(model => model.player[0].SortOrder)
</th>
<th>
@Html.DisplayNameFor(model => model.player[0].Team)
</th>*@
<th></th>
</tr>
</thead>
<tbody id="originShow">
@foreach (var item in Model.player)
{
<tr>
<td>
@*This is being hit on both the OnGet and the OnPost and is assigned value both times but only seen in browser on OnGet*@
@Html.DisplayFor(modelItem => item.PlayerName)
</td>
<td>
@Html.DisplayFor(modelItem => item.PlayerNumber)
</td>
@*<td>
@Html.DisplayFor(modelItem => item.PlayerActive)
</td>
<td>
@Html.DisplayFor(modelItem => item.SortOrder)
</td>
<td>
@Html.DisplayFor(modelItem => item.Team.TeamName)
</td>*@
<td>
<a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
<tbody id="changeShow">
</tbody>
</table>
}
</form>
@section Scripts{
<script>
function sendData() {
var selectedFilter = $("#myDropdown").val(); console.log(selectedFilter)
$.ajax({
type: "POST",
url: "/p2",
data: { selectedFilter: selectedFilter },
headers: {
RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (data) {
$("#changeShow").empty();
var players = JSON.parse(data);
console.log(players)
$("#originShow").hide();
$("#changeShow").show();
for (var i = 0; i < players.length; i++) {
$("#changeShow").append('<tr><td>' + players[i].PlayerName + '</td><td>' + players[i].PlayerNumber +'</td></tr>');
}
},
error: function(e) {
alert("there was an error--");
}
});
}
</script>
}
At the same time, OnPost needs to respond with a string in json format.
public async Task OnPost()
{
int teamid = int.Parse(selectedFilter);
//This works in the sense that player IS populated with the desired data
player = await (from pl in _context.Player where pl.TeamId == teamid select pl).ToListAsync();
Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(player));
}
Well that essentially did the trick, but not exactly the way I had wanted.
1) The original rendered html is still there, is is just hidden.
2) The data is "brute force directly appended" by javascript, and not "bound by the system", as I know it can do on the OnGet
If you look at my OnGet method, you can see that player list is being populated, and subsequently the view is looping through the list, and values are assigned, and
I can see the resulting html just as expected.
The exactly same happens in the OnPost method, a player list is being populated with different values,
and the view is looping through the new values. (And that lead me to believe that this was razor re-render the page, but apparently that is not the case. I have a feeling that I'm missing something important here)
But the resulting HTML is not changed at all on the OnPost
public async Task OnGetAsync()
{
team = await _context.Team.Select(a =>
new SelectListItem
{
Text = a.TeamName.ToString(),
Value = a.Id.ToString()
}).ToListAsync();
player = (from pl in _context.Player where pl.TeamId == 2 select pl).ToList();
}
2) The data is "brute force directly appended" by javascript, and not "bound by the system", as I know it can do on the OnGet
The POST response is returned to the AJAX function. It is up to you to design JavaScript that writes the POST response to the page. This is a well known and fundamental concept.
Member
1 Points
7 Posts
razor core.net don't render to table onpost but does render ongetasync
Jul 13, 2020 05:21 PM|barnonline|LINK
<br>
<p>Edited: I have now included ALL the code.</p><br>
<p>It is probably very straight forward, but I have not been able to google this, probably because I'm new to Razor, and I don't know the term to search for.</p><br>
<p>It is a simple page with at dropdownlist for teams, and when you have selected the team, it shows the players for that team.</p><br>
<ol><br>
<li>The ddl with teams renders fine </li><li>The table with the players renders fine, when called from OnGetAsync() </li><li>But when I try to do it on the OnPost(), I get a result from the database, and the player list gets populated, and in the view in the foreach
loop I can see the values being assigend, but the browser does not show this change,&nbsp;<br>
</li><li>I noticed that all the examples for OnPost usually redirects to another page, instead of &quot;reloading&quot; the same page, -have I missed something here?<br><br>
<br><br>
In the view:&nbsp; </li></ol><br>
<pre class="default prettyprint prettyprinted"><code><span class="pln"></span></code></pre><br>
<pre class="prettyprint lang-auto">@page<br>
@model rd.Pages.p2.p2Model<br>
@{<br>
ViewData[&quot;Title&quot;] = &quot;p2&quot;;<br>
}<br>
<br>
&lt;h1&gt;Index&lt;/h1&gt;<br>
<br>
&lt;form&gt;<br>
@Html.AntiForgeryToken()<br>
&lt;p&gt;<br>
<br>
&lt;select id=&quot;myDropdown&quot; asp-for=&quot;selectedFilter&quot; asp-items=&quot;Model.team&quot; onchange=&quot;sendData()&quot;&gt;<br>
&lt;option value=&quot;&quot;&gt;Choose a team&lt;/option&gt;<br>
&lt;/select&gt;<br>
<br>
&lt;/p&gt;<br>
<br>
@if (Model.player != null)<br>
{<br>
&lt;table class=&quot;table&quot;&gt;<br>
&lt;thead&gt;<br>
&lt;tr&gt;<br>
&lt;th&gt;<br>
@Html.DisplayNameFor(model =&gt; model.player[0].PlayerName)<br>
&lt;/th&gt;<br>
&lt;th&gt;<br>
@Html.DisplayNameFor(model =&gt; model.player[0].PlayerNumber)<br>
&lt;/th&gt;<br>
&lt;th&gt;<br>
@Html.DisplayNameFor(model =&gt; model.player[0].PlayerActive)<br>
&lt;/th&gt;<br>
&lt;th&gt;<br>
@Html.DisplayNameFor(model =&gt; model.player[0].SortOrder)<br>
&lt;/th&gt;<br>
&lt;th&gt;<br>
@Html.DisplayNameFor(model =&gt; model.player[0].Team)<br>
&lt;/th&gt;<br>
&lt;th&gt;&lt;/th&gt;<br>
&lt;/tr&gt;<br>
&lt;/thead&gt;<br>
&lt;tbody&gt;<br>
@foreach (var item in Model.player)<br>
{<br>
&lt;tr&gt;<br>
&lt;td&gt;<br> @*This is being hit on both the OnGet and the OnPost and is assigned value both times but only seen in browser on OnGet*@<br>
@Html.DisplayFor(modelItem =&gt; item.PlayerName)<br>
&lt;/td&gt;<br>
&lt;td&gt;<br>
@Html.DisplayFor(modelItem =&gt; item.PlayerNumber)<br>
&lt;/td&gt;<br>
&lt;td&gt;<br>
@Html.DisplayFor(modelItem =&gt; item.PlayerActive)<br>
&lt;/td&gt;<br>
&lt;td&gt;<br>
@Html.DisplayFor(modelItem =&gt; item.SortOrder)<br>
&lt;/td&gt;<br>
&lt;td&gt;<br>
@Html.DisplayFor(modelItem =&gt; item.Team.TeamName)<br>
&lt;/td&gt;<br>
&lt;td&gt;<br>
&lt;a asp-page=&quot;./Edit&quot; asp-route-id=&quot;@item.Id&quot;&gt;Edit&lt;/a&gt; |<br>
&lt;a asp-page=&quot;./Details&quot; asp-route-id=&quot;@item.Id&quot;&gt;Details&lt;/a&gt; |<br>
&lt;a asp-page=&quot;./Delete&quot; asp-route-id=&quot;@item.Id&quot;&gt;Delete&lt;/a&gt;<br>
&lt;/td&gt;<br>
&lt;/tr&gt;<br>
}<br>
<br>
&lt;/tbody&gt;<br>
<br>
&lt;/table&gt;<br>
}<br>
<br>
&lt;/form&gt;<br>
<br>
<br>
@section Scripts{ <br>
&lt;script&gt;<br>
function sendData() {<br>
var selectedFilter = &#36;(&quot;#myDropdown&quot;).val();<br>
&#36;.ajax({<br>
type: &quot;POST&quot;,<br>
url: &quot;/p2/p2&quot;,<br>
data: { selectedFilter: selectedFilter },<br>
headers: {<br>
RequestVerificationToken: &#36;('input:hidden[name=&quot;__RequestVerificationToken&quot;]').val()<br>
},<br>
<br>
error: function() {<br>
alert(&quot;there was an error&quot;);<br>
}<br>
});<br>
}<br>
&lt;/script&gt;<br>
}<br>
</pre><br>
<pre class="default prettyprint prettyprinted"><code><span class="pln">&nbsp;</span></code></pre><br>
<p><code></code><code><span class="pln"></span></code></p><br>
<p>In the controller</p><br>
<pre class="prettyprint lang-auto">using System;<br>
using System.Collections.Generic;<br>
using System.Linq;<br>
using System.Security.Cryptography.Xml;<br>
using System.Threading.Tasks;<br>
using Microsoft.AspNetCore.Mvc;<br>
using Microsoft.AspNetCore.Mvc.RazorPages;<br>
using Microsoft.AspNetCore.Mvc.Rendering;<br>
using Microsoft.EntityFrameworkCore;<br>
using rd.Models;<br>
<br>
namespace rd.Pages.p2<br>
{<br>
public class p2Model : PageModel<br>
{<br>
public List&lt;Models.Player&gt; player { get; set; }<br>
public List&lt;SelectListItem&gt; team { get; set; }<br>
<br>
<br>
private readonly rd.Models.rdnewContext _context;<br>
<br>
public p2Model(rd.Models.rdnewContext context)<br>
{<br>
_context = context;<br>
}<br>
<br>
public async Task OnGetAsync()<br>
<br>
{<br>
team = await _context.Team.Select(a =&gt;<br>
new SelectListItem<br>
{<br>
Text = a.TeamName.ToString(),<br>
Value = a.Id.ToString()<br>
}).ToListAsync();<br> //Should not really be bound here, just to prove that it CAN be bound<br>
player = (from pl in _context.Player where pl.TeamId == 2 select pl).ToList();<br>
<br>
<br>
}<br>
<br>
[BindProperty] public string selectedFilter { get; set; }<br>
<br>
public async Task OnPost()<br>
{<br>
int teamid = int.Parse(selectedFilter);<br>
<br>
//This works in the sense that player IS populated with the desired data<br>
player = await (from pl in _context.Player where pl.TeamId == teamid select pl).ToListAsync();<br>
<br>
}<br>
}<br>
}</pre><br>
<p><br><br>
<br><br>
</p><br>
All-Star
53751 Points
24069 Posts
Re: razor core.net don't render to table onpost but does render ongetasync
Jul 13, 2020 05:54 PM|mgebhard|LINK
We cannot see all the code. Are you making an AJAX request? Also, the way the code is written it should cause an error because you do not repopulate the team select.
All-Star
58484 Points
15810 Posts
Re: razor core.net don't render to table onpost but does render ongetasync
Jul 13, 2020 05:54 PM|bruce (sqlwork.com)|LINK
you should use OnPostAsync, but how do you call it? via a form.submit()? ajax?
Member
1 Points
7 Posts
Re: razor core.net don't render to table onpost but does render ongetasync
Jul 13, 2020 11:32 PM|barnonline|LINK
All code is included, yes I'm using AJAX, and that part works just fine.
Actually good point regarding the dropdownlist, after the post, I would expect the dropdownlist to be empty, but it is unchanged, -as in the entire page is unchanged.
There is now more comments in the code where I have put breakpoints, and where I can see that I do get the desired values and it is assigned where it should, except the only time I can see data in the table in the browser is on the OnGet, even if I can see that data is assigend in the view on both the OnGet AND OnPost, it is ONLY the values from the OnGet I can see in the browser
It is like the assignment on the OnPost, does not "take", or have any effect
Member
1 Points
7 Posts
Re: razor core.net don't render to table onpost but does render ongetasync
Jul 13, 2020 11:33 PM|barnonline|LINK
Yeah I have also tried OnPostAsync, no difference. Yes I used AJAX
Member
80 Points
32 Posts
Re: razor core.net don't render to table onpost but does render ongetasync
Jul 14, 2020 07:09 AM|Evern|LINK
HI,
The Razor page is rendered by the razor engine, but the ajax request doesn't make razor re-render it, so one way to do this is to render the page in jquery as an ajax request to the data.
At the same time, OnPost needs to respond with a string in json format.
Best Regards,
Evern
Member
1 Points
7 Posts
Re: razor core.net don't render to table onpost but does render ongetasync
Jul 14, 2020 08:04 AM|barnonline|LINK
Well that essentially did the trick, but not exactly the way I had wanted.
1) The original rendered html is still there, is is just hidden.
2) The data is "brute force directly appended" by javascript, and not "bound by the system", as I know it can do on the OnGet
If you look at my OnGet method, you can see that player list is being populated, and subsequently the view is looping through the list, and values are assigned, and I can see the resulting html just as expected.
The exactly same happens in the OnPost method, a player list is being populated with different values, and the view is looping through the new values.
(And that lead me to believe that this was razor re-render the page, but apparently that is not the case. I have a feeling that I'm missing something important here)
But the resulting HTML is not changed at all on the OnPost
public async Task OnGetAsync() { team = await _context.Team.Select(a => new SelectListItem { Text = a.TeamName.ToString(), Value = a.Id.ToString() }).ToListAsync(); player = (from pl in _context.Player where pl.TeamId == 2 select pl).ToList(); }
All-Star
53751 Points
24069 Posts
Re: razor core.net don't render to table onpost but does render ongetasync
Jul 14, 2020 10:26 AM|mgebhard|LINK
The POST response is returned to the AJAX function. It is up to you to design JavaScript that writes the POST response to the page. This is a well known and fundamental concept.
Member
1 Points
7 Posts
Re: razor core.net don't render to table onpost but does render ongetasync
Jul 19, 2020 05:07 PM|barnonline|LINK
I would like the controller to ( re-)render the page, just as it does on the OnGet.
This is the usual approach with Asp.mvc, is it very different with core & razor
And it SEEMS like it is rendered, it loop through the view again, with the new values from the database.
But there is no change in the resulting HTML.
All-Star
53751 Points
24069 Posts
Re: razor core.net don't render to table onpost but does render ongetasync
Jul 19, 2020 05:37 PM|mgebhard|LINK
My best guess is you're asking how to return partial content. See the following blog to understand how to return partial page in Razor Pages.
https://www.learnrazorpages.com/razor-pages/partial-pages
All-Star
58484 Points
15810 Posts
Re: razor core.net don't render to table onpost but does render ongetasync
Jul 20, 2020 02:53 AM|bruce (sqlwork.com)|LINK
If you want the server to render the page, don’t use Ajax. If you make an Ajax call, then then JavaScript gets the response and must update the dom.