DNN: HttpContext.Current.Session not Working - c#

I'm not an expert in .NET programming and I'm trying to solve this problem but no success.
We decided to revamp our old website and part of it is to switch theme. But we have a function from old that we can't move to the new theme.
Our old website has a function that will get user's session code, so that if they move to our affiliate website via url, they will be automatically logged in.
This is the code from our old theme...
OLD THEME CODE
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="/Home.ascx.cs" Inherits="Mandeeps.DNN.Skins.Tucson.Tucson" %>
<%# Register TagPrefix="dnn" Namespace="DotNetNuke.Web.Client.ClientResourceManagement" Assembly="DotNetNuke.Web.Client" %>
<script type="text/javascript">
var onetimeurl = "<%#HttpContext.Current.Session["OneTimeURL"]%>";
$(document).ready(function() {
$('.financials_link').attr("href", "https://sub.domain.com?authToken=" + onetimeurl);
$('.financials_link').attr("target", "_blank");
var service = $.ServicesFramework(-1);
$.ajax({
type: "GET",
url: service.getServiceRoot("WebAuthModule") + "webauth/getauthtoken",
beforeSend: service.setModuleHeaders,
dataType: "json"
}).done(function(a) {
a && $(".financials_link").attr("href", "https://sub.domain.com?authToken=" + a)
});
});
</script>
It's working great. But when moved the code to the new theme, the code is not showing up and its breaking the page's layout. And I'm getting this error.
Line 20: Error BC30516: Overload resolution failed because no accessible 'ToString' accepts this number of arguments.
NEW THEME CODE
<%# Control Language="vb" AutoEventWireup="false" Explicit="True" Inherits="DotNetNuke.UI.Skins.Skin" %>
<script type="text/javascript">
var onetimeurl = "<%#HttpContext.Current.Session["OneTimeURL"]%>"; <!--LINE 20-->
$(document).ready(function() {
$('.financials_link').attr("href", "https://sub.domain.com?authToken=" + onetimeurl);
$('.financials_link').attr("target", "_blank");
var service = $.ServicesFramework(-1);
$.ajax({
type: "GET",
url: service.getServiceRoot("WebAuthModule") + "webauth/getauthtoken",
beforeSend: service.setModuleHeaders,
dataType: "json"
}).done(function(a) {
a && $(".financials_link").attr("href", "https://sub.domain.com?authToken=" + a)
});
});
</script>
Noticed on the first line, I added the control codes because that is the only thing I think is different from each other. The rest are pretty much the same.
What I've done so far is I decompiled the Home.ascx (.dll) and looked for the OneTimeURL, but I wasn't able to find it.
I wish you guys can spot the problem so I can fix this.

It seems odd to me that you are saying the old one is C# and the new one is VB??
But given what I see above, try this, just change the square brackets to parens, so the new line 20 is:
var onetimeurl = "<%#HttpContext.Current.Session("OneTimeURL") %>";
If that doesn't work, then add try adding this function at the bottom.
<script runat="server">
Public Function GetSession() As String
Return HttpContext.Current.Session("OneTimeURL")
End Function
</script>
And then line 20 would need to be:
var onetimeurl = "<%#GetSession() %>";

Related

How can I perform an ajax call to .aspx.cs

