Change ASP.Net Session ID - Call from Desktop App via AJAX - c#

I have an old VB6 application - I need to shell out to a ASP.net site via a web browser. I have the browser opening and calling the ASP site successfully. I need the VB6 app to know when the Web Browser session is closed. The VB app form (or save button) needs to be disabled when the web browser session is open. (I don't want to use the process Id of the windows process to check this.)
My thought are:
Cross domain cookies perhaps? (security?)
I have my VB6 app able to call server WebMethods
Saving a session ID in the database which is usedbut both apps?
Some advice would be excellent. Many thanks.

Internal Company Applications.
Desktop App (VB6)
Code to allow VB6 apps to contact Asp service. On any Asp.Net page create an extra [WebMethod] in this case a ‘IsWindowOpen’ method has been added to the test.aspx page (see red text beow)
Send a JSON message to the ASP.Net service to query if a WINDOWS_STATUS Session variable is set (this tells us if a browser window is open\closed).
When shelling out to the Asp.Net site with parameters (plan Id etc.) we’ll send in an extra param for ‘Session Id’.
Randomly generate a Session Id in VB6 app [random: 24 char long, lower case, and digits between 0-5], this is replicating how the Asp.Net framework is going to generate its own Session Id for communication between the HTML and C#. We will then override the Asp.Net Session Id given to us by Asp.Net with our own random generated Session ID.
Check if ASP.Net session variable is set in VB6:
Private Sub Command1_Click()
Dim objHTTP As Object
Dim Json As String
Dim result As String
' === Check if Browser Session is open ===
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
url = "http://dub-iisdev/SessionTest/test.aspx/IsWindowOpen"
objHTTP.open "POST", url, False
objHTTP.setRequestHeader("cookie") = "ASP.NET_SessionId=" + txtCookie.Text ' Required twice
objHTTP.setRequestHeader("cookie") = "ASP.NET_SessionId=" + txtCookie.Text ' Required twice
objHTTP.setRequestHeader "Content-type", "application/json"
objHTTP.send (Json)
result = objHTTP.responseText
txtOutput.Text = result
Set objHTTP = Nothing
End Sub
ASP.Net
We’ll need a few pieces of plumbing here :
A small method for setting ASP.Net session IDs
A small closing aspx page which will run some code when we leave the browser, and
Some extra C# methods and JavaScript in our existing pages.
1. Setting Session ID:
Copy variable from old session to new location
protected void ReGenerateSessionId(string newsessionID)
{
SessionIDManager manager = new SessionIDManager();
string oldId = manager.GetSessionID(Context);
string newId = manager.CreateSessionID(Context);
bool isAdd = false, isRedir = false;
manager.RemoveSessionID(Context);
manager.SaveSessionID(Context, newsessionID, out isRedir, out isAdd);
HttpApplication ctx = (HttpApplication)HttpContext.Current.ApplicationInstance;
HttpModuleCollection mods = ctx.Modules;
System.Web.SessionState.SessionStateModule ssm = (SessionStateModule)mods.Get("Session");
System.Reflection.FieldInfo[] fields = ssm.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
SessionStateStoreProviderBase store = null;
System.Reflection.FieldInfo rqIdField = null, rqLockIdField = null, rqStateNotFoundField = null;
SessionStateStoreData rqItem = null;
foreach (System.Reflection.FieldInfo field in fields)
{
if (field.Name.Equals("_store")) store = (SessionStateStoreProviderBase)field.GetValue(ssm);
if (field.Name.Equals("_rqId")) rqIdField = field;
if (field.Name.Equals("_rqLockId")) rqLockIdField = field;
if (field.Name.Equals("_rqSessionStateNotFound")) rqStateNotFoundField = field;
if ((field.Name.Equals("_rqItem")))
{
rqItem = (SessionStateStoreData)field.GetValue(ssm);
}
}
object lockId = rqLockIdField.GetValue(ssm);
if ((lockId != null) && (oldId != null))
{
store.RemoveItem(Context, oldId, lockId, rqItem);
}
rqStateNotFoundField.SetValue(ssm, true);
rqIdField.SetValue(ssm, newsessionID);
}
Your first landing page will set the new Session ID (from VB6) param sent into the server– using out ReGenerateSessionId class above.
After this code executes out instance to Asp.Net and our instance of VB6 will have the same Session Id for HTTP communication
protected void Page_Load(object sender, EventArgs e)
{
// Simulate Session ID coming in from VB6...
string sessionId;
Random rnd = new Random();
sessionId = "asdfghjklqwertyuiop12345" [24 char - a to z (small) & 0-5]
// Set new session variable and copy variable from old session to new location
ReGenerateSessionId(sessionId);
// Put something into the session
HttpContext.Current.Session["SOME_SESSION_VARIABLE_NAME"] = "Consider it done!";
}
2. Open\Closing Browser
One of the ASP.Net pages needs to have three new WebMethods: SetOpenWindow, SetClosingWindow and IsWindowOpen
Opening the Browser:
C#. SetOpenWindow:
This will be called from your first (or any required) HTML pages via the .ready JavaScript. When the page has loaded the JavaScript will simply fire an Ajax call to the SetOpwnWindow web method. The method will set a Session variable WINDOW_STATUS to OPEN.
[WebMethod()]
[ScriptMethod(UseHttpGet = false)]
public static string SetOpenWindow()
{
HttpContext.Current.Session["WINDOW_STATUS"] = "OPEN";
return "Status:" + HttpContext.Current.Session["WINDOW_STATUS"];
}
ASPX. Call SetOpenWindow from Ajax once the page has loaded. This sets the WINDOW_STATUS to OPEN
<script src=”Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
jQuery.ajax({
url: 'test.aspx/SetOpenWindow',
type: "POST",
dataType: "json",
data: "",
contentType: "application/json; charset=utf-8",
success: function (data) {}//alert(JSON.stringify(data));
});
$("#form1").submit(function () {
submitted = true;
});
});
</script>
Closing the Browser:
On pages where the browser window can be closed call JavaScript to catch when the browser window is closing (handy to add this to your master page instead of to each page!). This calls the ClosingSessionPage aspx page to run the SetClosingWndow webmethod:
<script type=”text/javascript”>
var submitted = false;
function wireUpWindowUnloadEvents() {
$(document).on('keypress', function (e) { if (e.keyCode == 116) { callServerForBrowserCloseEvent(); } }); // Attach the event keypress to exclude the F5 refresh
$(document).on("click", "a", function () { callServerForBrowserCloseEvent(); }); // Attach the event click for all links in the page
}
$(window).bind("onunload", function () { if (!submitted) { callServerForBrowserCloseEvent(); event.preventDefault(); } });
$(window).bind("beforeunload", function () { if (!submitted) { callServerForBrowserCloseEvent(); event.preventDefault(); } });
window.onbeforeunload = function () { if (!submitted) { callServerForBrowserCloseEvent(); } };
window.onunload = function () { if (!submitted) { callServerForBrowserCloseEvent(); } };
$(window).bind("onunload", function () { if (!submitted) { callServerForBrowserCloseEvent();event.preventDefault();} });
function callServerForBrowserCloseEvent() {
window.open("ClosingSessionPage.aspx", "Closing Page", "location=0,menubar=0,statusbar=1,width=1,height=1"); }
function btn_onclick() { open(location, '_self').close(); }
</script>
The close JavaScript method above redirects to a closing aspx page to run some ajax and then close itself – The Ajax calls SetClosingWindow the session WINDOW_STATUS variable to CLOSED.
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server" title="Closing Session">
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
jQuery.ajax({
url: 'test.aspx/SetClosingWndow',
type: "POST",
dataType: "json",
data: "",
contentType: "application/json; charset=utf-8",
success: function (data) {
window.close();
} }); });
</script>
</head>
<body>
<form id="form1" runat="server">
<p>Closing browser session, please wait.</p>
</form>
</body>
</html>
C# SetClosingWindow
Called from Ajax JavaScript when the Browser window is closing and sets WINDOW_STATUS to CLOSED:
[WebMethod()]
[ScriptMethod(UseHttpGet = false)]
public static string SetClosingWndow()
{
HttpContext.Current.Session["WINDOW_STATUS"] = "CLOSED";
ScriptManager.RegisterClientScriptBlock((Page)(HttpContext.Current.Handler), typeof(Page), "closePage", "window.close();", true);
return "Status:" + HttpContext.Current.Session["WINDOW_STATUS"];
}
3. Is Browser Open?
ASP.Net WebMethod called by VB6 whenever it needs to know if the Browser window is Open or Closed.
[WebMethod()]
[ScriptMethod(UseHttpGet = false)]
public static string IsWindowOpen()
{
string isWindowOpen = HttpContext.Current.Session["WINDOW_STATUS"] != null ? HttpContext.Current.Session["WINDOW_STATUS"].ToString() : "CLOSED";
return "IsWindowOpen:" + isWindowOpen;
}

