Edge + Express + SQL Server unexplainable StackOverflow - c#

So I've been banging my head against a wall trying to figure this one out. A StackOverflow is crashing my server whenever I try to retrieve data from SQL Server using several different methods but I am unable to pinpoint the exact cause of the issue.
I've been able to put together a structure with Express that retrieves data from my database when the server stands up, but when I attach a route to the same method, I get "the" StackOverflow (I'm unsure if there is a single cause for the crash or if I'm dealing with two separate issues that both manifest as Stack Overflows)
I'll focus this question on one of the stack overflows in the hope that it is responsible for all of the crashes.
At any rate, this is the server config that was able to marshal data back to node from the .NET class library(which in turn makes the ADO.NET calls into my MSSQL db):
var express = require('express');
var http = require('http');
var edge = require('edge');
var app = express();
app.set('port',process.env.PORT || 3000);
app.use(app.router);
var repository = {
list: edge.func({assemblyFile:'bin\\Data.dll',typeName:'Data.GetListTask',methodName:'Invoke'})
});
app.get('/tickets', repository.list);
http.createServer(app).listen(app.get('port'),function(request,response){
console.log('Express server listening on port ' + app.get('port'));
console.log('[Before][repository.list]');
repository.list({}, function(error, result) {
console.log('[Result][repository.list]');
if(result){
result.forEach(function(item){
console.log('[List contains]{' + item.Id + '|' + item.Description + '}');
});
}
else{
console.log('No items found');
}
});
});
Whenever the server starts, the repository's list is retrieved and spooled to the console; however, if I use my /tickets route, the server crashes with a Stack Overflow.
The "good" response:
The crash when I try to activate my route (the real route is named 'tickets')
I'm not very experienced with node or express, so I'm not entirely sure I've specified that '/tickets' route properly.

This was a stupid problem with my Express route.
app.get('/tickets', function (request, response) {
ticketRepository.getTickets({}, function (error, result){
response.json(result);
});
});
returns the results from my database as expected.
protip: If you're trying to respond with "stuff", it helps to actually put "stuff" on the response.

Related

Is it possible to have more than one parse client configured in a single app?

