Nancyfx Request.Session not holding values on AJAX post - c#

I'm quite new to Nancy so hopefully I'm just doing something silly here. I've got a nancy service which I'm posting data to like so:
$.ajax({
type: 'POST',
url: url,
data: JSON.stringify({
searchTerm: productSearchTerm,
pageSize: pageView.PageSize(),
selectedBrands: pageView.checkedBrands(),
pageNumber: pageView.CurrentPage(),
selectedCategories: pageView.checkedCategories(),
selectedGender: pageView.checkedGender(),
SelectedColours: pageView.checkedColour(),
saleItemsOnly: pageView.saleItemsOnly(),
selectedMinimumPrice: pageView.minPrice(),
selectedMaximumPrice: pageView.maxPrice()
}),
contentType: "application/json; charset=utf-8",
dataType: 'json'
})
.done(function (data) {
bindSearchResult(data);
})
.fail(function (a) {
console.log(a);
});
Then in the service I need to hold on to a bunch of string values for future requests from the user, which I'm doing like this:
private void AddListOfStringToIsSessionNull(string name, IEnumerable<string> data)
{
if (Session[name] == null)
{
Session[name] = data.ToList();
}
}
These seems to set the session variables and an "_nc" cookie is present when I inspect the page after it returns.
However if I then F5 the page the session items are all null again at the server.
I've ruled out are cross site posting as it's all on the same domain.
Could this be an AJAX thing? Seems unlikely as this seems a pretty standard thing to do.
Or can you not set it on a POST?
If so is there a way around this?
If someone could help I'd be forever grateful as otherwise I'm going to have to revert back to writing this in WCF which will make me hurl myself from the window :)
Thanks a lot.
Edit
Open a new incognito window in Chome I hit home page, no nancy cookie
present (which is correct)
Enter a search term which calls back over and AJAX post and grabs JSON, also pops a list of strings in the Nancy Session
Check cookie, a nancy one has appeared like so and the session value is correct on post back:
npTBnqPp99nLd5fU0%2btJbq%2fY%2bdf2UFWTaq5D28Az7Jw%3dzF8cIHNxTWX399sbmowjheho2S29ocpKs1TXD51BrbyPPNCeLfAcYqWhkRHqWdwKJNED5kuspllIjhI5rf2W6NKtf8xo68BlF5eLLgJxMtAxw2yD2ednEzUazq1XBt2Id77t5LE5tZVwkpRGDT5b9J0nQnr9zfzCOALXb2hQQGBPkMVyNNTO24pW1UC6Uda3B86LLYA02Jgy4G9DiT6KsutR3pSXO8AZFOlcmAEHbSSX9A8FAHaL ... etc.
I then search for a different search term which calls this bit of code:
--Session.DeleteAll();
The nancy session is re-populated with new data and returns back to the browser
However at this point the cookie has not been updated with the new value it is still as below:
npTBnqPp99nLd5fU0%2btJbq%2fY%2bdf2UFWTaq5D28Az7Jw%3dzF8cIHNxTWX399sbmowjheho2S29ocpKs1TXD51BrbyPPNCeLfAcYqWhkRHqWdwKJNED5kuspllIjhI5rf2W6NKtf8xo68BlF5eLLgJxMtAxw2yD2ednEzUazq1XBt2Id77t5LE5tZVwkpRGDT5b9J0nQnr9zfzCOALXb2hQQGBPkMVyNNTO24pW1UC6Uda3B86LLYA02Jgy4G9DiT6KsutR3pSXO8AZFOlcmAEHbSSX9A8FAHaL.... etc.
Is there anything else I need to do to solve this?

So my issue was me being a bit daft really, the implementation of the cookie stuff works well, however there were occasions when I was stuffing too much into the cookie and pushing it over the 4K cookie limit.
This meant that I was seeing some inconsistent behavior where sometimes the cookie worked nicely (the cookie was < 4K) where as for some search terms too much was being written into the cookie which meant either the cookie was never created or it was not overwriting the existing cookie.
So yes, my fault, but thought this answer might aid someone as silly as me trying to store the world in a cookie..
Right I'm off to write a session provider.

Related

Display consistently changing value on an ASP.NET web form

I am currently writing a program in C# that constantly outputs random values between 1 and 12 and displays them in a label control on an ASP.NET web form. While the output is successfully written to the web form, it only displays one value. In other words, I want the label output to track the output (display) each value that is produced by the function as written below to produce a consistently changing value:
[WebMethod]
public static string StreamData()
{
string[] value = new string[1];
Random rnd = new Random();
Thread t = new Thread(delegate ()
{
while (true)
{
value[0] = rnd.Next(1, 13) + "";
}
});
t.Start();
return value[0];
}
I have tried using an AJAX function to pull the data from the function but I am not too sure if I am going about displaying the data in the right way:
<script type="text/javascript">
$(function () {
$.ajax({
type: 'POST',
url: 'default.aspx/streamdata',
data: '',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (msg) {
//alert(msg.d);
$('#<%= lblReading.ClientID %>').html(msg.d);
}
});
});
</script>
The program is being written to test the concept of trending live data from PLCs using TIA Portal 15 with said data obtained from sensor readings across a production line. The idea behind this program is to serve as a proof of concept that real-time data can in fact be displayed and trended in an ASP.NET web environment to be accessed across a range of web-compliant devices. Despite my efforts in displaying random values in this way, my attempts have been thus far unsuccessful, although I am determined to not give up. I researched this method which uses SignalR to achieve something similar to my desired solution, though I am unsure of how to implement it in my case: How to implement real time data for a web page
Could somebody please shed some light on how the above might be achieved?
Many Thanks,
Ben.
Your requirement can be accomplished in ASP.Net web forms using SignalR.
Please take a look at this small tutorial on how to do that,
Adding SignalR to an ASP.NET WebForms Project