I've spent 4 days trying to make an ajax call to my .aspx.cs. In the best case, I got answer in html format. I don't understand why that happened, maybe I have to add some lib from NuGet or write something in web.config?
What I tried:
[HttpPost] [HttpGet]
[WebMethod]
jQuery ajax call
change url
my first app was a sample from VS with razor pages, I thought the problem was in using razor, so I created new project - a empty web application, but I still got the same answer from server in html format.
What I want to get:
My app imitates a vending machine. A user click on buttons with coins and coins have to increase on server side. (BtnAddCoin()) Also user's coins are always showing on a panel. (ShowInsertedCoins())
ClientSide.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="ClientSide.aspx.cs" Inherits="VendingMachine.ClientSide" Async="true" AsyncTimeout="60" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<link rel="stylesheet" href="StyleSheet.css" />
<title></title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
function AddCoin(coin) {
alert(coin);
var val1 = coin;
$.ajax({
type: "POST",
url: "/ClientSide.aspx/BtnAddCoin",
data: '{coin: "' + coin + '" }',
dataType: "text",
success: function (data) {
alert("AddCoin" + data);
},
error: function (req, status, error) {
alert(error + status);
}
}).done(function (result) { ShowInsertedCoin(); });
}
function ShowInsertedCoin() {
var insertedCoins = document.getElementById('InsertedCoins');
alert('ShowInsertedCoin');
$.ajax({
type: "GET",
url: "/ClientSide.aspx/ShowInsertedCoins",
dataType: "text",
data: {},
success: function (data) {
alert("ShowInsertedCoin " + data);
insertedCoins.textContent = data;
}
});
}
</script>
</head>
<body>
<form id="form1" runat="server">
</form>
<div>
<h1>Coffee machine</h1>
</div>
<div>
<div>
<p> Add coins: </p>
<div>
<div>
<a id ="coin1" onclick="AddCoin(1)"> 1 </a>
<a> 2 </a>
<a> 5 </a>
<a> 10 </a>
</div>
</div>
<div>
<p id="InsertedCoins" ><%=ShowInsertedCoins()%> </p>
</div>
</div>
</div>
</body>
</html>
ClientSide.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace VendingMachine
{
public partial class ClientSide : System.Web.UI.Page
{
static int coins = 10;
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static string ShowInsertedCoins()
{
return "You inserted: " + coins.ToString();
}
[WebMethod]
public void BtnAddCoin(int coin)
{
coins = +coin;
//ShowInsertedCoins();
}
}
}
So, how I can do an ajax call to .aspx.cs with jQuery or js?
Why do I get html format when my function has to return a string?
Thanks for your attention and help.
Lots of issues here.
First issue?
You have this static value for the page class:
static int coins = 10;
You can't really control, or use or have static values in a class. The MAIN reason is such values will apply to all users of the site - not just the one user.
You can as a general rule call, use, consume static classes. In fact in vb.net, we OFTEN create a Module, and inside we have our boatload of helper routines, and routines that we freely call that library of code. While each of the routines can freely use local values, you can NOT use variables global to that module, since no instance of the class is being created, and as a result, multiple users will/would be able to set such values - and overwrite values used by other users. Worse yet, how long does the server persist such static values?
Answer: it is a total Las Vegas gamble.
this means to persist that coin count, we can choose one of MANY possible ways to persist that value.
We can have a global JavaScript variable hold the value.
We can use a control like text box to hold the value (and hide it)
We can use a hidden control (so ViewState will hold the value).
We can use ViewState directly to the hold the value (client side persisting), but is managed by server side code.
We can use session() to hold the value (server side persisting)
Over the years, we see "many" attempts to pass, share, persist data vales in a static class. It sometimes works, and often during development it "seems" to work, but the instant you deploy to a real working site, it blows up in a huge ball of flames.
So, using a static class to hold a Hodge podge of code? Sure, no problem, and that's quite much what we do in c# to obtain general "code module" of routines that we need throughout the applcation. But, be a vb.net module, or in c# a static class? Any concept of global values to that static class MUST be taken off the table and NOT used!!
Ok, so let's cook up a working example. We first have to choose a place/spot to hold and persist our coin count.
Hum, we have many choices. However, since this example code involves server side code. Then let's use session.
I mean, it would kind of defeat this whole example if we write the code 100% client-side JavaScript (which is not all that bad of a idea). However, since we attempting to learn, and use a web method?
Then let's wire this up using a web method. (as noted, we really don't need to use any server-side code here).
So, if we going to use session() to persist the value, then on first page load, we setup our coin count with a starting value of 10.
Also, WHEN you use/call/consume a web method of the page? There is NOT a instance of the page class. As a result, ANY AND ALL web methods must be static. In fact, it means really don't care if we placed the web method in the current page, is some ascx file, or wherever. Since the web page is NOT being posted back to the server, then all of the controls, values and things on that web page are STILL sitting on your desktop, and there is no copy of the web page in existence on the server side.
Next up:
data: '{coin: "' + coin + '" }',
dataType: "text",
So, you have some jason data, yet on the next line you saying we going to use text? Nope!!! If you going to pass json data the method, it going to return such json data back. Same goes if you choose xml, or whatever.
So, you can't pass json data, but then on the next line state we going to use text!!!!!
Ok, so our server side code now becomes this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// setup starting coin count
Session["CoinCount"] = (int)0;
}
}
[WebMethod(enableSession: true)]
public static void BtnAddCoin(int coin)
{
int MyCoins = (int)HttpContext.Current.Session["CoinCount"];
MyCoins += coin;
HttpContext.Current.Session["CoinCount"] = MyCoins;
Debug.Print("coins = " + MyCoins.ToString());
}
[WebMethod(enableSession: true)]
public static string ShowInsertedCoins()
{
int MyCoins = (int)HttpContext.Current.Session["CoinCount"];
return "You inserted: " + MyCoins.ToString();
}
Now, for client side, DO NOTE that when you use json format, then the return value/results are of the ".d" property of the web method. This is a asp.net thing, and it just the way it works.
So, now our client side code;
<div>
<div>
<p>Add coins: </p>
<div>
<div>
<a id="coin1" onclick="AddCoin(1)">1 </a>
<a>2 </a>
<a>5 </a>
<a>10 </a>
</div>
</div>
<div>
<p id="InsertedCoins"></p>
</div>
</div>
</div>
<script>
function AddCoin(coin) {
$.ajax({
type: "POST",
url: "/CoinCount.aspx/BtnAddCoin",
data: JSON.stringify({ coin: coin }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
// alert("AddCoin" + data);
ShowInsertedCoin();
},
error: function (req, status, error) {
alert("x" + error + status);
}
}).done(function (result) { ShowInsertedCoin(); });
}
function ShowInsertedCoin() {
var insertedCoins = $('#InsertedCoins');
$.ajax({
type: "POST",
url: "CoinCount.aspx/ShowInsertedCoins",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: {},
success: function (data) {
insertedCoins.text(data.d);
}
});
}
</script>
Next up?
How did "form2" get inserted into this page?
If you create a new aspx page, (web forms), then the last gazillion pages will have by default form1, and BIG flag that you have form2 here.
Anyway, the above should work. Note that you not only are sending json data, but you as a general rule need to add the content type, and you had this missing:
contentType: "application/json; charset=utf-8",
Also, so far we only added a click event for the "1", and you have to do the same for the other 3 values you have.
As other people already commented, it's recommended to use newer technologies, other than Webforms, but if you want to continue using it or it's an project of your work or something related, here's how I normally do in Javascript:
$.ajax({
method: "POST",
url: "ClientSide.aspx/BtnAddCoin",
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify({
obj: JSON.stringify(data)
}),
success: function (response) {
let return = JSON.stringify(response.d);
// something
},
error: function (ex) {
// something
console.log(ex.Message)
},
beforeSend: function () {
// something
},
complete: function () {
// somethin
}
});
And for the C# file, every time you want to make an webmethod, that method need to be public and static, just like that (at least I learned that every time needs to be static):
[WebMethod]
public static string BtnAddCoin(int newCoin)
{
return newCoin;
}
Try and see if that helps