Related

How to redirect after session timeout in MVC .Net?

I want to redirect my page after 2 minutes of inactivity, for this I am using the below code to ping the controller every 2.5 minutes and if the session has expired I redirect to the original login page:
`<script language="javascript" type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script language="javascript" type="text/javascript">
var ReqTime =#Session.Timeout
ReqTime = ReqTime * 60 * 1000 + (.5 * 60 * 1000);
$(function () {
setInterval(CheckSession, ReqTime);
});
function CheckSession() {
$.post('#Url.Action("SessionInfo","Home")', null, function () {
console.log("Time");
});
}
</script>
Controller:
public ActionResult SessionInfo()
{
if (Session["LoginUserName"]==null)
{
return RedirectToAction("Index","Home");
}
}
This code does not re-direct to the Home/Index. Can you tell me where I'm going wrong?
Try using Javascript instead ,since redirect from server side need a post back
You can check session by controller and return a value to figure out if session end or not
function CheckSession() {
$.ajax({
type: "GET",
url: "#Url.Action("SessionInfo", "Home")"
}).done(function (data) {
if (data === true) {
window.location.href = "#Url.Action("Index", "Home")";
}
}).fail(function (e) {
alert('Error');
});
}
Controller
public JsonResult SessionInfo()
{
if (Session["LoginUserName"] == null)
{
return Json(true, JsonRequestBehavior.AllowGet);
}
return Json(false, JsonRequestBehavior.AllowGet);
}
This code for explaining
By making those session checking ajax request you just extend life-span of the user session.
If you would like to inform browser that user session has end I recommend to implement a SignalR service to have direct communication ( push capability ) between server and the browser ( realtime ).
Implement a SignalR service,
Create a session_end method in your global.asax file, in the session_end send a message to user browser that your session has end.
Just it

Passing an array from javascript to code behind - C#

In my website, i'm declaring an array in javascript and insert them elements dynamically. So now, I want use that array from my C# code. I don't want use ajax to send that element to an web service... I just want use an C# event, like OnClick and access the array that was build in javascript.
I searched for an answer but I just found the oposite.
Thanks
The easiest way is AJAX call and i don't understand why you are avoiding that ?
Make an AJAX call from your button click.
look here a demo :
Ajax call is not calling to the server side and in httpfox shows error as "Error loading content (NS_ERROR_DOCUMENT_NOT_CACHED)" in ajax post call
for example : covert your array to a json string and call a web client in your c# code. Here i have a button . on button click i want to send my GRIDVIEW data to c# method(web method).
you need to remember that while sending json data using stringfy() method,
in server side we need to define the parameter as object.
not any other format like string/int/bla bla.....
use Scripts/jquery-1.8.3.min.js
http://code.jquery.com/ui/1.10.3/jquery-ui.js
$('#btnResult').on('click', function () {
var mydata = [];
$("#<%=GridProjectDetails.ClientID %> tr").each(function () {
var myObject = new Object();
var id = $(this).find("input[name*='ID']").val();
var locationcode = $(this).find("input[name*='TextLocationCode']").val();
var Location = $(this).find("input[name*='TextLocation']").val();
myObject.id = id;
myObject.locationcode = locationcode;
myObject.Location = Location;
mydata.push(myObject);
});
var myString = JSON.stringify({ details: JSON.stringify(mydata) });
alert(myString);
var exportdata = myString;
$.ajax({
type: "POST",
url: "Default.aspx/ExportToExcel",
data: exportdata,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$("#Result").text(data.d);
},
error: function () { alert(arguments[2]); }
});
});
});
and server side method should be
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string ExportToExcel(object details)
{
return "Message : Success";
}
It's a kinda weird thing to do, but if you have to do it, you can do it by creating a form, inside the form have a hidden text field and call a function when submitting to update the value of this field.
The markup:
<form id="yourForm" method="post" >
<input type="text" name="hiddenFieldName" id="hiddenFieldName" hidden="hidden" />
</form>
The javascript:
void yourProcedure() {
var yourArray = ["Value1", "Value2", "Value3", "Value4"];
document.getElementById('hiddenFieldName').value = yourArray.join();
document.getElementById("yourForm").submit();
}
Then in the server, the form variable will contain "Value1,Value2,Value3,Value4".

access/iterate over a C# list in jQuery

i am trying to make an image gallery with pictures fading in and out. I already have that part covered, but so far im hard coding the image url's in my .aspx page. I don't want this, i need it to be dynamic.
<script type="text/javascript">
$(function()
{ var img = $("img.x");
$(img).hide().eq(0).show();
var cnt = img.length
setInterval(imgRotate, 5000);
function imgRotate() {
$(img).eq((img.length++) % cnt).fadeOut("slow",
function() {
$(img).eq((img.length) % cnt).fadeIn("slow");
});
}
});
</script>
<body>
<form id="form1" runat="server">
<div>
<img class="x" alt="Image1" src="Desert.jpg"/>
<img class="x" alt="Image1" src="Lighthouse.jpg"/>
</div>
</form>
this makes the images fade in and out, which is good, but as you can see, i've hardcoded the images in this example. I can't use this for my application.
What i want to do is the following:
i want to pass a List<string> (codebehind) to the jQuery script that will just iterate over the list and replace the source url of the image.
i just want to do something like this in the jQuery script (pseudo-code):
int counter = 0;
var img = ListFromCodeBehind[counter];
//do some fading stuff
count++;
i've tried using <%=%> server tags, and so forth but to no avail. I've read lots of things but they all seem overly complicated for what i'm trying to achieve..
Why is everybody forcing you to use AJAX? There is no need to load image list in separate HTTP request. I assume your code comes from some aspx page. Therefore you can provide a public method in this Pages's class (lets call it GetImages()) that returns a string that looks like JavaScript array. I.e.
public string GetImages()
{
return "['Desert.jpg', 'Lighthouse.jpg']";
}
Then in you JavaScript code (that is placed in this Page's aspx file as well) you can call public method of Page's class with classic ASP syntax:
int counter = 0;
var ListFromCodeBehind = <%= this.GetImages() %>;
var img = ListFromCodeBehind[counter];
//do some fading stuff
count++;
which will finally print:
var ListFromCodeBehind = ['Desert.jpg', 'Lighthouse.jpg'];
and this is the result I believe you expect.
You can add a Web Method into your aspx page (code behind) that can be called by AJAX.
Your code behind method will return a string that contains the URL to the images, in a JSON format (so that JQuery knows how to iterate though it out of the box).
Have a look at this thread to have an idea of how to create a web method in an aspx code behind file. I'd do it via asp.net MVC though...much more straightforward
Calling an ASP.NET server side method via jQuery
//Controller
[HttpGet]
public JsonResult GetImageURLS()
{
var urls = GetUrls();
return Json(new { urls = urls }, JsonRequest.AllowGet);
}
//js file
$.ajax({ url : '/GetImageURLS/', success : function(e) { if (e && e.urls) {
var $images = $(".images");
for (var i in e.urls) {
$images.append('<img src="' + i.url + '" class="x" ' + ' alt="' + i.alt + '" /> ';
}
});
//html
<div class="images">
</div>
Try this for initial load of the images. Then call your function on them after the images are populated.
You can use AJAX and call a webservice in your Javascript to return your image list as follows:
function LoadImages() {
var url;
url = "WebServices/wsImages.asmx/GetImageList"
$.ajax({
type: "POST",
url: url,
contentType: "application/json; charset=utf-8",
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
},
success: function (response) {
var imgList = response.d;
//Loop through image list etc.
}
});
}

Redirecting to another page in ASP.NET MVC using JavaScript/jQuery

I want to redirect from one page to another page in ASP.NET MVC 3.0 using JavaScript/jQuery/Ajax. On button click event I have written JavaScript code like below.
function foo(id)
{
$.post('/Branch/Details/' + id);
}
My controller code is like this:
public ViewResult Details(Guid id)
{
Branch branch = db.Branches.Single(b => b.Id == id);
return View(branch);
}
When I click on a button it is calling the Details action inside BranchController, but it doesn't return to the Details view.
I didn't get any error or exception. It's showing status 200 OK in Firebug. What is wrong in my code and how can I redirect to the Details view page?
You are not subscribing to any success callback in your $.post AJAX call. Meaning that the request is executed, but you do nothing with the results. If you want to do something useful with the results, try:
$.post('/Branch/Details/' + id, function(result) {
// Do something with the result like for example inject it into
// some placeholder and update the DOM.
// This obviously assumes that your controller action returns
// a partial view otherwise you will break your markup
});
On the other hand if you want to redirect, you absolutely do not need AJAX. You use AJAX only when you want to stay on the same page and update only a portion of it.
So if you only wanted to redirect the browser:
function foo(id) {
window.location.href = '/Branch/Details/' + id;
}
As a side note:
You should never be hardcoding urls like this. You should always be using url helpers when dealing with urls in an ASP.NET MVC application. So:
function foo(id) {
var url = '#Url.Action("Details", "Branch", new { id = "__id__" })';
window.location.href = url.replace('__id__', id);
}
This could be done by using a hidden variable in the view and then using that variable to post from the JavaScript code.
Here is my code in the view
#Html.Hidden("RedirectTo", Url.Action("ActionName", "ControllerName"));
Now you can use this in the JavaScript file as:
var url = $("#RedirectTo").val();
location.href = url;
It worked like a charm fro me. I hope it helps you too.
You can use:
window.location.href = '/Branch/Details/' + id;
But your Ajax code is incomplete without success or error functions.
// in the HTML code I used some razor
#Html.Hidden("RedirectTo", Url.Action("Action", "Controller"));
// now down in the script I do this
<script type="text/javascript">
var url = $("#RedirectTo").val();
$(document).ready(function () {
$.ajax({
dataType: 'json',
type: 'POST',
url: '/Controller/Action',
success: function (result) {
if (result.UserFriendlyErrMsg === 'Some Message') {
// display a prompt
alert("Message: " + result.UserFriendlyErrMsg);
// redirect us to the new page
location.href = url;
}
$('#friendlyMsg').html(result.UserFriendlyErrMsg);
}
});
</script>
<script type="text/javascript">
function lnkLogout_Confirm()
{
var bResponse = confirm('Are you sure you want to exit?');
if (bResponse === true) {
////console.log("lnkLogout_Confirm clciked.");
var url = '#Url.Action("Login", "Login")';
window.location.href = url;
}
return bResponse;
}
</script>
check the code below this will be helpful for you:
<script type="text/javascript">
window.opener.location.href = '#Url.Action("Action", "EventstController")', window.close();
</script>

update field or redirect page using jquery and asp.net mvc

Im new to jquery and stuck with what i want to achieve.
Heres what I want to do using jquery and asp.net mvc.
click a submit button
this calls an action method called LogOn in the controller Account
if the call allows users to log in succesfully redirect to a url (sepecified by LogOn)
if it fails replace a div(with id="error") with "sorry error occured"
so far I tried this:
$("#submit")
.button()
.click(function () {
$.ajax({
type: "POST",
url: "Account/LogOn",
dataType: "json",
success: function (data, textStatus) {
if (data.redirect) {
// data.redirect contains the string URL to redirect to
window.location.href = data.redirect;
}
else {
// data.form contains the HTML for the replacement form
$("#error2").replaceWith(data.error);
}
}
});
});
how do I construct the relevant bits in the action method? to make this work?
and is the jquery code ok? i suspect prob not.
Thanks
If you want to redirect asp.net page at same directory , you can by Jquery/Java script by this :
$("#ctl00_iframecontent_BtnCancle").click(function () {
window.location = "IncSLAList.aspx?bi=37";
});
and
To redirect to Another page of project , can use :
window.location.href = "http://ImageUpload/Welcome.aspx?
Your jQuery is almost correct:
Don't call .button() (unless you're using jQuery UI and want to do that)
Add return false; at the end of the click handler to prevent the browser from submitting normally.
In the action, you would either return Json(new { redirect = str }) or return Json(new { error = str }).

Categories