Refresh Page on Back Click - MVC 4 - asp.net-mvc-4

What would be a simple way to force my ActionResult to always fire when I hit this page? On browser back click, for instance, this will not execute.
public ActionResult Index()
{
//do something always
return View();
}

Disabling cache on the ActionResult forces the page to refresh each time rather than rendering the cached version.
[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]
public ActionResult Index()
{
//do something always
return View();
}
Now when you click the browsers back button, this is hit every time.

You could try the onunload event and ajax:
<script>
window.onunload = function () {
$.ajax({
url: '/ControllerName/Index',
type: 'POST',
datatype: "json",
contentType: "application/json; charset=utf-8"
});
};
</script>

Adding this code to my HTML works just fine for me:
<input id="alwaysFetch" type="hidden" />
<script>
setTimeout(function () {
var el = document.getElementById('alwaysFetch');
el.value = el.value ? location.reload() : true;
}, 0);
</script>
This might come handy for those who prefer not to deal with server side code as opposed to the accepted solution.
All it does is assign a value to a hidden input on first load which will remain on the second load in which case the page is force refreshed.

Related

Remote model annotation refreshes page on success

Model Class
[Remote(
"isExaminationTemplateInUse",
"GENExaminationTemplate",
AdditionalFields = "ExaminationTemplateID",
ErrorMessage = "Template Name already exists.",
HttpMethod = "POST"
)]
[Required(ErrorMessage = "Template Name is required.")]
[DisplayName("Name")]
public String ExaminationTemplateName { get; set; }
Controller
[HttpGet]
[HttpPost]
[Route("isExaminationTemplateInUse")]
public async Task<ActionResult> isExaminationTemplateInUse(String ExaminationTemplateName, int ExaminationTemplateID)
{
return Json(true);
}
AJAX Part
//Submit Main Form.
$(document.body).on("submit", "#mainForm", function (event) {
//Prevent Default Region.
event.preventDefault();
//Post Region.
//Serialize the form datas.
$.ajax({
url: '/GENExaminationTemplate/SetExaminationTemplate',
type: "post",
async: true,
data: { pstrJSONMasterData: jsonMasterData },
success: function (response) {
window.location.href = response;
}
});
});
Add New Record Mode, Works Fine. Reason: In this mode focus moves through the field and on submit it does not go for validation.
Edit Record Mode, Not Works Fine. Reason: Focus not moves through the field, On click of submit button system moves into action "isExaminationTemplateInUse" and on line "return Json(true);" refreshes page, that moves to page load function rather page save function. However, by just passing focus through the field that is using [Remote], system works fine.
In scripts section following file references are also present on top of the page.
jquery.js,jquery.validate.js, jquery.validate.unobtrusive.js

How to add client click event to div to call method in ASP.NET Core 2.2 Razor page

I made a calendar in a Razor page, and I want to make each date (a div) clickable so they call a method and pass it the clicked date (div id set to date). I'm generating the calendar in the cs page and I'm not using MVC controllers.
#model Budget.Pages.CalendarModel
#{
ViewData["Title"] = "Calendar";
}
<form method="post">
#Html.Raw(Model.getCal())
</form>
And then in my cs page I have the method getCal() that generates a calendar via divs, css and some math, which is working fine, but I need to attach onClick events to each day (div).
public string getCal()
{
//I won't print out all of my calendar generation code in ordfer to simplify this question.
//The code below happens in a loop where the MM, DD and YYYY change as appropriate to be
//unique. This is where I want to put my onclick events to call another method, onDateSelect(this.id)
retValue += "<div id='" + MM + "_" + DD + "_" + YYYY + "' class='col-md-9 dayCell'>" +
strDayNo +
"</div>";
return retValue; //When out of loop of course
}
After rendering the content with #Html.Raw(Model.getCal()) in your page , you can add click event on your div :
#section Scripts{
<script>
$(document).on('click', ".dayCell", function () {
});
</script>
}
Razor Pages are designed to be protected from (CSRF/XSRF) attacks. Hence, Antiforgery token generation and validation are automatically included in Razor Pages. Please refer to below article for code sample :
Handle Ajax Requests in ASP.NET Core Razor Pages
Here is code sample based on your requirement :
#section Scripts{
<script>
$(document).on('click', ".dayCell", function () {
$.ajax({
type: "POST",
url: "/YourPageName?handler=Send",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: JSON.stringify({
ID: this.id
}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
},
failure: function (response) {
alert(response);
}
});
});
</script>
}
Server side function :
public JsonResult OnPostSend([FromBody]PostData value)
{
....
}
public class PostData
{
public string ID { get; set; }
}
Also configure the antiforgery service to look for the X-CSRF-TOKEN header:
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");