Webmethods with HttpContext.Current.User.Identity.IsAuthenticated stop working after inactivity on Azure

I'm testing the Azure server with pages that use Ajax(json)/Webmethod functions.
Some of those functions check HttpContext.Current.User.Identity.IsAuthenticated before they run code. Unfortunately, if a user is logged in and the page doesn't make a full postback request to the server, only those webmethods functions that check HttpContext.Current.User.Identity.IsAuthenticated stop running completely after couple of minutes without giving any error. They don't even run the else code block (see below).
I've tested those pages on a local server and everything worked fine as it should, even after a long period of inactivity. Here is an example of a webmethod
[WebMethod]
public static string serviceMenu(int IDservice)
{
StringBuilder SBphotoMenu = new StringBuilder();
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
// Do stuff
}
else
{
// Do other stuff
}
return SBphotoMenu.ToString();
}
I'm calling the webmethod as follows:
function serviceMenu(IDservice) {
$.ajax({
type: "POST",
url: "/UserControls/serviceMenu",
data: "{ IDservice: " + IDservice }",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
// Do Stuff
}
})
}
This behavior occurs only if the user is logged in. Now if the user is not logged in then all functions work properly even on Azure.
As a matter of fact, when the webmethods stop running and I refresh the page the user is still logged in and the webmethods start running again but for couple of minutes only and then the same behavior occurs again.
What's going wrong?
The problem is caused by the session variables and not autentication. In fact the session state is not maitained for ASP.NET applications in Azure using the default "inProc" method. Azure uses other methods, of which some are costy: Table storage, SQL Azure, or Windows Azure Caching.

How to get data from a client on load?

I'm aware that data can be passed in through the URL, like "example.com/thing?id=1234", or it can be passed in through a form and a "submit" button, but neither of these methods will work for me.
I need to get a fairly large xml string/file. I need to parse it and get the data from it before I can even display my page.
How can I get this on page load? Does the client have to send a http request? Or submit the xml as a string to a hidden form?
Edit with background info:
I am creating a widget that will appear in my customer's application, embedded using C# WebBrowser control, but will be hosted on my server. The web app needs to pass some data (including a token for client validation) to my widget via xml, and this needs to be loaded in first thing when my widget starts up.
ASP.NET MVC 4 works great with jQuery and aJax posts. I have accomplished this goal many times by taking advantage of this.
jQuery:
$(document).ready(function() {
$.ajax({
type: "POST",
url: "/{controller}/{action}/",
data: { clientToken: '{token}', foo: 'bar',
success: function (data, text) {
//APPEND YOUR PAGE WITH YOUR PARSED XML DATA
//NOTE: 'data' WILL CONTAIN YOUR RETURNED RESULT
}
});
});
MVC Controller:
[HttpPost]
public JsonResult jqGetXML(string clientToken, string foo)
{
JsonResult jqResult = new JsonResult();
//GET YOUR XML DATA AND DO YOUR WORK
jqResult.Data = //WHATEVER YOU WANT TO RETURN;
return jqResult;
}
Note: This example returns Json data (easier to work with IMO), not XML. It also assumes that the XML data is not coming from the client but is stored server-side.
EDIT: Here is a link to jQuery's Ajax documentation,
http://api.jquery.com/jQuery.ajax/
Assuming you're using ASP.NET, since you say it's generated by another page, just stick the XML in the Session state.
Another approach, not sure if it helps in your situation.
If you share the second level domain name on your two sites (i.e. .....sitename.com ) then another potential way to share data is you could have them assert a cookie at this 2nd level with the token and xml data in it. You'll then be provided with this cookie.
I've only done this to share authentication details, you need to share machine keys at a minimum to support this (assuming .Net here...).
You won't be able to automatically upload a file from the client to the server - at least not via a browser using html/js/httprequests. The browser simply will not allow this.
Imagine the security implications if browsers allowed you to silently upload a file from the clients local machine without their knowledge.
Sample solution:
Background process imports xml file and parses it. The background process knows it is for customer YYY and updates their information so it know the xml file has been processed.
A visitor goes to the customer's web application where the widget is embedded. In the markup of the widget the customer token has been added. This could be in JavaScript, Flash, iFrame, etc.
When the widget loads, it makes a request to you app which then checks to see if the file was parsed for the provided customer (YYY) if it has, then show the page/widget.
If the XML is being served via HTTP you can use Liqn to parse the data.
Ex.
public partial class Sample : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string url = "http://news.yahoo.com/rss/";
var el = XElement.Load(url).Elements("channel");
StringBuilder output = new StringBuilder();
foreach (var c in el.Elements())
{
switch (c.Name.LocalName.ToLower())
{
case "title":
output.Append(c.Value);
output.Append("<br />");
break;
}
}
this.Label1.Text = output.ToString();
}
}
It is not exactly clear what the application is and what kind of options you have, and what kind of control over web server you have.
If you are the owner of the web server/application your options are way wider. You can first send a file to web-server with HTTP POST or PUT, including a random token, and then use the same token for GET with token in the query string
or use other options, applicable to third party-owned websites
if you are trying to consume some auth api, learn more about it. since you are hosting web browser control, you have plenty of options to script it. including loading whatever form, setting textarea or hidden field text with your xml and then simulating a submit button click. you can then respond to any redirects and html responses.
you can also inject javascript inside the page that would send it to server with ajax request.
the choice heavily depends on the interaction model.
if you need better advice, it would be most helpful if you provided sample/simplified url/url pattern, form content, and sequence of events that is expected from you from code/api/sdk perspective. they are usually quite friendly.
There are limited number of ways to pass data between pages. Personally for this I would keep in session during the generating page and clear it when it is retrieved in the required page.
If it is generated server side then there is no reason to retrieve it from client side.
http://msdn.microsoft.com/en-us/library/6c3yckfw(v=vs.100).aspx
Create a webservice that your C# app can POST the XML to and get back HTML in response. Load this HTML string into the WebBrowser control rather than pointing the control to a URL.

