StackoverflowException while in prod on IIS - asp.net

I have a serious issue trying to put my Web Application into production.
My application is coded in VB.Net (With Visual Web Developer 2010), and the environment of production is a virtual machine with Microsoft Server 2008 R2, and IIS 7.5, the application is running with Asp.net 4.0. I tried also on my own computer (Windows 7), where I installed IIS, and the same bug occurs.
To limit the charge on SQL server, I put into session a list of rights, which is loaded each time the user wants to have access to any page.
The bug occurs exactly when this list contains more than 178 objects. At 178, the session is created and the page is correctly executed ; but when I add a 179th element or more (and I tried with different elements, so this can't come from the elements themselves), the page just don't execute correctly the code and IIS crash...
It seems that when there is more than 179 elements in this list, IIS just recycle the App, and so, the session is lost...
When I debug the application with Visual Web Developer, it is running well, without bug. But when I try to put it into production, that bug occurs. So, this seems to be linked with IIS.
Another problem is that when IIS recycle my App, it doesn't create any log file. So I have nothing more precise to give you.
I need help to find a solution to this problem. I try for a week, and I found nothing... this is driving me crazy... If someone has any idea or need more information, please tell me, so I can dig deeper...
Thanks to everyone.
EDIT :
I tried something else, I bypassed the sessions, and now, the rights are directly charged from SQL. The problem still occurs. So, it doesn't come from sessions, but SQL.
So, I wonder if there is any limit while doing requests on SQL.
But SQL doesn't seems to have any problem with request that return 3000 elements, and when it returns 179 elements with a lot of joins, it just crash... Well, I have no idea what to do or where search for a solution...
EDIT2 :
But, like I said, the problem doesn't occurs when I try execute the code from Visual Web developer. And, with it or in production environment, it's the same SQL server that execute de SQL requests... So, the problem can't come from SQL finally...
EDIT3 :
I finally found something. In the Windows logs, I have a StackOverflowException... What happy news ! (And we are on stackoverflow.com, is that linked? xD).
EDIT4 :
Here is the error from the windows log. Maybe it can help anyone.
Nom du journal :Application
Source : Windows Error Reporting
Date : 29/04/2014 11:53:11
ID de l’événement :1001
Catégorie de la tâche :Aucun
Niveau : Information
Mots clés : Classique
Utilisateur : N/A
Ordinateur : SRVWEB.DOMMH01.local
Description :
Récipient d’erreurs , type 0
Nom d’événement : CLR20r3
Réponse : Non disponible
ID de CAB : 0
Signature du problème :
P1 : w3wp.exe
P2 : 7.5.7601.17514
P3 : 4ce7afa2
P4 : System.Core
P5 : 4.0.30319.18408
P6 : 5231116c
P7 : 1197
P8 : 0
P9 : System.StackOverflowException
P10 :
Fichiers joints :
Ces fichiers sont peut-être disponibles ici :
C:\ProgramData\Microsoft\Windows\WER\ReportQueue\AppCrash_w3wp.exe_e41148f8d4e7fcf353a2d93bfe4367a48b981de2_0a6131b2
Symbole d’analyse :
Nouvelle recherche de la solution : 0
ID de rapport : 125b520d-cf84-11e3-912f-00155dc81602
Statut du rapport : 4
EDIT 5 :
I put here the piece of code where I take the rights with LINQ to SQL. I don't think this will be really helpful, but there it is...
A right contains a Username, the id of the rights, the id of a family (a family is a set of "objects"), and a place. So finnaly, I get a list of "Object/Place" associated with rights for a specified user... So I can limit the access for only some "object/place" for each user.
Another thing is the familyJoker, and the placeJoker. When a right is associated with a placeJoker, wee add to the rights of this user any object/place where the object is in the family. It's the same when the family is the familyJoker. Finally, if family and place are both joker, we add all the combinations possible(the combinations possible are in the objectPlace table)
This is the code :
Public Shared Function getListeDroitsUtilisateurSession(ByVal username As String) As List(Of DroitsUtilisateurSession)
Dim db As SINDIDB = New SINDIDB
Dim familleJoker As String = FamilleMetier.famille_Joker
Dim lieuJoker As String = Lieu.lieu_Joker
Dim requeteSansJoker = From d In db.DroitsUtilisateurs
Where d.Utilisateur = username
Join r In db.Roles
On d.ID_Role Equals r.ID_Role
Join oif In db.ObjetsInFamilleMetiers
On d.ID_Famille Equals oif.ID_Famille
Join f In db.FamilleMetiers
On oif.ID_Famille Equals f.ID_Famille
Where (Not f.Nom_Famille = familleJoker)
Join ol In db.ObjetLieux
On oif.ID_Objet Equals ol.ID_Objet
Where (d.ID_Lieu = ol.ID_Lieu)
Join l In db.Lieux
On ol.ID_Lieu Equals l.ID_Lieu
Where (Not l.Valeur_Lieu = lieuJoker)
Select New DroitsUtilisateurSession With {.Role = r, .ObjetLieu = ol}
Dim requeteFamilleJoker = From d In db.DroitsUtilisateurs
Where d.Utilisateur = username
Join r In db.Roles
On d.ID_Role Equals r.ID_Role
Join f In db.FamilleMetiers
On d.ID_Famille Equals f.ID_Famille
Where (f.Nom_Famille = familleJoker)
From oCross In db.Objets
Join ol In db.ObjetLieux
On oCross.ID_Objet Equals ol.ID_Objet
Where (d.ID_Lieu = ol.ID_Lieu)
Select New DroitsUtilisateurSession With {.Role = r, .ObjetLieu = ol}
Dim requeteLieuJoker = From d In db.DroitsUtilisateurs
Where d.Utilisateur = username
Join r In db.Roles
On d.ID_Role Equals r.ID_Role
Join l In db.Lieux
On d.ID_Lieu Equals l.ID_Lieu
Where (l.Valeur_Lieu = lieuJoker)
Join oif In db.ObjetsInFamilleMetiers
On d.ID_Famille Equals oif.ID_Famille
From lCross In db.Lieux
Join ol In db.ObjetLieux
On oif.ID_Objet Equals ol.ID_Objet
Where (lCross.ID_Lieu = ol.ID_Lieu)
Select New DroitsUtilisateurSession With {.Role = r, .ObjetLieu = ol}
Dim requeteFamilleEtLieuJoker = From d In db.DroitsUtilisateurs
Where d.Utilisateur = username
Join r In db.Roles
On d.ID_Role Equals r.ID_Role
Join f In db.FamilleMetiers
On d.ID_Famille Equals f.ID_Famille
Where (f.Nom_Famille = familleJoker)
Join l In db.Lieux
On d.ID_Lieu Equals l.ID_Lieu
Where (l.Valeur_Lieu = lieuJoker)
From olCross In db.ObjetLieux
Select New DroitsUtilisateurSession With {.Role = r, .ObjetLieu = olCross}
Dim requeteTotale = requeteSansJoker.Union(requeteFamilleJoker).Union(requeteLieuJoker).Union(requeteFamilleEtLieuJoker)
Dim resultat As List(Of DroitsUtilisateurSession) = requeteTotale.ToList
Dim listeDroitsUtilisateur As List(Of DroitsUtilisateurSession) = New List(Of DroitsUtilisateurSession)
If (resultat IsNot Nothing) Then
For Each item In resultat
listeDroitsUtilisateur.Add(New DroitsUtilisateurSession With {.Role = item.Role, .ObjetLieu = item.ObjetLieu})
Next
End If
Return listeDroitsUtilisateur
End Function
EDIT 6: I found something about the limit size of the pile of w3wp applications. This can be linked to my problem...
Here is the link :
http://support.microsoft.com/kb/932909
I'm digging.
EDIT 7: So, I made a little change to my code. Now, when it have to calculate the rights, it let another thread do it. This thread has a bigger stack size. So I thought it can change something, but the same problem occurs...
And I don't said it before, but there is NO recursive code in my App.
Here is the code I implemented :
Dim ThreadD As ThreadDroits = New ThreadDroits
ThreadD.Username = User.Identity.Name
Dim t = New Thread(AddressOf ThreadD.ExecuteDroits, 419430400)
t.Start()
t.Join()
Dim listeDroits As List(Of DroitsUtilisateurSession) = ThreadD.ListeDroits
And here is the new class :
Public Class ThreadDroits
Private m_Username As String
Public Property Username As String
Get
Return m_Username
End Get
Set(ByVal value As String)
m_Username = value
End Set
End Property
Private m_listeDroits As List(Of DroitsUtilisateurSession)
Public Property ListeDroits As List(Of DroitsUtilisateurSession)
Get
Return m_listeDroits
End Get
Set(ByVal value As List(Of DroitsUtilisateurSession))
m_listeDroits = value
End Set
End Property
Public Sub ExecuteDroits()
ListeDroits = DroitsUtilisateurSession.getListeDroitsUtilisateurSession(Username)
End Sub
End Class

Related

ASP.NET/VB date works on localhost but not remoteserver

I'm having alot of trouble trying to get the date from a DateTime picker to save to my database. It works fine when run from Localhost, but when running it on the public server it doesn't.
Originally i used the cDate function, plus also tried Convert.ToDateTime. But on the server it now gives me an error "String was not recognized as a valid DateTime."
I researched and found that its best to used the DateTime.TryParse function. After finding an example i changed it for my project and now im getting the error "Must declare the scalar variable "#articledate"."
When i debug the project, the value added into the "result1" DateTime is correct. But it still throws the error at ExecuteNonQuery?
If it makes a difference, the main server is hosted with GoDaddy, Localhost is my PC.
Any help or advice would be greatly appreciated.
cnSQL1 = New SqlConnection(MSSQL.cRemoteConnectionString)
cnSQL1.Open()
sSQL = "SELECT NewsID FROM News WHERE Season = #season AND Heading = #heading AND ArticleDate = #articledate AND Author = #author AND Club = #club AND State = #state AND AddedDate = #addeddate AND AddedBy = #addedby AND Release = #release"
Dim com1 As New SqlCommand(sSQL)
com1.Connection = cnSQL1
com1.Parameters.AddWithValue("#season", General.sSeason)
com1.Parameters.AddWithValue("#heading", General.UppercaseFirstLetter(txtHeading.Text))
Dim result1 As DateTime
com.Parameters.AddWithValue("#articledate", DateTime.TryParseExact(txtArticleDate.Text, "dd-MM-yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, result1))
'com1.Parameters.AddWithValue("#articledate", Convert.ToDateTime(txtArticleDate.Text))
com1.Parameters.AddWithValue("#author", txtAuthor.Text)
com1.Parameters.AddWithValue("#club", ddlClub.SelectedItem.Value)
com1.Parameters.AddWithValue("#state", dsState.Tables(0).Rows(0).Item(0))
com1.Parameters.AddWithValue("#addeddate", Date.Today)
com1.Parameters.AddWithValue("#addedby", Session("UserID"))
com1.Parameters.AddWithValue("#updatedate", Date.Today)
com1.Parameters.AddWithValue("#updateby", Session("UserID"))
com1.Parameters.AddWithValue("#release", s)
com1.ExecuteNonQuery()
The error "Must declare the scalar variable "#articledate" is caused by a typo. When you add the parameter you should use the SqlCommand variable named com1 not the variable com.
But after this you have a more critical error. All the TryParse methods return booleans. The converted date is written in the last parameter passed to TryParse.
In this way you are passing a boolean to AddWithValue and this method takes whatever you put in the value parameter. It has no way to know that you want a date, so it happily complies with your request.
You should do (Notice that the SqlCommand to use is com1 not com)
Dim result1 As DateTime
if DateTime.TryParseExact(txtArticleDate.Text, "dd-MM-yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, result1) Then
com1.Parameters.AddWithValue("#articledate", resul1)
Else
.....
In general it is better to avoid AddWithValue exactly because it takes whatever you pass to it. The preferred way is with
if DateTime.TryParseExact(txtArticleDate.Text, "dd-MM-yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, result1) Then
com1.Parameters.Add("#articledate", SqlDbType.Datetime).Value = result1
com1.Parameters.AddWithValue("#season", General.sSeason)
com1.Parameters.AddWithValue("#heading", General.UppercaseFirstLetter(txtHeading.Text))
com1.Parameters.AddWithValue("#author", txtAuthor.Text)
com1.Parameters.AddWithValue("#club", ddlClub.SelectedItem.Value)
com1.Parameters.AddWithValue("#state", dsState.Tables(0).Rows(0).Item(0))
com1.Parameters.AddWithValue("#addeddate", Date.Today)
com1.Parameters.AddWithValue("#addedby", Session("UserID"))
' This is not used by the query, commented out
' com1.Parameters.AddWithValue("#updatedate", Date.Today)
' This is not used by the query, commented out
' com1.Parameters.AddWithValue("#updateby", Session("UserID"))
com1.Parameters.AddWithValue("#release", s)
com1.ExecuteNonQuery()
Else
MessageBox.Show("Date is not valid")
End If
I have also removed two parameters that are not used in the query above (though they should not cause the error message above)

Database Editing in Session OnEnd Classic ASP

I was Creating a website in Classic ASP Project, having a Logout feature.
I want to access the login database and make changes, when the session ends. The coding is something like:
In global.asa :
Sub Session_OnEnd()
Set studcon = Server.CreateObject("ADODB.Connection")
studcon.Open "Provider = Microsoft.JET.OLEDB.4.0;Data Source = E:\mailfan.mdb"
Set studrec = Server.CreateObject("ADODB.Recordset")
studrec.Open "login", studcon, 1, 3
studrec.movefirst
found = 0
Do While studrec.EOF or found = 1
If studrec("ID") = Session("uid") Then
studrec("log") = 0
studrec.Update
End If
studrec.movenext
Loop
studrec.close
studcon.close
Set studrec = Nothing
Set studcon = Nothing
End Sub
But Even After Session.Abandon the value of log field Remains the same (It is 1 when session's active).
Small Update: I tried to google it, and did recieve a very similar link having the same question: http://www.justskins.com/forums/problem-with-global-asa-77015.html
But the code is the same as suggested by Aaron Bertrand in the above link. Is it due to IIS 8.0? Because I would be Running it on Win XP sp3 IIS 6. And I Do require it to work there.
I can't see an SQL query anywhere in your code. If you're intent on using a recordset for your update then in place of
studrec.Open "login", studcon, 1, 3
you should have something like
studrec.Open "select * from login", studcon, 1, 3
This assumes that your database table is called "Login"
Using a recordset is actually an over complex means of doing all this though, An Update query should suffice. You could remove all your code from
Set studrec = Server.CreateObject("ADODB.Recordset")
to
studrec.close
and replace it with
studcon.Execute("UPDATE Login set log = 0 where id = " & Session("uid"))

Sorting And Merging Data Returned From Web Service

I'm working on a web service using asp.net.
I'm creating a timetable display board like you see in airports, bus stations or train stations.
I am in charge of creating the services for 1 station, and there are other people in charge of the other stations.
I have created my web services and now im trying to consume the others.
I can consume them but everyone else has got their web services returning different values, for example, I'm returning route id, journey id, start location, end location, stops, days running, times. but other peoples web services may return data like route id, start, end, stops, times, platform, journey status. in one table, and the other data that matches up with mine in another web service.
So how do i filter out the data that i do not need, like platform and journey status in the example.
Also, how would I merge everyone's data from web services into 1 grid view so i can display all the trains that pass through my station.
I'm quite new to web services, but I am trying and I have got quite a bit done by myself, im just stuck on this bit.
I hope this isn't a stupid question
Dim allStations As New List(Of ScheduleEntry)
Dim ws1 As New Hull.ArrivaServices()
For Each u1 As Hull.Result In ws1.ShowRouteByStation("hrw")
Dim s As New ScheduleEntry
s.StartTime = u1.Departure
s.StopTime = u1.Arrival
allStations.Add(s)
Next
Dim ws2 As New Heathrow.Heathrow_Airport()
For Each u2 As Heathrow.Result In ws2.GetHeathrowTrains
Dim s As New ScheduleEntry
s.StartTime = u2.BeginTime
s.StopTime = u2.EndTime
allStations.Add(s)
Next
GridView1.DataSource = allStations
GridView1.DataBind()
I converted the datasets to datatables to make it compatable with each other.
DatatableA.Merge(DatatableB)
So now DatatableA also Contains all the DatatableB collumns and rows.
If the column names are the same and the data type is the same, the 2 columns become 1.
So I made sure the data types were the same, if they werent I converted them, then renamed the column name in DatatableB to the column name in DatatableA.
DatatableA.Columns(columnnumber).ColumnName = "NewName"
Remember when counting the columnnumber, its left to right and the first column is 0
If I had to convert the datatype, I made a new column in DatatableB (Same name as corrisponding collumn in DatatableA)
DatatableB.Columns.Add("NewColumnName", GetType(DataType))
Then I created a loop to go through the datatable rows of the collumn with the data I want to convert
Dim i as integer
Dim z as integer
i = 0
z = DatatableB.Rows.Count`
and putting the new converted data in the NewColumn by using
Do until i = z
DatatableB.Rows(i)("ColumnName") = "ConvertedData)
Next
Hope this helps someone
Your problem isn't what we normally call sorting and merging, not really. The largest problem is that you have a number of services which all return similar data formats, but not identical. So your first step will be to make them identical: within your program.
First, decide what you want to display in your grid. Let's say you only want to display start and stop time. So make a class that can hold a start and stop time:
Public Class ScheduleEntry
Public Property Start As DateTime
Public Property Stop As DateTime
End Class
You will use a List(Of ScheduleEntry) to populate your grid.
Now, depending on which service you call, just take the Start and Stop and add them to your list. Assume the case of two services with different return values:
Dim allStations As New List(Of ScheduleEntry)
Dim ws1 As New SERVICE1.CLASS()
For Each u1 As SERVICE1.Result In ws1.METHOD
Dim s As New ScheduleEntry
s.StartTime = u1.Departure
s.StopTime = u1.Arrival
allStations.Add(s)
Next
Dim ws2 As New SERVICE2.CLASS()
For Each u2 As SERVICE2.Result In ws2.METHOD2
Dim s As New ScheduleEntry
s.StartTime = u2.BeginTime
s.StopTime = u2.EndTime
allStations.Add(s)
Next
GridView1.DataSource = allStations
GridView1.DataBind()

Where do DAC objects live (in Classic ASP)?

I have taken over a departing programmer's Classic ASP object, and I'm trying to debug some DAC code. The trouble is I don't really understand what DAC is or how it works -- and I can't find were the DAC code "lives".
Here's the individual line of code:
set runObj = server.CreateObject("DAC.clsDb_container")
We use SQL Server, and I looked in Enterprise Manager under Stored Procedures and User-Defined functions, but I don't see anything named clsDB_container.
Any suggestions where I can find the code for this DAC object?
The full code in context:
FUNCTION getNewGUID
Dim runCON, runObj, runCMD
DebugWrite( "<BEGIN> iRoutines.asp|getNewGUID (a) GUID=" & GUID & " dealernum=" & dealernum )
set runObj = server.CreateObject("DAC.clsDb_container")
if not runObj.run_query("EXEC sproc_createGUID") then
traperror(runObj.DB_ErrStr)
else
GUID = replace(runObj.get_by_ordinal(0),"-","")
dealernum_len = trim(cstr(len(dealernum)))
set runObj = nothing
end if
getNewGUID = dealernum_len & dealernum & GUID
DebugWrite( "<END> iRoutines.asp|getNewGUID (b) getNewGUID=" & getNewGUID & " dealernum=" & dealernum )
END FUNCTION
This looks like a custom COM object that was written as a data access layer for the site.
The name of the object would be DAC.clsDb_container and lives in a DLL somewhere on the web server.
It is not standard - you will need to look for (I am guessing here) the VB6 or Delphi code that created it if you want to be enlightened further.
if all you need is a GUID then you could do this
<%
Function createGuid()
Set TypeLib = Server.CreateObject("Scriptlet.TypeLib")
dim tg : tg = TypeLib.Guid
createGuid = left(tg, len(tg)-2)
Set TypeLib = Nothing
End Function
%>

how to fix EntityReference error

I'm attempt to commit mostly all new objects to the database, apart from the user. I'm new to entity framework and im not sure how to combat this error.
Error on line _orderDetail.CalenderItems.Add(_newCalendarItem):
The object could not be added or attached because its EntityReference has an EntityKey property value that does not match the EntityKey for this object.
Code:
_db.Orders.AddObject(_order)
For Each n In _namelist
_db.Names.AddObject(n)
Next
For Each n In _namelist
For i As Integer = 1 To _copies
Dim _orderDetail As New OrderDetail
_db.OrderDetails.AddObject(_orderDetail)
_orderDetail.Name = n
_orderDetail.Order = _order
For Each c In _calendarItems
Dim _newCalendarItem As New CalenderItem
_newCalendarItem.Image = c.Image
_newCalendarItem.YearMonth = c.YearMonth
_orderDetail.CalenderItems.Add(_newCalendarItem)
Next
Next
Next
_db.SaveChanges()
I believe I need to add add an entity reference but I'm not sure how. Can anyone point me in the right direction
As dnndeveloper says, your answer is ObjectContext.CreateObject<T>.
So you're gonna want -
Dim ci = _db.CreateObject(Of CalenderItem)()
ci.OrderDetail = _orderDetail
ci.Image = c.image
ci.YearMonth = c.YearMonth
_orderDetail.CalenderItems.Add(ci)
or something along those lines. I've run into this issue a couple of times and this has worked so far.
HTH
Instead of creating a "new calendaritem" you should use _db.OrderDetails.CalendarItem.New() etc... either that or set _newCalendarItem.EntityKey to null.

Resources