Cannot get json data with ajax in Razor Pages [duplicate]

This question already has answers here:
Example AJAX call back to an ASP.NET Core Razor Page
(8 answers)
Closed 5 years ago.
i am trying to get some data from Razor Pages in ASP.NET Core 2.0.
But the problem is that it does not returns any data.
I also tried debugging it, it does not fire that method (OnGetProducts) at all.
The model Index.cshtml.cs:
private IProductRepository _productRepository;
public IndexModel(IProductRepository repository)
{
_productRepository = repository;
}
public void OnGet()
{
}
public IActionResult OnGetProducts(int page)
{
var model = _productRepository.GetProducts().Skip(page * 10).Take(10);
return new JsonResult(model);
}
the razor page Index.cshtml
<div id="products">
</div>
#section scripts{
<script>
$(function () {
getProducts(0);
});
var isInitialized = false;
function getProducts(page) {
$.ajax({
type: 'GET',
url: "Products",
contentType: "application/json",
dataType: "json",
data: {
handler: 'Products',
page: page
},
success: function (datas) {
console.log(datas);
}
});
}
</script>
}
p.s. this page in in folder Pages/Products/Index.cshtml(.cs)
I usually use razor functions to generate URLs instead of hard coding them in js. If your action is not even being triggered, assuming that you are not accidentally in release mode, it is because the URL doesn't point to the right location. First of all set js variables in razor something like this:
var productsURL = #Url.Context("~/products");
Also run yourdomain/products in your browser and if you get a 404.
Alternatively I use this function to directly use c# objects in js:
public static IHtmlContent ToJS(this IHtmlHelper htmlHelper, object obj)
=> htmlHelper.Raw(JsonConvert.SerializeObject(obj));
With this function created in a static class, you can also create a js object directly something like this:
<script>
var products = #Html.ToJS(repository.GetProducts().Skip(page * 10).Take(10));
</script>
Of course this will only create the object in page load, if you want it to change after page load, you can consider creating a partial view via ajax. Also note that the second alternative will be slower than the first for ajax.

MVC 4 View Knockout Bindings not updating on ajax call

