Please note that I had already tried to apply the solution on Handling session timeout in ajax calls but did not worked for me.
In an ASP.NET MVC5 project, I open pages by rendering partialview via AJAX as shown below:
function renderPartial(e, controller, action) {
var controllerName = controller;
var actionName = action;
if (String(actionName).trim() == '') {
return false;
}
if (typeof (controllerName) == "undefined") {
return false;
}
var url = "/" + controllerName + "/" + actionName;
$.ajax({
url: url,
data: { /* additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
error: function (jqXHR, textStatus, errorThrown) {
var message = errorThrown;
if (jqXHR.responseJSON != null) {
message = jqXHR.responseJSON.message;
}
},
success: function (data) {
var requestedUrl = String(this.url).replace(/[&?]X-Requested-With=XMLHttpRequest/i, "");
if (typeof (requestedUrl) == "undefined" || requestedUrl == 'undefined') {
requestedUrl = window.location.href;
}
// if the url is the same, replace the state
if (typeof (history.pushState) != "undefined") {
if (window.location.href == requestedUrl) {
history.replaceState({ html: '' }, document.title, requestedUrl);
}
else {
history.pushState({ html: '' }, document.title, requestedUrl);
}
}
//Load partialview
$("#div-page-content").html(data);
}
});
};
On the other hand, when session timeout and call this method by a hyperlink, there is an empty white page on the partialview field where partialview page should be rendered. So, is it possible:
1) to display a partialview at this field?
2) to redirect user Login page?
Note: I would also be happy if you suggest a smart way to Handle Session Expire in ASP.NET MVC. Thanks in advance...
Related
I have a web application with Common.js and it has the following function which is calling when this button btnBookingStatus was clicked.
$(document).on('click', '#btnBookingStatus', function () {
var req = new Object();
req.strMinNo = $(parent.document).find('#hdnFMinNo').val();
req.strSeqNo = $(parent.document).find("#hdnPSeqNo").val();
req.strUserId = $(parent.document).find("#hdnUserId").val();
if (req.strMinNo == undefined || req.strMinNo == '') {
req.strMinNo = $(parent.document).find('#hdnMinNo').val();
}
if (req.strSeqNo == undefined || req.strSeqNo == '') {
req.strSeqNo = $(parent.document).find('#hdnFinSeqNo').val();
}
if (req.strUserId == undefined || req.strUserId == '') {
req.strUserId = $(parent.document).find('#hdnCurrentUserId').val();
}
$.ajax({
type: "POST",
data: JSON.stringify(req),
url: "../Common/LibUiUtilities.aspx/fnCreamsBookingStatus",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
if (data != null) {
var retData = JSON.parse(data.d);
if (retData.oRetunStatus == 'P' || retData.oRetunStatus == 'null') {
alert("Creams Booking still in progress...");
}
else {
$(parent.document).find('#drpBookingStatus').removeAttr('disabled');
$(parent.document).find('#drpBookingStatus').val(retData.oRetunStatus);
$(parent.document).find('#drpBookingStatus').attr('readonly', true);
alert("Creams Booking Success");
}
if (retData.oReturnMsg != undefined && retData.oReturnMsg != 'null') {
$(parent.document).find('#lblBkWarningMsg').text(retData.oReturnMsg);
} else {
$(parent.document).find('#lblBkWarningMsg').empty();
}
}
}
});
});
There are 5 client windows with the same btnBookingStatus button with the same functionality, which needs to be called the above-mentioned JS function. But the hidden field names which pass the parameters are different.
For eg:-
Form1.aspx --> hdnFMinNo, hdnFSeqNo
Form2.aspx --> hdnPMinNo, hdnPSeqNo
Form3.aspx --> hdnMinNo, hdnSeqNo
These element Ids can not be changed
I wanted to pass the parameters (MIN_NO and SEQ_NO) from ASPX to the Common.js without accessing the parent window's elements.
Please help me out with this.
When I click the button that calls the JavaScript, it executes the script which calls the controller that inserts the record using Entity Framework. But it doesn't always reload the page even when I have the location.reload().
What happens is that it successfully submits the record but doesn't reflect in the grid (the list of records), when I submit another record again the first and 2nd inserted record will now show up. Am I doing something wrong with how I'm handling this?
PS, can someone also review my codes as I'm still quite new to web and MVC. Another question of mine is that my form is set like this: #using (Html.BeginForm("Create", "CableSystemType", FormMethod.Get)) but my submit button is declared POST in formmethod, I'm just wondering if this is good practice and if this has a bearing to my issue.
View
<input type="submit" id="btnSave" value="Save" class="btn btn-success" formmethod="post" onclick="return SaveUser();" />
Javascript
function SaveUser() {
debugger;
var json = {
usrId: $('#usrId').val(),
usrDesc: $('#usrDesc').val(),
usrStatus: $('input[name=usrStatus]:checked').val()
};
var chckUsr = document.getElementById("usrDesc").value;
var chckStat = document.querySelector('input[name="usrStatus"]:checked').value;
if (chckUsr === "") {
alert("Description is required.");
return false;
}
if (chckStat === "") {
alert("Status is required.");
return false;
}
$.ajax({
url: '/User/Save_User',
type: 'POST',
dataType: 'json',
data: JSON.stringify(json),
contentType: 'application/json; charset=utf-8',
success: function (response) {
if (response != null && response.success) {
//User is unique
alert(response.responseText);
} else {
//User already exists
alert("response.responseText);
}
//When I put alert in this area it shows up, but page doesn't refresh. I use Chrome
location.reload();
},
});
};
Controller
public JsonResult Save_User(UserViewModel model)
{
string _message = string.Empty;
using (var _odb = new DBEntities())
{
try
{
if (_odb.USR_MSTR.Any(o => o.USR_DESC == model.usrDesc))
{
return Json(new { success = false, responseText = "User already exists." }, JsonRequestBehavior.AllowGet);
}
else {
USR_MSTR usr_master = new USR_MSTR();
string id = Guid.NewGuid().ToString();
usr_master.USR_ID = Guid.NewGuid().ToString().Remove(5);
usr_master.USR_DESC = model.usrDesc;
usr_master.CREA_DT = DateTime.Now;
if (model.usrStatus == "Active")
{
usr_master.INACTV_DT = null;
}
else if (model.usrStatus == "Inactive")
{
usr_master.INACTV_DT = DateTime.Now;
}
_odb.USR_MSTR.Add(usr_master);
_odb.SaveChanges();
return Json(new { success = true, responseText = "User sucessfully saved." }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
_message = "An error occured.";
_message = ex.InnerException.Message;
}
}
return Json(true);
}
I have a connection with my DB and my DB sends me some integer value like "1","2" or something like that.For example if my DB send me "3" I display the third page,it's working but my problem is when it displays the third page it's not hide my current page.I think my code is wrong in somewhere.Please help me
<script>
function show(shown, hidden) {
console.log(shown,hidden)
$("#"+shown).show();
$("#"+hidden).hide();
}
$(".content-form").submit(function(){
var intRowCount = $(this).data('introwcount');
var exec = 'show("Page"+data.result,"Page' + intRowCount + '")';
ajaxSubmit("/post.php", $(this).serialize(), "", exec,"json");
return false;
})
function ajaxSubmit(urlx, datax, loadingAppendToDiv, resultEval, dataTypex, completeEval) {
if (typeof dataTypex == "undefined") {
dataTypex = "html";
}
request = $.ajax({
type: 'POST',
url: urlx,
dataType: dataTypex,
data: datax,
async: true,
beforeSend: function() {
$(".modalOverlay").show();
},
success: function(data, textStatus, jqXHR) {
//$("div#loader2").remove();
loadingAppendToDiv !== "" ? $(loadingAppendToDiv).html(data) : "";
if (typeof resultEval !== "undefined") {
eval(resultEval);
} else {
//do nothing.
}
},
error: function() {
alert('An error occurred. Data does not retrieve.');
},
complete: function() {
if (typeof completeEval !== "undefined") {
eval(completeEval);
} else {
//do nothing.
}
$(".modalOverlay").hide();
}
});
}
</script>
Thanks for your helping my code working fine now.The problem is occured because of the cache. When I clear cache and cookies on Google Chrome it fixed.
The second parameter passed into the show() method is a bit wrong:
"Page' + intRowCount + '"
Perhaps you meant:
'Page' + intRowCount
Edit: wait wait you pass in a string of code to ajaxSubmit? What happens inside it?
If ajaxSubmit can use a callback, try this:
var exec = function(data) {
show('Page' + data.result, 'Page' + intRowCount);
};
Assuming your html is:
<div id='Page1'>..</div>
<div id='Page2'>..</div>
<div id='Page3'>..</div>
add a class to each of these div (use a sensible name, mypage just an example)
<div id='Page1' class='mypage'>..</div>
<div id='Page2' class='mypage'>..</div>
<div id='Page3' class='mypage'>..</div>
pass the page number you want to show and hide all the others, ie:
function showmypage(pageselector) {
$(".mypage").hide();
$(pageselector).show();
}
then change your 'exec' to:
var exec = 'showmypage("#Page"+data.result)';
It would be remiss of my not to recommend you remove the eval, so instead of:
var exec = "..."
use a function:
var onsuccess = function() { showmypage("#Page"+data.result); };
function ajaxSubmit(..., onsuccess, ...)
{
...
success: function(data) {
onsuccess();
}
}
I have an hyperlink of the file name and want to download the file retrieved from database. I can download the file, but the form is posted during this process. Instead of this, I want the form is not posted with the help of ajax, but my code hits error in Ajax call. Is there a smart way to achieve this?
View:
<a onclick="downloadFile(#Model.ID);" target="blank">#Model.FileName</a>
<script>
function downloadFile(id) {
$.ajax({
url: '#Url.Action("Download", "Controller")',
type: "POST",
data: JSON.stringify({ 'id': id }),
dataType: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status == "Success") {
alert("Done");
} else {
alert("error occurs on the database level!");
}
},
error : function () {
alert("an error has occured!!!");
}
});
}
</script>
Controller:
public FileContentResult Download(int id)
{
var dataContext = repository.Attachments.FirstOrDefault(p => p.ID == id);
if (dataContext != null)
{
return File(dataContext.FileData, dataContext.FileMimeType);
}
else
{
return null;
}
}
why not just change your link to
<a href="#Url.Action("Download", "Controller", new { id = Model.ID })" >#Model.FileName</a>
The easiest way to download a file is to link it directly like calling the action: "/FileController/Download?Id=2"
The problem is that if you get an error, it will redirect you to a blank page...
To resolve this i created this function:
function DownloadFile(id, Type) {
var hiddenIFrameID = 'hiddenDownloader',
iframe = document.getElementById(hiddenIFrameID);
if (iframe === null) {
iframe = document.createElement('iframe');
iframe.id = hiddenIFrameID;
iframe.style.display = 'none';
document.body.appendChild(iframe);
}
if (Type == undefined || Type == "")
Type = null;
iframe.src = "/File/Download?ID=" + id;
}
This function creates an hidden iframe pointing to the file path (action). If it gives an error, it will not blow up your page.
I have a MVC web app that receives data from a database and displays it in a table for the user. The user goes through a series of dropdowns and buttons, each being populated using AJAX calls. Then a table is created and shown. As an example, here is one such section of code.
#Html.LabelFor(model => model.RootID)
#Html.DropDownListFor(model => model.RootID, Model.AvailableRoots)
<input type="button" id="RootsBtn" value="Go" />
<script language="javascript" type="text/javascript">
$(function () {
$("#RootsBtn").click(function () {
var selectedItem = $('#RootID').val();
$("#MiscTable").empty();
$.ajax({
cache: false,
type: "GET",
url: RootDirectory + "Home/GetTableData/",
data: { "id": selectedItem },
success: function (data) {
var myTable = $('#MiscTable');
$.ajax({
cache: false,
type: "GET",
url: RootDirectory + "Home/GetProperties/",
data: { "id": selectedItem },
success: function (data2) {
if (data2['IsAddAvailable'] == 'True' && data2['IsViewOnly'] == 'False' && data2['IsEnabled'] == 'True' &&
data2['IsViewOnly_User'] == 'False' && data2['IsEnabled_User'] == 'True') {
$('#Add' + data2['TableName']).show();
}
if (data.length > 0) {
var firstRecord = data[0];
var headerRow = $('<thead>');
for (var columnTitle in firstRecord) {
headerRow.append($('<th>', { text: columnTitle }));
}
headerRow.append($('<th>', { text: " " }));
myTable.append(headerRow);
var record;
var dataRow;
for (var dataIndex = 0; dataIndex < data.length; dataIndex++) {
record = data[dataIndex];
dataRow = $('<tr>');
for (var column in firstRecord) {
dataRow.append($('<td>', { text: record[column] }));
}
var id = record['ID'];
var showDelete = ((record['IsDeleteAvailable'] == 'True' || ((record['IsDeleteAvailable'] == null || record['IsDeleteAvailable'] == "") && data2['IsDeleteAvailable'] == 'True')) && data2['IsDeleteAvailable_User'] == 'True');
var showEdit = ((record['IsEditAvailable'] == 'True' || ((record['IsEditAvailable'] == null || record['IsEditAvailable'] == "") && data2['IsEditAvailable'] == 'True')) && data2['IsEditAvailable_User'] == 'True');
var str1 = RootDirectory + data2['TableName'] + "/Edit/" + id;
var str2 = RootDirectory + data2['TableName'] + "/Details/" + id;
var str3 = RootDirectory + data2['TableName'] + "/Delete/" + id;
if (showDelete && showEdit && data2['IsViewOnly'] != 'True' && data2['IsViewOnly_User'] != 'True') {
dataRow.append('<td>Edit<br />Details<br />Delete</td>');
}
else if (!showDelete && showEdit && data2['IsViewOnly'] != 'True' && data2['IsViewOnly_User'] != 'True') {
dataRow.append('<td>Edit<br />Details</td>');
}
else if (showDelete && !showEdit && data2['IsViewOnly'] != 'True' && data2['IsViewOnly_User'] != 'True') {
dataRow.append('<td>Details<br />Delete</td>');
}
else {
dataRow.append('<td>Details</td>');
}
myTable.append(dataRow);
}
}
},
error: function (xhr, ajaxOptions, throwError) {
alert("Error");
}
});
$('#MiscTable').show();
},
error: function (xhr, ajaxOptions, throwError) {
alert("Error");
$('#MiscTable').hide();
}
});
});
});
</script>
Everything works right now to display whatever table has been chosen by the user in the dropdown list. When the user uses a link in the table (Edit, Details, Delete) they are taken to a new page to handle this action. When finished it takes them back to this main page. Unfortunately the state of their dropdowns and table were obviously not stored, so they have to go through the menus again to see their changes.
I have heard that there are anchors that can allow a page to go to a specific configuration of javascript/AJAX. I've tried to search for it but haven't been successful. What I am wanting is the ability for the user to search through my dropdowns and select table X. Then in table X they can say to edit item Y. When finished editing Y and clicking submit (or back to table to undo changes) rather than going back to the start of the main page, it should repopulate the dropdowns and go back to showing table X.
Maybe a link like /Home/Index/#X?
Is this possible and how would it be done?
You're talking about hash fragments. In a general sense, all this is doing is using the target as a dumping ground for data needed to render the page as it was, since the target portion of the URL is not sent to the server and doesn't cause a page refresh. On it's own this does nothing, but you could have JavaScript on page that parses this information out of the URL and does something meaningful with it.
So for your purposes you could go with something like:
`/path/to/page#select1=foo&select2=bar`
Then, you would need JS on that page that pulls out the fragment (location.hash) and parses out the name value pairs to finally use that to set the selects back to the state they were in previously and load whatever data needs to be loaded via AJAX.