Convert string to HTML to inject to paragraph via WebMethod

Im doing a Maintenance Page where people can store the description of what it will say in a Resource file, at this point in the requirement they dont even know if the text will be pure text or will have tags like <a></a>. So at this point I have to assume it will be the case.
This proyect have been made in Webforms framework 3.5 in VS2010.
For simplicity sake I'll reveal the relevant parts:
<article>
<img alt="an image" src="Images/logo.jpg"/>
<h2>Site under Maintenance</h2>
<div>
<p id="Description"></p>
</div>
</article>
<script src="Includes/jquery-1.12.3.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: "GET",
url: "MaintenanceSite.aspx/GetMaintenanceDescription",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
$("#Description").text(msg.d);
}
});
});
</script>
Backend:
[WebMethod]
[ScriptMethod(UseHttpGet = true)]
public static string GetMaintenanceDescription()
{
string mensaje = HttpUtility.HtmlEncode(Resources.MaintenanceDescription);
return mensaje;
}
The problem is, Im receiving this on my paragraph:
<To href="">Contact Us</a>
(without the spaces as stack overflow is parsing the html correctly).
What am I missing?
There's two issues here. Firstly you need to remove the call to HtmlEncode() in the C# logic to return a plain HTML string. Secondly you need to use jQuery's html() method to display it instead of text(), as the latter will again encode the HTML.
string mensaje = Resources.MaintenanceDescription;
$("#Description").html(msg.d);

Dynamically created jQuery controls are not being added to my asp.net page