So I have a few different parse servers setup.
One server is just to capture error logs from various applications (I have a LOT out there) in nice uniformed database.
So I might have a specific standalone data migration tool that if it encounters an error, will write out the exception into this Error_log parse table/class. No problem there.
But, if I have an app that uses a Parse Database for itself, I have not been able to figure out how to let it work on it's own parse server configuration for it's own stuff, but write out error logs to this other Parse server instance.
Yes... I could go through the trouble of writing out something via the REST api just for writing out logs,but I am I trying to avoid that and stick with native parse APIs for the particular platform I am on because of the benefits that the APIs give over REST (like save eventually for the none .NET stuff).
EDIT
Some clarification was requested so here I go...
On the app side of things (c# for this example but the same holds true for iOS etc)… I do the usual initialization of the Parse client as such …
ParseClient.Initialize(new ParseClient.Configuration
{
ApplicationId = "MyAppID",
WindowsKey = "MyDotNetKey",
Server = "www.myparseserver.com/app1"
});
So for all calls to save a parse object go through that parse client connection
But what I need to do would be something like this ….
//Main App cloud database
ParseClient1.Initialize(new ParseClient.Configuration
{
ApplicationId = "MyAppID",
WindowsKey = "MyDotNetKey",
Server = "www.myparseserver.com/app1"
});
ParseClient2.Initialize(new ParseClient.Configuration
{
ApplicationId = "MyAppID",
WindowsKey = "MyDotNetKey",
Server = "www.myparseserver.com/errorcollection"
});
try{
ParseConfig config = null;
config = await ParseConfig.GetAsync().ParseClient1;
} catch (Exception ex){
ParseObject MyError = new ParseObject("Error_Log");
MyError["Application"] = "My First App-App2";
MyError["Error"] = ex.message;
await MyError.Save().ParseClient2;
}
Yes - this is all fake code... my point is I want to be able to have multiple ParseClient instances in one app.
Now... I can simply write a routine that writes out errors that resets the ParseClient.Initialization to the error parse server instance and then redo it back to the original (primary app data) instance when it's done... but that is just asking for trouble in a multi threaded environment and will cause conflicts if some other thread in the app goes to write out parse data right at the moment the error method resets the init.
If ParseClient were IDisposable I could probably do that using :
ParseClient ParseErrorServer = new ParseClient();
ParseErrorServer.ApplicationId = "hmmm";
ParseErrorServer.WindwosKey= "hmmm";
ParseErrorServer.Server= "www.hmmm.com/errorcollection";
using ParseErrorServer {
//Do The Work
}
Is that clear as mud yet? ;P
Without alteration I believe none of the Parse SDKs have the ability to initialise multiple instances.
In the iOS SDK for example, is possible to make a new instance (say with a different server url) upon restarting the app but you cannot have multiple. There has also been discussion on the iOS SDK about being able to change the configuration without restart but no one has implemented this yet.
We would happily review a PR for this, however it would require a major and complex overhaul as you would have to manage cache, users etc across multiple instances.

server.transfer in express node js

I would like to transfer request one server to another server. Like server.transfer in C#. I know we can go for response.redirect or response.writeHead methods in nodejs but these have a client side (browser) interaction.
In my case, the user should not see where I am redirecting as it should server to server call.
As of now, I have achieved by unirest.
app.get('/home', function(request, response) {
unirest.get("www.example.com/userdetails").end(function (res) {
response.send(res.body)
});
});
But am expecting same in express. suggestions welcome.
You can do that inside express with http.request method, but you can also use higher level packages, like request and axios.
I created an express module to add req.transfer(path, preserveData) to all routes. This allows you to internally transfer requests without sending a redirect to the client:
var express = require('express');
var requestTransfer = require('express-request-transfer');
var app = express();
app.use(requestTransfer); // adds req.transfer method to all routes
// route 1
app.get('/api/time', function(req, res){
res.send(new Date());
});
// route 2
app.post('/', function(req, res){
// transfer without form/query data
req.transfer('/api/time');
// transfer with incoming form/query data
// req.transfer('/api/time', true);
});
It functions the same as Server.Transfer from C#. Source code on GitHub

Calling wcf aync service in asp.net core 2.0 while waiting the result

I do understand that I might be getting this wrong since I am porting asp.net application to asp.net core 2.0 (mainly because the optimizations regarding load speed on pages) but I would ask the question anyway.
So my queries are working properly when I am fetching data only, however, I ran into a problem while having to fetch a file path from the database in order to download it on the client side. Since I don't need the whole model of the file I have 3 field dto on the client side that I fill up with the information regarding the file (etc location, size, filename) the problem is that when I send the async request toward the WCF service on Azure that's hold my entity framework link to the database the code continues further without waiting for the data to be retrieved from the database and throws null reference exception while attempting to fill the dto object that is to be sent further to the client in order to retrieve the file that's marked for downloading
This is my data access on the client side
internal async Task<AnimalDocument> GetAnimalDocument(int id)
{
var data = await _context.GetAnimalDocumentAsync(id);
var result = JsonConvert.DeserializeObject<AnimalDocument>(data);
return result;
}
And this is where I get the null exception
public SeriliazedFile GetFile(int id, int type)
{
var result = new SeriliazedFile();
if (type == 1)
{
var data = _context.GetHumanFile(id);
result.FileName = data.Result.DocumentName;
result.FilePath = data.Result.DocumentLocation;
result.FileSize = data.Result.FileSize.Value;
}
else if (type == 2)
{
var data = _context.GetAnimalDocument(id);
result.FileName = data.Result.DocumentName;
result.FilePath = data.Result.DocumentLocation;
result.FileSize = data.Result.FileSize.Value;
}
return result;
}
Is there a way to force the async request to wait for the result before returning Task that I retrieve from the WCF? I've tried telling _context.GetAnimalDocument(id).Wait(); however, nothing happens it still proceeds further without any result.I've noticed that the trigger to retrieve the data is fired after the ajax request that is sent toward the page returns 200 causing something like a deadlock but I might be wrong. If anyone could give me a work around it would be nice, I am pretty sure that I would figure it out on my own eventually but time is rare anyway, I hope you have a good day.
I am sorry for posting this, it was not a issue with the WCF or the code in any way, async works perfectly fine with asp.net core 2.0 the issue was with me. I am still adapting to the concept of have [FromBody] in front of the types in the functions, it appears to be that I missed one and I was getting id 0 by default (not that I can figure out why I would get 0 instead of null on integer field when there is no data but that doesn't matter anyway.) in my id field and the data layer was returning null value that's why I was getting null reference exception later.

ASP.NET to HTML5 localStorage

In ASP.NET (web forms), I am retrieving a set of key/value pairs from an SQL database to be used in a DropDownList. This list is quite large (can be over 2000 entries) and used multiple times over many of the pages on the website and I've been looking into ways to cache this set of data on the local client to reduce bandwidth. The list doesn't change often so having a cached copy a week or more should be fine.
I wanted to know if it was at all possible and/or practical to have this list stored using HTML5 local storage and have a DropDownList fill from the client storage. If no data if found locally, then going on to query the database for the list.
If you have over 2000 entries in a select box it dosnt sound all that usable anyway.
Have a look at something like Select2. Particularly the "Loading Remote Data" example.
http://ivaynberg.github.io/select2/
I have been involved in writing a couple of apps where data is pushed back and forth regularly and we built an API object in Javascript to handle data being pulled from the server on request.
The API module requested data and took an action depending on its success status. You could build a simple API module to use if you feel that you may need to expand the type of data returning later, or just build a single AJAX call to pull the data for the drop down list.
An example of the API interface would be as such:
/**
* Parameter 1, string - Command Name for the server to interpret
* Parameter 2, object - Data that should be passed to the server (if necessary)
* Parameter 3, string - the HTTP method to use: 'GET', 'POST', 'PUT' etc.
* Parameter 4, function - the callback to fire once the response is received.
**/
api('CommandName', { key: 'value' }, 'METHOD', function(response) {
if(response.success) {
//Store data in localStorage here
}
});
As you stated above, you are using the data multiple times throughout the pages on your website. Therefore in the JavaScript you would write a check on load which determines if the data has been stored within the localStorage, and if not makes a call to the API to populate it. This would ensure that the client always has that data available. This can be done like so:
//On Load
if(!localStorage.dropdown) {
api('CommandName', { key: 'value' }, 'METHOD', function(response) {
if(response.success) {
localStorage.dropdown = response.data;
}
});
}

C# LDAP performance

Where I work, we have two modes of authentication:
CAS (http://www.jasig.org/cas)
LDAP
CAS is the primary method, but it is often unreliable at peak traffic times and so we have been using LDAP as a fallback mode for when we notice that CAS is down. Previously, we were using PHP for doing our LDAP fallback and got reasonable performance. There wasn't a noticeable delay during login other than the expected network lag times. A login took probably ~250-500ms to complete using LDAP.
Now, we are making a new system and have chosen ASP.NET MVC4 as the platform rather than PHP and I am tasked with trying to get this fallback working again. I have been pulling my hair out for about 6 hours now trying different things over and over again, getting the same result (perhaps I am insane). I have finally managed to connect to LDAP, authenticate the user, and get their attributes from LDAP. However, the query consistently takes 4.5 seconds to complete no matter what method I try.
This is very surprising to me seeing as the PHP version was able to do nearly the same thing in 1/8th the time and it would seem that the .NET framework has excellent support for LDAP/ActiveDirectory. Am I doing something incredibly horribly wrong?
Here are the guts of my function as it stands now (this one is the latest iteration that manages to do everything in one 4.5 second query):
public Models.CASAttributes Authenticate(string username, string pwd)
{
string uid = string.Format("uid={0},ou=People,o=byu.edu", username);
LdapDirectoryIdentifier identifier = new LdapDirectoryIdentifier("ldap.byu.edu", 636, false, false);
try
{
using (LdapConnection connection = new LdapConnection(identifier))
{
connection.Credential = new NetworkCredential(uid, pwd);
connection.AuthType = AuthType.Basic;
connection.SessionOptions.SecureSocketLayer = true;
connection.SessionOptions.ProtocolVersion = 3;
string filter = "(uid=" + username + ")";
SearchRequest request = new SearchRequest("ou=People,o=byu.edu", filter, SearchScope.Subtree);
Stopwatch sw = Stopwatch.StartNew();
SearchResponse response = connection.SendRequest(request) as SearchResponse;
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
foreach (SearchResultEntry entry in response.Entries)
{
Debug.WriteLine(entry.DistinguishedName);
foreach (System.Collections.DictionaryEntry attribute in entry.Attributes)
{
Debug.WriteLine(attribute.Key + " " + attribute.Value.GetType().ToString());
}
Debug.WriteLine("");
}
}
}
catch
{
Debugger.Break();
}
Debugger.Break();
return null; //debug
}
The PHP version of this follows this sequence:
Bind anonymously and look up the user information using a basedn and cn
Bind again using the username and password of the user to see if they are authentic
It does two binds (connects?) in 1/8th the time it takes the .NET version to do one! Its this sort of thing that makes me thing I am missing something.
I have tried methods based on the following sites:
http://roadha.us/2013/04/ldap-authentication-with-c-sharp/ - Required 2 queries to do what I wanted and was too slow. I went through probably 6 different tries of doing it differently (varying the authentication & connection settings, etc).
http://web.byu.edu/docs/ldap-authentication-0 - One PHP version, but has a small snippet about .NET at the bottom. I needed to get the profile as well and they weren't exactly descriptive.
System.DirectoryServices is slow? - Current version
EDIT:
Using wireshark, I saw that the following requests are made:
bindRequest passing along my uid (delta 0.7ms)
bindResponse success (delta 2ms)
searchRequest "ou=People,o=byu.edu" wholdSubtree (delta 0.2ms)
searchResEntry "uid=my uid,ou=People,o=byu.edu" | searchResDone success 1 result (delta 10.8ms)
unbindRequest (delta 55.7ms)
Clearly, the overhead is coming from .NET and not from the requests. These don't add up to 4.5 seconds in any way, shape, or form.
ldap.byu.edu sure looks like a fully qualified DNS host name. You should change your LdapDirectoryIdentifier constructor to new LdapDirectoryIdentifier("ldap.byu.edu", 636, true, false).
I think you're definitely on the right track using System.DirectoryServices for this, so you may just need to tweak your search request a bit.
You're only looking to get one result back here, correct? Set your size accordingly :
request.SizeLimit = 1;
This is a tricky one, but make also sure you're suppressing referral binds as well. You'll want to set this before you call connection.SendRequest(request) :
//Setting the DomainScope will suppress referral binds from occurring during the search
SearchOptionsControl SuppressReferrals = new SearchOptionsControl(SearchOption.DomainScope);
request.Controls.Add(SuppressReferrals);

Categories

Resources