Replacing Timer text with result of DB calculation when Timer hits 00:00:00

I have a jQuery Countdown Timer that I am using, and I need to be able to access my Database and perform some calculations and then return the result:
$('#expireMessage').countdown({until: shortly,
expiryText: '<div class="over">It\'s all over</div>'});
$('#expireMessageStart').click(function() {
shortly = new Date();
shortly.setSeconds(shortly.getSeconds() + 5.5);
$('#expireMessage').countdown('change', {until: shortly});
});
Now, the above code just displays a countdown timer, and counts down. And when it hits
00:00:00
it displays a message "It's all over".
But what I need it to do is display a different message depending on the result of the DB calculations.
The DB work I can do, but I'm not sure how to go about retrieving that info from the database when using jQuery. I'd really appreciate your help.
Thank you
You need to set up something on the server side to talk to the database for you, then return the result in JSON format. What that something is depends on what your server-side code is written in. Are you using PHP? Java? ASP.NET?
I work primarily in ASP.NET, so one way I might tackle this is adding a WebMethod to my page that executes a database query, builds the message, serializes it to JSON, and returns it to the client.
In your JavaScript, you'll want to execute either an XMLHttpRequest (if you're using regular JavaScript) or a jQuery AJAX request.
Here's a very simple example of what a jQuery AJAX call might look like:
$.ajax({
url: 'http://mysite.com/getmymessage',
success: function( data ) {
// Here's where you'd update your countdown display, but I'm just writing to the console
console.log( 'The server says: ' + data.myDbResult );
}
});

Wait for file to exist in ASP.NET

I have an ASP.NET page, where the user is able to trigger a console app on our server, which generates a file. What I want is the user to see a message that states 'Requesting file', then as soon as the file becomes available (i.e. File.Exists for the file returns true), the Requesting file message will change to a link of the file.
Is this easy to accomplish in ASP.NET?
In you web page implement a JSON call to a certain WebMethod which checks if the file has be been generated or not.
you can add your message in the calling function and clear it in the complete event, where you can create the link to the file also
function ddlLeaveChanged(sender, e) {
if (leaveTypeId != '-1' && dateFrom != '' && leaveStatusId != '-1') {
$('#lblMessage').show();
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: WebServiceUrl + 'YourMethod',
success: FunctionSuccedded,
error: FunctionFailed
});
}
function FunctionsSuccedded(result, e) {
if (result) { $('#lblMessage').hide(); }
}
This can be achieved using a combination of:
Javascript setInterval
[jquery.Ajax][2]
ASP.NET Web Method
A javascript function can be triggered every x seconds (using setInterval) to trigger a Web Method using AJAX to check whether the file exists.
Check the links I've provided above. These should be all you need to get this working.
If you want to avoid file systems all together you could key off a database field as well, i.e. when the linked is clicked an entry is made into a database table of some sort that signifies file creation pending, and then periodically check if the status has been updated. The server side code would update that same key and have a url in the datastore as well, so you could just check for the status of file created and the link the datastore. This would also result in you having a history of file creation, which you could purge as you saw fit, so from an ASP.NET perspective you would only be relying on data access code to determine if your file was created.
Not much different in ASP.NET vs any other platform. You can go about it like this:
Make AJAX call when the triggering link is clicked.
Server-side code that handles the call launches an external process to generate the file, and waits for it to complete.
After checking that the file is indeed there, reply to the AJAX call with a meaningful message (i.e. one that contains enough information to build a link to the file).

Categories

Resources