I am not quite sure what I am doing wrong here, I have a page in my webforms project which uses jQuery accordion. When the page is loaded for the first time, the server side code fetches some data to populate a user control which is then added to my page as shown below. This works fine and I have no problem with this.
The problem is, I am trying to generate a similar thing on my client, using jQuery by simply creating the controls in jQuery ajax response function and then add to dvProjects
ASPX markup:
<asp:Content ID="Content2" ContentPlaceHolderID="Content" runat="server">
<div runat="server" id="dvProjects" class="dvAccordion">
</div>
</asp:Content>
jQuery AJAX code:
function AddUserProject() {
var projectDialog = $('.dvEditExhibition');
var projectName = projectDialog.find('.txtProjectName').val();
var projectDescription = projectDialog.find('.txtProjectDescription').val();
var project= JSON.stringify({
'projectId': "00000000-0000-0000-0000-000000000000",
'projectName': projectName,
'projectDescription': projectDescription
});
$.ajax({
type: "POST",
url: "PresentationService.asmx/AddUserProject",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: project,
success: function(response) {
var data = response.d;
console.log(data);
var h3Title = $('<h3/>', {
id: "h3ProjectTitle",
text:data.Name
});
var divWrapper = $('<div/>', {
});
var dvProjectImages = $('<div/>', {
class: "dvProjectImages"
});
var imgProjectImage = $('<img/>', {
id: "imgProjectImage",
class: "imgProjectImage"
});
var dvProjectDetails = $('<div/>', {
id: "dvProjectDetails",
});
var pProjectDescription = $('<p/>', {
id: "pProjectDescription",
class: "pProjectDescription",
text: data.Description
});
dvProjectImages.append(imgProjectImage);
dvProjectDetails.append(pProjectDescription);
divWrapper.append(dvProjectImages, dvProjectDetails);
var dvProjects = $('#dvProjects');
dvProjects.append(h3Title);
},
error: function(response) {
}
});
}
My problem is these controls are not added to dvProjects.
Update: you had a bug in your javscript too, refer to my comments.
That's because when you set a div to runat="server" every html element in it, becomes a Literal Control server side and they are persisted to view state.
When you post the page, the server side control rebuilds the runat="server" div with information in the postdata (view state).
When you add controls with jQuery they are not in the postData/ViewState, so when the server side code revuilds the div, it doesn't see the ones you added with jQuery.
To fix that, you would need to create a custom WebControl and implement IPostBackEventHandler. So instead of...
<div runat="server" id="dvProjects" class="dvAccordion">
You would have something like this,
<xyz:ProjectsControl runat="server" cssclass="dvAccordion" id="theProjects" />
Then to add a control to it, you would do something like
__doPostBack('<%= theProjects.UniqueID %>, 'someJsonStringHere');
Then in your IPostBackEventHandler implementation, you serialize the json string coming in and use that to determine what server side controls to add to the ProjectsControl.
WebControl has methods you can override, WriteBeginTag, WriteEndTag, and there you could write an opening div and closing div, so your web control would render as a div.
By adding a string property calledd "CssClass" to your webcontrol, you can use that to set the class. So in WriteBeginTag you would also write out the class attribute to the div using CssClass as the value.

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.
}
});
}

using ajax in asp.net c#

how can i use ajax to call a server side method i tried this code but it gives me the alert error messsage and i can't find my problem please help and thank you :
enter code here
<%# Control Language="C#" AutoEventWireup="true" CodeFile="ImageEditor_UserControl.ascx.cs" Inherits="ImageEditor_UserControl" %>
<script type="text/javascript" src="Scripts/jquery-1.4.1.js"></script>
<script type ="text/javascript">
$(document).ready(function () {
$('#<%=uploadButton.ClientID %>').click(function () {
$.ajax({
type: "POST",
url: "ImageEditor_UserControl.ascx/helo",
data: "{}",
contentType: "application/json;charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function () { alert("success"); },
error: function () { alert("error"); }
})
return false;
});
});
</script>
<asp:Button ID="uploadButton" runat="server" Text="Upload" />
C# Code
[WebMethod]
public static string helo() {
return "Message from server.";
}
You should call *.asmx files (there are other options but this is for the beginning).
Look out for tutorials on web services & ajax consuming.
Have you checked on the line $('#<%=uploadButton.ClientID %>').click(function () { that the
<%=uploadButton.ClientID %> is actually replace by the value and not taken literally?
Do you use firefox? if yes, install the addon "FireBug". Enable firebug to check the request and the response.
Firebug will show you sometimes the error message returned from the server, as in you jquery syntax you are not loading the attributes for the method anonymous method callback for error.
error: function (req,error) { alert("error: " + req.statusText); }
This will give you a heads up on what is going wrong.
Unfortunately you cannot call a page method (server side method) that is a part of a user control. You will have to use a method in an aspx page.

Categories