problem using winforms WebBrowser in asp.net - asp.net

i am using the WebBrowser control in asp.net page. here is the simple code:
Public Class _Default
Inherits System.Web.UI.Page
Private WithEvents browser As WebBrowser
Dim th As New Threading.Thread(AddressOf ThreadStart)
Sub ThreadStart()
browser = New WebBrowser
AddHandler browser.DocumentCompleted, AddressOf browser_DocumentCompleted
browser.Navigate("http://www.someurl.com/")
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
th.SetApartmentState(Threading.ApartmentState.STA)
th.Start()
th.Join()
End Sub
Private Sub browser_DocumentCompleted(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)
If browser.Document IsNot Nothing Then
Dim textbox As HtmlElement = browser.Document.GetElementById("txt1")
textbox.InnerText = "some text"
Dim button As HtmlElement = browser.Document.GetElementById("btn1")
button.InvokeMember("click")
End If
End Sub
End Class
the problem is that the webbrowser's DocumentCompleted event is not being handled. It looks like the page request finishes before anything else could happen.
what's the solution to this problem?

I really recommend reading this article(He won a price for it..)
Using the WebBrowser Control in ASP.NET
http://www.codeproject.com/KB/aspnet/WebBrowser.aspx
His solution is to create 3 threads for it to work..

I'm not sure but I have some concerns about the way you wrote your code.
You are creating and initializing your thread as soon as your class instance is created. This is before the form has been loaded.
I can't say for sure this couldn't work but I would definitely recommend creating the thread in your Load event handler, just before you use it.
I wrote some similar code in C# to generate a website thumbnail. Although that code does not use the DocumentCompleted event, I played with that event when I wrote it and it seemed to work okay. You can compare my code to yours.
Also, I should mention I have one hosting account where the code doesn't work. It seems to simply die when I call Thread.Join. However, it doesn't appear that's the issue you're running into.

Related

Scope of Page.Cache property in ASP.NET 4.0

I'm now work on ASP.NET project
and want to use Page.Cache property to cache the String data like bellow way.
but, it behaves like having a Session scope.
I understand Page.Cache property is retuning a current System.Caching.Cache object
and that must have an Application scope.
I could check below code works fine, but my project's code not -- it makes cache for per session.
And, that replaced Cache of Application (with Lock and UnLock) works fine too.
Public Class WebForm1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim key_str As String = "cache_key"
Dim cached_value = Cache.Get(key_str)
If cached_value Is Nothing Then
cached_value = "stored_value"
Cache.Insert(key_str, cached_value, Nothing, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5), CacheItemPriority.Normal, New CacheItemRemovedCallback(AddressOf RemovedCallback))
End If
Label1.Text = cached_value
End Sub
Public Sub RemovedCallback(ByVal key As String, ByVal value As Object, ByVal removedReason As CacheItemRemovedReason)
Debug.WriteLine("#Callback!")
End Sub
End Class
above code
works fine
my project code
works like session scope
and If replaced Cache with Application, that works fine
Are there any possible to occur such a behavior or not?
(or I just made a mistake on anywhere else in logics?)
Please point out If concerning some configure files.
I maybe made a mistake.
My project is a Azure project and so Page.Cache is to store a data for per azure instance? Right?

How to print in VB?

