ASP.NET sqldatasource.select(arg) gives stackoverflow.exception error - asp.net

I have a code to read the total number of rows in a SQLDatasource:
Protected Sub DSArticles_Selected(sender As Object, e As SqlDataSourceStatusEventArgs) Handles DSArticles.Selected
Dim args As DataSourceSelectArguments = New DataSourceSelectArguments
Dim dv As DataView = DSArticles.Select(args)
dv.RowFilter = DSArticles.FilterExpression
LblCikkekSzama.Text = dv.Count & " cikk"
End Sub
The browser says the page cannot be viewed. When in debugging mode I get the error:
An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll.
Any ideas?
Thanks
Sudi

I have a feeling you're causing an infinite loop because in the selected event you're doing Select() which triggers the selected event again, which calls Select again, etc... So this is probably not a good place to do this. Maybe move it to page_load or somewhere else that wouldn't trigger the selected event continuously. Somewhere that makes sense for what you're trying to accomplish.

Related

VB.Net exception: Object reference not set to an instance of an object

I'm currently working on coding a web page for a school project. This site is supposed to be a simple online store where people can order prints of artwork. The specific page I'm working on has a Drop Down List (ddlArt) that is bound to my database and displays a list of the different art pieces available. When the user selects one of the items, all the information on that item is pulled from the database and displayed on the page in a variety of labels and such. The only thing is that I'm getting a null reference exception error saying "Object reference not set to an instance of an object" when I go to try to run the page. I got the same error on a homework assignment earlier in the year and managed to get it fixed, but I can't remember what I did and I can't get help from school until next week, so I thought I'd try my luck on here. Here's my code:
Private selectedArt As Art
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
ddlArt.DataBind()
End If
selectedArt = Me.GetSelectedArt
lblArtID.Text = selectedArt.ArtID()
lblArtName.Text = selectedArt.ArtName()
lblCaption.Text = selectedArt.Caption()
lblDescription.Text = selectedArt.Description()
imgArt.ImageUrl = "~/images/" & selectedArt.FileName()
End Sub
Private Function GetSelectedArt() As Art
Dim artTable As DataView = CType(SqlDataSource1.Select(DataSourceSelectArguments.Empty), DataView)
artTable.RowFilter = "ArtID = '" & ddlArt.SelectedValue & "'"
Dim artRow As DataRowView = artTable(0)
Me.imgArt.ImageUrl = "~/images/" & artRow("FileName")
Dim art As New Art
art.ArtID = artRow("ArtID").ToString
art.ArtName = artRow("ArtName").ToString
art.Caption = artRow("Caption").ToString
art.Description = artRow("LongDescription").ToString
art.FileName = artRow("FileName").ToString
Return art
End Function
And here's the code for the Art class, in case anybody is interested:
Public Class Art
Public Property ArtID As Integer
Public Property ArtName As String
Public Property ArtType As String
Public Property Caption As String
Public Property FileName As String
Public Property Description As String
End Class
When I get the error, it highlights the artTable.RowFilter = "ArtID = '" & ddlArt.SelectedValue & "'" line in the GetSelectedArt function. I've tried comparing it to my corrected homework assignment that I mentioned, but I can't seem to find the problem. My VB is a little fuzzy because it's been awhile since I actually took the class. Any suggestions? Thanks a bunch!
If I understand your comment above correctly, on the initial page load there is nothing in the ddlArt, because the user must first choose an art type.
If that is correct, then your answer to my question is your answer.
For whatever reason (and without seeing at least the Select statement), artTbl is not getting instantiated, which is why you're seeing the Object reference not set to an instance of an object error.
One way to fix this (without knowledge of your SqlDataSource it's hard to give a precise answer) is to modify your Page Load method so that GetSelectedArt is only called when the user has selected an item from the drop down list. Right now GetSelectedArt is called every time the page loads.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
ddlArt.DataBind()
Else
selectedArt = Me.GetSelectedArt
lblArtID.Text = selectedArt.ArtID()
lblArtName.Text = selectedArt.ArtName()
lblCaption.Text = selectedArt.Caption()
lblDescription.Text = selectedArt.Description()
imgArt.ImageUrl = "~/images/" & selectedArt.FileName()
End If
End Sub
However, the above modification will only prevent GetSelectedArt from being called on the initial page load. If your SqlDataSource.Select command is still returning nothing, then you're still going to have this problem.
A better solution would be to call the GetSelectedArt on the ddlArt.SelectedIndexChanged event handler. This way you'll know that you have (or should have) a valid SelectedValue from ddlArt.
Also, if you don't populate the drop down until the user selects an art type from the radio button list, why are you binding the drop down list on the initial page load (and what are you binding it to)? Or is the drop down list and detail information on a different page from the radio button list?
May be .. with ArtID as integer
artTable.RowFilter = "ArtID = " & format(ddlArt.SelectedValue)

ASP.NET Page_Load runs twice due to Bitmap.Save

I have created an VB.NET page to record views for ads and will call page from img src.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim insert_number As Integer = 0
Dim ad_id As Integer = 0
If Request.QueryString("adid") Is Nothing Then
ad_id = 0
Else
If Not Integer.TryParse(Request.QueryString("adid"), ad_id) Then
ad_id = 0
End If
End If
Dim connectStr As String = System.Configuration.ConfigurationManager.AppSettings("connectStr").ToString()
Dim myconnection As SqlConnection = New SqlConnection(connectStr)
Dim mySqlCommand As SqlCommand
myconnection.Open()
Try
mySqlCommand = New SqlCommand("sp_record", myconnection)
mySqlCommand.CommandType = CommandType.StoredProcedure
mySqlCommand.Parameters.AddWithValue("#record_id", ad_id)
insert_number = mySqlCommand.ExecuteNonQuery()
Catch ex As Exception
End Try
myconnection.Close()
Dim oBitmap As Bitmap = New Bitmap(1, 1)
Dim oGraphic As Graphics = Graphics.FromImage(oBitmap)
oGraphic.DrawLine(New Pen(Color.Red), 0, 0, 1, 1)
'Response.Clear()
Response.ContentType = "image/gif"
oBitmap.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif)
'oBitmap.Dispose()
'oGraphic.Dispose()
End Sub
Unless I comment oBitmap.Save line, the code runs twice and it makes two inserts (store prcoedure runs twice) to Database.
I have tried AutoEventWireup = "true" and "false" at #PAGE. "true" runs code twice, "false" did not do anything (no error) and did not give any output as well.
I have also tried following version of creating 1pixel image output but it did run twice as well (it requires aspcompat=true in #PAGE part):
'Response.ContentType = "image/gif"
'Dim objStream As Object
'objStream = Server.CreateObject("ADODB.Stream")
'objStream.open()
'objStream.type = 1
'objStream.loadfromfile("c:\1pixel.gif")
'Response.BinaryWrite(objStream.read)
Any ideas are welcome.
You may want to do an onload function for the image to see why it's being called a second time. I'm guessing that it's getting loaded somewhere in the preload and then being called (.Save) during the page load as well and that's why you're seeing the double entry.
If you are trying to get unique page loads, you may want to try putting the oBitmap.Save line within a check for postback like this within the page load:
If Page.IsPostback = False Then
'Bitmap Code Here
End If
And see if that fixes it for you.
If you're loading data from a database, you'll want to make sure that it also is within that PostBack check (because a. you're loading the data twice and b. it can cause these double postbacks in some circumstances).
Edit: Wanted to edit code section to include all bitmap code, not just the save.
Not sure about the specifics, but that is a lot of code within in Page_Load function.
Generally, the way I would solve this type of problem is to have some sort of page arguments that you can check for in order to do the correct things. Either add some get/post parameters to the call that you can check for or check things like the Page.IsPostBack.
I realize this is an old post but I had an similar issue where the page was firing twice on the postback. I found several posts sugesting what is being dicusses here. However, what corrected my issue was setting the page directive property AutoEventWireup=false at the page level.
Here is a good article How to use the AutoEventWireup attribute in an ASP.NET Web Form by using Visual C# .NET that helped me solve this.
Hope this helps!
Risho

How do I Prevent FormView from clearing user's entered Values after Insert Method has fired?

I have been struggling with getting FormViews to work the way Microsoft expects me to for about a day and have figure a bunch of great stuff out.
I can catch e.Exception and e.ReturnValue in the ObjectDataSource.Inserting Event Handler and I can even cheat and check other properties of the Object in the ObjectDataSource.ObjectDisposing by checking the e.ObjectInstance ... and I even learned that FormView's Inserting Handler Runs AFTER the ObjectDisposing Handler so If there is a problem found I still have time to react to it and st the e.KeepInInsertMode to true on the FormView.
My problem is, it seems that the values entered by the user into the Insert form are cleared regardless.
So, How do I Prevent a FormView from clearing after it's Insert Method has fired?
(Using ASP.NET + VB)
I don't think posting my code here will really do much good and i would have to modify it to trim out confidential business logic stuff... so I'll skip it for now.
edit:
I have found a temporary and admittedly terribly cludgy solution (in case no one ever finds a REAL solution to the problem).
I have a page variable defined as:
Dim eInsertArgs As FormViewInsertedEventArgs
And then I do the following in my ItemInserted handler
If boolInsertErrorOccurred = False Then
e.KeepInInsertMode = True
eInsertArgs = e
Else
eInsertArgs = Nothing
End If
Then on each of the controls I have something like this in that controls databinding event:
If IsNothing(eInsertArgs) = False Then
Dim _sender As TextBox = sender
_sender.Text = eInsertArgs.Values("_FieldName")
End If
The effect of this is that I am setting the values BACK to the submitted values AFTER ASP.NET binds the FormView to the default (blank) Template.
Please help me find a less terrible solution. :)
You need to create your own server control which inherits from the FormView control.
Public Class MyFormView
Inherits FormView
Protected Overrides Sub OnDataSourceViewChanged(ByVal sender As Object,
ByVal e As EventArgs)
If (MyBase.CurrentMode = FormViewMode.Insert) Then
MyBase.RequiresDataBinding = False
Else
MyBase.OnDataSourceViewChanged(sender, e)
End If
End Sub
End Class
Please take a look at this page: http://www.dotnetmonster.com/Uwe/Forum.aspx/asp-net/76885/FormView-Insert

ASP.NET: Very simple event handling not working

I have an object Order with a simple event,
Public Event ErrorOccurred(ByVal msg As String)
that I raise in the constructor like so when an order cannot be found (along w/setting a boolean error flag:
RaiseEvent ErrorOccurred("This order does not exist in the database.")
[Error] = True
I have a webform subscribed to the order's ErrorOccurred event:
Public WithEvents o As New Order
and I have an error handler method on the form:
Private Sub OnErrorOccurred(ByVal msg As String) Handles o.ErrorOccurred
litMsg.Text = "<p class=""error-confirm"">" & msg & "</p>"
End Sub
When a textbox is changed, it autoposts back to the page and employs the following logic:
Private Sub txtOrderID_TextChanged(ByVal sender As Object,_
ByVal e As System.EventArgs) Handles txtOrderID.TextChanged
If IsNumeric(txtOrderID.Text) Then
If o.OrderID = 0 Then o = New Order(txtOrderID.Text)
If Not o.Error Then
'do stuff'
Else
'error, run error handling'
End If
....
When there is an error (when the Else logic is run), everything performs as expected except the event does not fire. However, since the Error flag is set to true, it means the event MUST have fired, since that line executes AFTER the RaiseEvent line.
I've tried everything I can think of, but I cannot figure out what could be wrong. I have events strewn everywhere in my project and they all work well using virtually the same structure. What could I be doing wrong here?
I would say that since you are raising the event in the constructor, before you even have a reference to the object in your parent class, that you are unable to handle the event. In this case, especially with errors in the constructor, you would probably be much better off throwing an exception than to raise an event. I would be better to throw an exception, because some other code calling your class might not even handle the event, and you would most likely want to know that an error occured. Throwing exceptions is the standard way of letting the calling code know that an error occured. Events are more for optional things that the calling class may want to handle, but that it may also want to ignore.

ASP.NET Dynamic User Controls

I'm sure this question has been asked a million times, however I haven't been able to find an answer that solves my problem.
I am programmatically adding some custom user controls to a PlaceHolder which I have on a simple aspx page. All of the user controls Postback's work correctly except for one which has a Gridview on it.
For some reason any postback that gets fired from within this control, does not call the specified event on the first click, however all future clicks it will work fine. I have no idea why this is the case, but many solutions I have found, suggest adding an ID to the ascx User Control, however this doesn't work in my case.
I've taken a look at the source file for the page that gets generated before and after the first click, javascript used for calling the postback changes, i.e
Before first click: onclick="javascript:__doPostBack('tmpControlID$sgvPrimaryEmploymentHistory','Select$0')"
After first click: onclick="javascript:__doPostBack('OFFHome1$tmpControlID$sgvPrimaryEmploymentHistory','Select$0')"
OFFHome1 is the parent user control which exists on the aspx page. All other controls are added to a placeholder in this control, i.e.
<%# Control Language="vb" AutoEventWireup="false" CodeBehind="OFFHome.ascx.vb" Inherits="UmbracoUserControls.OFFHome" %>
<asp:PlaceHolder ID="phOFFSection" runat="server"></asp:PlaceHolder>
Nothing to complicated. Then in the code behind the controls are loaded into the placeholder using the following:
Private Sub LoadNextOFFStep()
Dim ControlName As String = "TestControl.ascx"
phOFFSection.Controls.Clear()
If ControlName IsNot Nothing AndAlso ControlName <> String.Empty Then
Dim NewControl As Object = LoadControl(ControlName)
With NewControl
.ID = USERCONTROLNAME
Dim StepCompleted As Boolean = .FillControl()
If StepCompleted Then
Exit Sub
End If
Dim AllowSkip As Boolean = .AllowSkip()
btnSkip.Visible = AllowSkip
End With
phOFFSection.Controls.Add(NewControl)
End If
End Sub
Again, nothing overly complicated. The USERCONTROLNAME is just a const with the value "tmpControlID" in it.
The control that is giving me trouble is a little complicated, I was originally using a custom GridView control that we have created, but have removed it and replaced it with the standard asp one to see if the problem still occurs, and it does.
Any button, on control which fires off a postback will fail the first time, and all future click will work correctly. On the first click the Page_Load event will get called, but that is it.
What am I doing wrong??
After far too much time spent on this, I have finally worked it out.
It was to do with the order of events, however just not where I had thought. The FillControl function was getting called before User Control had been added to the PlaceHolder. I changed this so that it gets called after the User Control was added to the PlaceHolder and now it works first time.
Basically the code looks like this now:
Private Sub LoadNextOFFStep()
Dim ControlName As String = "TestControl.ascx"
phOFFSection.Controls.Clear()
If ControlName IsNot Nothing AndAlso ControlName <> String.Empty Then
Dim NewControl As Object = LoadControl(ControlName)
With NewControl
.ID = USERCONTROLNAME
Dim AllowSkip As Boolean = .AllowSkip()
btnSkip.Visible = AllowSkip
End With
phOFFSection.Controls.Add(NewControl)
Dim StepCompleted As Boolean = CType(phOFFSection.Controls(0), Object).FillControl()
If StepCompleted Then
LoadNextOFFStep()
Exit Sub
End If
End If
End Sub
Thanks for everyone's help.
Well... the answer to the first question is simple: It fails the first time because the ID of the control (or rather, in the postback script) is different on subsequent page loads. It works on subsequent clicks because the control ID stays the same.
Now as to WHY that is... much tougher! But probably something to do with the order of operations here.
Try explicitly setting the NamingContainer value for NewControl:
With NewControl
.NamingContainer = OffHomeOne; // whatever
.ID = USERCONTROLNAME

Resources