I have gone through as many questions on here as I could find and tried all the different suggestions and cannot get this to work. I have a view that is bound with Knockout using the mapping plugin and it works okay but only when I do the "wrong thing". Everything that I have read says that you should only make one call to ko.applyBindings() per view and then everything should update using ko.mapping.fromJS(). I cannot seem to get this to work, the only way I have been able to get my view to refresh is to call ko.applyBindings() again in the success call back from my .ajax() call. Here is the offending code.
<script type="text/javascript">
var viewModel;
$(document).ready(function() {
$("#panelbar").kendoPanelBar({
expandMode: "multiple"
});
$.ajax({
type: 'GET',
url: '/Home/IsUserMarketingManager',
success: function (data) {
if (data == true) {
$('#submitNewCase').hide();
$('#approveCase').show();
$('#disapproveCase').show();
}
}
});
// Generate client View Model from Server View Model
viewModel = new ViewModel();
ko.mapping.fromJS(#Html.Raw(Json.Encode(Model)),{}, viewModel);
ko.applyBindings(viewModel);
});
function ViewModel () {
var self = this;
self.addLocation = function() {
self.AdditionalLocations.push({ GaNumber: "" });
};
}
</script>
And later this to update the form with retrieved data:
<script type="text/javascript">
$('#btnImport').click(function () {
$.blockUI({ message: '<h2>Importing Client Information...</h2> <img src="/Images/ajax-loader.gif"><br />' });
$.ajax({
type: 'post',
url: '/Home/ImportClientCrmInfoJson',
dataType: "json",
data: ko.mapping.toJS(viewModel),
success: function (data) {
$.unblockUI();
if (!data.AccountNull) {
ko.mapping.fromJS(data, {}, viewModel);
} else {
alert("Could not find account for this GA Number, please try again.");
}
}
});
});
</script>
When submitting the form to my controller, all the data is there and mapped correctly to my server side View Model, but the form in the view isn't updated with the data that comes back from the $.ajax call. I've gotten the form to update if I do the following, but I know it's not the right way and has caused me other issues as well.
<script type="text/javascript">
$('#btnImport').click(function () {
$.blockUI({ message: '<h2>Importing Client Information...</h2> <img src="/Images/ajax-loader.gif"><br />' });
$.ajax({
type: 'post',
url: '/Home/ImportClientCrmInfoJson',
dataType: "json",
data: ko.mapping.toJS(viewModel),
success: function (data) {
$.unblockUI();
if (!data.AccountNull) {
viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel); // This works but isn't the right way...
} else {
alert("Could not find account for this GA Number, please try again.");
}
}
});
});
</script>
Any help would be much appreciated.
Have you examined that the following line of code appears to create a 'NEW' viewmodel?
viewModel = ko.mapping.fromJS(data);
When you do this the new viewModel the old bindings are destroyed. This is why you have to call ApplyBindings again. Anyway, I think the above line of code is the root of the problem.
Is there a way for you to create an observable property on the viewModel and allow the viewModel to reflect the data in this object? That may be a more practical approach to the update process.
In the success callback of the ajax call, use this method ko.applyBindings(viewModel) but pass as a second parameter the DOM portion you want to update as follows
ko.applyBindings(viewModel, $("#mydiv")[0])
Don't use a jquery object but a REAL DOM object.

How to get the load event before ajax call to PHP returns

I would like my webpage to render faster. Based on this article, I understand that the page renders when the 'load' event is fired.
When I look at the Network Tab of my Chrome browser, I see that the 'load' event is fired after an ajax call to a PHP script returns.
Webpage is live at http://www.99like.com/index.php
=> Is there any way to get the page to render before the PHP script is called?
Following is the extract of the code which I think is relevant for the question:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="highcharts.js"></script>
<script type="text/javascript">
var ajax_load = "<img class='loading' src='images/load.gif' alt='loading...' />";
var inputForm = "<div class='shadow'><form type='submit' onsubmit='displayChart(); return false'><input id='searchBox' type='text' size='30' value='search keyword' /></form></div>";
var chart = "<div id='chart' class='shadow'></div>";
var chartPage = inputForm + chart;
$(function ()
{
exampleChart();
});
function exampleChart() {
$('#searchBox').val("hotel"); // nice example
displayChart ();
}
function displayChart () {
var keyword = $('#searchBox').val();
var chart = new Highcharts.Chart({ ... });
chart.showLoading();
var phpFunctionURL = "getChartData.php";
var DataSeries;
$.ajax( {
url: phpFunctionURL,
dataType: 'json',
async: false,
data: { ... },
success: function(json) { DataSeries = json; }
} );
}
</script>
A few remarks:
Make sure all your JavaScript are at the bottom of the page, including JQuery and Google Analytics code
Your web-page is missing the end tag
If needed, you could wait for the onLoad event to launch your AJAX request instead of the DomReady event, this will speed up the page rendering.
Looks like your AJAX request is synchronous. Making it asynchronous will solve the problem.
$.ajax( {
url: phpFunctionURL,
dataType: 'json',
async: true, // Changed from false to true
data: { ... },
success: function(json) { DataSeries = json; }
} );