I have a web application build using classic ASP and VB. How do I print a document from within the back end VB code?
Protected Sub btnPrint_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPrint.Click
End Sub
What i am trying to do is get user to click on button a letter is generated and sent to printer?
You could use the window.print javascript function which will open the print dialogon the client browser allowing him to choose the printer and print the page:
Protected Sub btnPrint_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPrint.Click
ClientScript.RegisterStartupScript([GetType](), "print", "window.print();", true)
End Sub
As a side note, what you have is not a classic ASP application with VB, you have a classic ASP.NET WebForms application using VB.NET as a code behind.
UPDATE:
As requested in the comments section here's how you could write a generic handler which will dynamically generate the HTML you would like to print:
Imports System.Web
Imports System.Web.Services
Public Class Print
Implements System.Web.IHttpHandler
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Response.ContentType = "text/html"
context.Response.Write("<html><body onload=""window.print();""><table><tr><td>value1</td><td>value1</td></tr></table></body></html>")
End Sub
ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
Now simply navigate to /Print.ashx.
you could look into some reports frameworks like CrystalReports (used to come with VS but you have to download it from SAP nowadays.
Here is a nice tutorial for the report-engine that comes packed into Visual Studio (I have to admit I don't have much experience with this but it looks fine to me): Creating an ASP.NET Report

ASP.NET BasePage Class Page_Load not Fired on Postback

I have the following BasePage class...
Public Class BasePage
Inherits System.Web.UI.Page
Private litError As Literal
Protected SO As Session
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
SO = Session.Item("SO")
If SO Is Nothing Then
Session.Abandon()
Response.Redirect("~/timeout.htm")
End If
litError = Page.FindControl("litError")
If litError IsNot Nothing Then
litError.Visible = False
End If
End Sub
Protected Sub ShowMessage(ByVal Message As String)
Show(Message, "message")
End Sub
Protected Sub ShowError(ByVal Message As String)
Show(Message, "error message")
End Sub
Protected Sub ShowSuccess(ByVal Message As String)
Show(Message, "success message")
End Sub
Private Sub Show(ByVal Message As String, ByVal CssClass As String)
If litError IsNot Nothing Then
litError.Text = String.Format("<span class=""{0}"">{1}</span>", CssClass, HttpUtility.HtmlEncode(Message))
litError.Visible = True
End If
End Sub
End Class
Every page in this application inherits this class. The SO variable represents a custom session class, that is very simple and just holds a couple of basic settings to be used throughout the application. The problem is, my Page_Load in this base class does not fire if a natural postback occurs (in this case, it is a gridview postback by sorting/paging). Then later in my code when I reference SO, I get a null reference exception because it hasn't been pulled from session.
Why doesn't the base Page_Load fire?
Try moving your code into the Page_Init event.
Microsoft has some info on each event in the lifecycle http://msdn.microsoft.com/en-us/library/ms178472.aspx. This MSDN page tells you what types of things you should handle in each event.
You might want to think about implementing SO as a property, where the Get does (not sure if this is correct VB...)
Dim so As Session = Session.Item("SO")
If so Is Nothing Then
Session.Abandon()
Response.Redirect("~/timeout.htm")
End If
return so
It could be that something else is happening in the Init events that is causing it to fail. So rather than it not being called it just hasn't been called yet.
It could be that the autoevent wireup isn't wiring it up correctly, tend to override the OnInit event and attach the events manually myself, I have also read somewhere that this improves perfomance by not requiring the framework to do heaps of reflection on every post.
But back to your problem... try making the SO object private and create a property accessor for it that first checks that if the private is set, if not set it, before returning the private variable. If it isn't set and can't be found then it can abort the same way you are doing in the Load. This means that to load the variable you won't be dependent on the Page_Load from firing and thus the SO object should be available for you during the init routines, if you need it.

Preserve Data-structure on AJAX postback

Partial Class ClientCenter_UpdateSub
Inherits System.Web.UI.Page
Structure PInfo
Dim Name As String
Dim Surname As String
End Structure
Dim OldPInfo As New PInfo
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
'blah blah
OldPInfo.Name = Dt.Rows(0).Item("Name").ToString
OldPInfo.Surname = Dt.Rows(0).Item("Surname").ToString
end if
end sub
End Class
The first time the page loads my structrure is filled correctly.
After an AJAX postback all the structure fields are setting to nothing. (It seems that the Dim OldPInfo As New PInfo is called again), but i should better ask the SO Experts.
So anyway, what am i doing wrong here?
First off, You should never assign a variable outside of a property or a method.
Second, web applications are stateless (which means NOTHING is automatically saved from call to call - unless you store it somewhere like Viewstate, Session, etc.).
Remember to accept this answer if it helps solve your problem.

Something wrong with my GridView code

this code never fills the grid view I know that somthing is wrong here the code
Imports System.Data
Imports ZidduDataSetTableAdapters
Partial Class _Default
Inherits System.Web.UI.Page
Dim filesAdp As New FilesTableAdapter
Dim filestable As New ZidduDataSet.FilesDataTable
Protected Sub btnfill_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnfill.Click
Me.GridView1.DataSource = filesAdp.GetData
Me.GridView1.DataBind()
End Sub
End Class
and I already created the dataset with wizard called ZidduDataSet.xsd
and the adapter name is FilesTableAdapter
can any one help?
i am not a VB coder, but i think you should call Databind() function on Page Load event too.
hope this helps.
the only thing wrong with the code is that filestable is never used. If your gridview isn't showing up then you have a problem else where i think.
btnfill_Click isn't getting called. Check the .aspx markup to make sure the event handler is referenced.
filesAdp.GetData doesn't return any data.
GridView1 isn't visible on the page.

Resources