Catching errors or exceptions - asp.net

I built a mashup of google maps and weather.com and everytime one of these server is not responding my application hangs up too.What do you think I can do to prevent or minimize hanging up of my web apps?Hanging up like you can't navigate away from that page....
I got this code on my app code to access the weather service;
Public Class WeatherIn
Private _path As String
Private _cachedFile As String
Public Sub New(ByVal path As String)
_path = path
_cachedFile = String.Format("{0}\WeatherInCache.xml", _path)
End Sub
Public Function GetWeather(ByVal arg As String) As String
Return _getWebWeather(arg)
End Function
Private Function _getCachedWeather() As String
Dim str As String = String.Empty
Using reader As New StreamReader(_cachedFile)
str = reader.ReadToEnd()
End Using
Return str
End Function
Private Function _getWebWeather(ByVal arg As String) As String
Dim baseUrl As String = "http://xoap.weather.com/weather/local/{0}?cc=*&dayf=5&link=xoap&prod=xoap&par={1}&key={2}"
Dim jane As String = arg
Dim james As String = "api key"
Dim john As String = "another api key"
Dim url As String = String.Format(baseUrl, jane, james, john)
Using client As New WebClient()
Try
Dim xml As New XmlTextReader(client.OpenRead(url))
Dim xslt As New XslCompiledTransform()
xslt.Load(_path + "/Pathto.xslt")
Using writer As New StreamWriter(_cachedFile)
xslt.Transform(xml, Nothing, writer)
End Using
Return _getCachedWeather()
Catch exception As WebException
Dim xmlStr As String = "<errorDoc>"
xmlStr += "<alert>An Error Occurred!</alert>"
xmlStr += [String].Format("<message>{0}</message>", exception.Message)
xmlStr += "</errorDoc>"
Dim doc As New XmlDocument()
doc.LoadXml(xmlStr)
Dim reader As New XmlNodeReader(doc)
Dim xslt As New XslCompiledTransform()
xslt.Load(_path + "/Pathto.xslt")
Dim resultDocument As New XmlDocument()
Using writer As XmlWriter = resultDocument.CreateNavigator().AppendChild()
xslt.Transform(reader, DirectCast(Nothing, XsltArgumentList), writer)
End Using
Return resultDocument.OuterXml
End Try
End Using
End Function
Then I used the class above on my page where I display the weather like this:
'specific zip code or could be retrieved from querystring for dynamic retrieval
var jay="94576"
Dim weather As New WeatherIn(Server.MapPath(String.Empty))
Dim weatherData As String = weather.GetWeather(jay)
Response.ContentType = "text/xml"
Response.CacheControl = "no-cache"
Response.Write(weatherData)
which I retrieve the data and write on the page through javascript.Most of the time its the weather.com that goes down.I got no problem with google map its reliable....anybody got a solution why my page hangs up too if the remote server is not responding?The mashup is running smoothly if the remote server is responding...

When depending on external web services it is best to load asynchronously so that if one of them is slow you can show some kind of loading spinner to the page viewer. If it fails your page could simply report that reading from the web server failed and to try again later.
In this case I would load up the page with the Google map in place and then make an AJAX request for the Weather data.

Related

File Permissions Error using load balancers

I have a problem with logging. I have a class I use to log events, in my ASP.net application, to a text file. The class seems to work fine. Complications arise, though, because we are using a load balancer. We run our app on two servers. If one server fails, the load balancer will switch the web application to the other server. I can also direct the browser to specify which server to view the application on.
The problem is that when I go to one server, the application can log just fine. But if i try to switch to the other server, I get this error:
Exception Details: System.UnauthorizedAccessException: Access to the path '\myServer-qa\plantshare\someFolder\myApp\Logs\2012_12_14.txt' is denied.
ASP.NET is not authorized to access the requested resource. Consider
granting access rights to the resource to the ASP.NET request
identity. ASP.NET has a base process identity (typically
{MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6) that is used if
the application is not impersonating. If the application is
impersonating via , the identity will be
the anonymous user (typically IUSR_MACHINENAME) or the authenticated
request user.
To grant ASP.NET access to a file, right-click the file in Explorer,
choose "Properties" and select the Security tab. Click "Add" to add
the appropriate user or group. Highlight the ASP.NET account, and
check the boxes for the desired access.
If i delete the file, which ever server creates it first will be fine but the other will fail. If i check the files permissions only the server that created it will have permission. Is this an issue with my code or IIS? Also, We use windows authentication. Here is the class I use to write:
Imports System.Net
Imports System.IO
Public Class logger
Private Shared _thisInstance As logger
Private Shared InstanceLock As New Object
Private Shared FileLock As New Object
Private _path As String
Public Property path() As String
Get
Return _path
End Get
Set(ByVal value As String)
_path = value
End Set
End Property
Protected Sub New(ByVal path As String)
Me.path = path
End Sub
Public Shared Function GetSingleton(ByVal path As String) As logger
SyncLock InstanceLock
If _thisInstance Is Nothing Then
_thisInstance = New logger(path)
End If
End SyncLock
Return _thisInstance
End Function
Private Function checkDir(ByVal path As String) As Boolean
Dim dir As New DirectoryInfo(path)
Dim exist As Boolean = True
If Not dir.Exists Then
Try
dir.Create()
Catch ex As Exception
exist = False
End Try
End If
Return exist
End Function
Private Function checkFile(ByVal path As String) As Boolean
Dim myFile As New FileInfo(path)
Dim exist As Boolean = True
Dim objWriter As IO.StreamWriter
Dim fs As FileStream
If Not myFile.Exists Then
Try
fs = New FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite)
objWriter = New System.IO.StreamWriter(fs)
objWriter.Close()
objWriter.Dispose()
fs.Close()
fs.Dispose()
Catch ex As Exception
exist = False
Finally
End Try
End If
Return exist
End Function
'updates file
Public Sub Logger(ByVal filePath As String, ByVal Message As String, ByVal title As String, Optional ByVal stkTrace As String = "")
Dim sw As StreamWriter
Dim fs As FileStream
Dim path As String
Dim now As DateTime = DateTime.Now
Dim today As String
today = Date.Now.ToString("yyy/MM/dd")
path = Me.path & today.Replace("/", "_") & ".txt"
If checkFile(path) Then
SyncLock FileLock
fs = New FileStream(path, FileMode.Append)
sw = New StreamWriter(fs)
Try
sw.WriteLine("Title: " & title)
sw.WriteLine("Message: " & Message)
sw.WriteLine("StackTrace: " & stkTrace)
sw.WriteLine("Date/Time: " & now.ToString("yyyy/MM/dd HH:mm:ss"))
sw.WriteLine("================================================")
sw.Flush()
Catch ex As Exception
Throw
Finally
sw.Close()
fs.Close()
sw.Dispose()
fs.Dispose()
End Try
End SyncLock
End If
End Sub
End Class

Upload a document after saving it with agility pack fails

I've been struggling with some issue with an upload (thru FtpWebRequest) of a document after it's been saved with Html Agility pack.
I'm trying to edit a html file and then save it to a stringWriter and then upload it to a server.
I'm saving the document like this
...
doc.OptionAutoCloseOnEnd = True
doc.OptionWriteEmptyNodes = True
Dim sr As New StringWriter
doc.Save(sr)
And then upload it using asyncFtpUpload sub like the one on msdn but only with a few changes (instead of a filename I use the string)
http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx#Y3024
The result of this is that the file beeing uploaded get's the last bytes cut off.
When I see the source code of that file on the server, it misses the <\html> tag.
i have debugged the code and the string created on the doc.save() is correct, then in the upload routine, when i use the getBytes() it's still correct, and the requestStream write method writes the correct length of the stream.
I can't figure out what's happening with this code.
Can anyone help me figuring this out?
Here's the code:
Dim outStream As MemoryStream = New MemoryStream(ASCIIEncoding.Default.GetBytes(str))
Dim uploader As AsynchronousFtpUpLoader = New AsynchronousFtpUpLoader
uploader.startUpload(pag, outStream)
And the class:
Public Class AsynchronousFtpUpLoader
Public Sub startUpload(ByVal pag As FtpPage, ByVal stream As Stream)
Try
Dim waitObject As ManualResetEvent
Dim target As New Uri(pag.currentUrl)
Dim state As New FtpState()
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(target), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.UploadFile
request.UseBinary = False
request.Credentials = New NetworkCredential(pag.login, pag.password)
state.Request = request
state.stream = stream
' Get the event to wait on.
waitObject = state.OperationComplete
' Asynchronously get the stream for the file contents.
request.BeginGetRequestStream(New AsyncCallback(AddressOf EndGetStreamCallback), state)
' Block the current thread until all operations are complete.
waitObject.WaitOne()
' The operations either completed or threw an exception.
If state.OperationException IsNot Nothing Then
Throw state.OperationException
Else
End If
Catch ex As Exception
End Try
End Sub
Private Shared Sub EndGetStreamCallback(ByVal ar As IAsyncResult)
Dim state As FtpState = DirectCast(ar.AsyncState, FtpState)
Dim requestStream As Stream = Nothing
Try
requestStream = state.Request.EndGetRequestStream(ar)
Const bufferLength As Integer = 2048
Dim buffer As Byte() = New Byte(bufferLength) {}
Dim readBytes As Integer = 0
Dim stream As MemoryStream = state.stream
Do
readBytes = stream.Read(buffer, 0, bufferLength)
If readBytes <> 0 Then
requestStream.Write(buffer, 0, readBytes)
End If
Loop While readBytes <> 0
requestStream.Flush()
state.stream.Close()
requestStream.Close()
state.Request.BeginGetResponse(New AsyncCallback(AddressOf EndGetResponseCallback), state)
Catch e As Exception
state.OperationException = e
state.OperationComplete.[Set]()
Return
End Try
End Sub
Private Shared Sub EndGetResponseCallback(ByVal ar As IAsyncResult)
Dim state As FtpState = DirectCast(ar.AsyncState, FtpState)
Dim response As FtpWebResponse = Nothing
Try
response = DirectCast(state.Request.EndGetResponse(ar), FtpWebResponse)
response.Close()
state.StatusDescription = response.StatusDescription
state.OperationComplete.[Set]()
Catch e As Exception
state.OperationException = e
state.OperationComplete.[Set]()
End Try
End Sub

How to serialize List in VB.NET to JSON

I have the following code to convert a list of messages into json :
Public Class MessageService
<OperationContract()> _
Public Function GetMessage(Id As Integer) As String
Dim msg As New Message()
Dim stream As New MemoryStream()
Dim serializer As New DataContractJsonSerializer(GetType(NewMessage))
Dim dtMessages = msg.getUnreadMessages("3A3458")
Dim list As New ArrayList
Dim m As New NewMessage()
m.Id = 1
m.Text = "mmsg"
list.Add(m)
list.Add(m)
serializer.WriteObject(stream, list)
stream.Position = 0
Dim streamReader As New StreamReader(stream)
Return streamReader.ReadToEnd()
End Function
End Class
But I got the following error :
The server was unable to process the request due to an internal error.
For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client,
or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.
Here:
Dim serializer As New DataContractJsonSerializer(GetType(NewMessage))
You indicate to the serializer that you want to serialize a NewMessage instance.
And here:
serializer.WriteObject(stream, list)
you are passing an Arraylist. This obviously is ambiguous. I would recommend you modifying your method so that it returns directly a strongly typed collection and leave the JSON serialization to the binding instead of writing plumbing code in your data contract:
Public Class MessageService
<OperationContract()> _
Public Function GetMessage(Id As Integer) As List(Of NewMessage)
Dim list As New List(Of NewMessage)
Dim m As New NewMessage()
m.Id = 1
m.Text = "mmsg"
list.Add(m)
Return list
End Function
End Class

Google calendar in vb.net

I am trying to convert the calendar code of C#.NET provided on google site to VB.NET and facing some conversion issues. Please help me.
Code in C#.net:
static void RetrieveAcls(CalendarService service)
{
FeedQuery query = new FeedQuery();
query.Uri = new Uri("http://www.google.com/calendar/feeds/testingforfinals#gmail.com");
AtomFeed calFeed = service.Query(query);
Console.WriteLine();
Console.WriteLine("Sharing permissions for your calendars:");
// Retrieve the meta-feed of all calendars.
foreach (AtomEntry calendarEntry in calFeed.Entries)
{
Console.WriteLine("Calendar: {0}", calendarEntry.Title.Text);
AtomLink link = calendarEntry.Links.FindService(
AclNameTable.LINK_REL_ACCESS_CONTROL_LIST, null);
// For each calendar, retrieve its ACL feed.
if (link != null)
{
AclFeed feed = service.Query(new AclQuery(link.HRef.ToString()));
foreach (AclEntry aclEntry in feed.Entries)
{
Console.WriteLine("\tScope: Type={0} ({1})", aclEntry.Scope.Type,
aclEntry.Scope.Value);
Console.WriteLine("\tRole: {0}", aclEntry.Role.Value);
}
}
}
}
My code in VB.NET:
Public Sub RetrieveAcls(ByVal service As CalendarService)
Dim query As New FeedQuery
query.Uri = New Uri("http://www.google.com/calendar/feeds/testingforfinals#gmail.com")
Dim calFeed As New AtomFeed(service.Query(query))
Console.WriteLine()
Console.WriteLine("Sharing permissions for your calendars:")
Dim calendarEntry As New AtomEntry
Dim link As New AtomLink
Dim aclEntry As New AclEntry
For Each calendarEntry In calFeed.Entries
Console.WriteLine("Calendar: {0}", calendarEntry.Title.Text)
link = calendarEntry.Links.FindService(AclNameTable.LINK_REL_ACCESS_CONTROL_LIST, "")
If (link Is Nothing) Then
Dim feed As AclFeed()
feed = New AclFeed(query, service)
feed = service.Query(New AclQuery(link.HRef.ToString()))
For Each aclEntry In feed.Entries
Console.WriteLine("\tScope: Type={0} ({1})", aclEntry.Scope.Type, aclEntry.Scope.Value)
Console.WriteLine("\tRole: {0}", aclEntry.Role.Value)
Next
End If
Next
End Sub
Am facing error at "query" in "feed = New AclFeed(query, service)" which says Value of type Google.GData.Client.FeedQuery cannot be converted to 'System.Uri'... This issue is resolved... One more last issue is as per below...
Dim myQuery As New EventQuery(feedURI)
Dim myResultsFeed As New EventFeed(service.Query(myQuery))
I am getting error on "myResultsFeed" as "Argument not specified for parameter 'iService' of 'Public Sub New(uriBase As System.Uri, iService As Google.GData.Client.IService)'." and another error on "service.Query(myQuery)) as "Value of type 'Google.GData.Calendar.EventFeed' cannot be converted to 'System.Uri'."
static void DateRangeQuery(CalendarService service, DateTime startTime, DateTime endTime)
{
EventQuery myQuery = new EventQuery(feedUri);
myQuery.StartTime = startTime;
myQuery.EndTime = endTime;
EventFeed myResultsFeed = service.Query(myQuery) as EventFeed;
Console.WriteLine("Matching events from {0} to {1}:",
startTime.ToShortDateString(),
endTime.ToShortDateString());
Console.WriteLine();
for (int i = 0; i < myResultsFeed.Entries.Count; i++)
{
Console.WriteLine(myResultsFeed.Entries[i].Title.Text);
}
Console.WriteLine();
}
Well you've converted this:
AclFeed feed = service.Query(new AclQuery(link.HRef.ToString()));
to this:
Dim feed As AclFeed()
feed = New AclFeed(query, service)
feed = service.Query(New AclQuery(link.HRef.ToString()))
They're not the same at all! Your second line is calling a constructor for no obvious reason.
Just this would be fine:
Dim feed As AclFeed = service.Query(New AclQuery(link.HRef.ToString()))
It's also not clear why you've got lines like this:
Dim calendarEntry As New AtomEntry
Why are you calling the parameterless constructor for AtomEntry? Why are you declaring the variable outside the ForEach loop at all? Just use:
For Each calendarEntry As AtomEntry In calFeed.Entries
EDIT: For the other issue, I think you just need:
Dim myEventFeed As CType(service.Query(myQuery), EventFeed)
If you could provide the full method, that would help.
I'm not sure if it works, but this is the direct c#->VB.Net-Translation from developerfusion, the syntax seems to be correct. Only as a hint for your next problems ;)
Shared Sub RetrieveAcls(ByVal service As CalendarService)
Dim query As New FeedQuery()
query.Uri = New Uri("http://www.google.com/calendar/feeds/testingforfinals#gmail.com")
Dim calFeed As AtomFeed = service.Query(query)
Console.WriteLine()
Console.WriteLine("Sharing permissions for your calendars:")
' Retrieve the meta-feed of all calendars.
For Each calendarEntry As AtomEntry In calFeed.Entries
Console.WriteLine("Calendar: {0}", calendarEntry.Title.Text)
Dim link As AtomLink = calendarEntry.Links.FindService(AclNameTable.LINK_REL_ACCESS_CONTROL_LIST, Nothing)
' For each calendar, retrieve its ACL feed.
If Not link Is Nothing Then
Dim feed As AclFeed = service.Query(New AclQuery(link.HRef.ToString()))
For Each aclEntry As AclEntry In feed.Entries
Console.WriteLine(vbTab & "Scope: Type={0} ({1})", aclEntry.Scope.Type, aclEntry.Scope.Value)
Console.WriteLine(vbTab & "Role: {0}", aclEntry.Role.Value)
Next
End If
Next
End Sub

SQL Dataset to JSON

Alright I have been trying to figure this out and I read the MSDN page on the JavaScriptSerializer. However, I still can't figure out how to get this to work on an asp.net page. I want to convert my dataset into a json string so I can graph it using FLOT(graphing tool)
THIS MADE IT WORK THANKS FOR YOUR HELP GUYS: this is in vb.net for future people
Imports System.Web.Script.Serialization
....
Dim myObject = dataset.GetXml()
Dim jsonString = (New JavaScriptSerializer()).Serialize(myObject)
Reference the assembly System.Web.Extensions.dll and then do this:
using System.Web.Script.Serialization;
....
var myObject = ... your stuff ...
var jsonString = new JavaScriptSerializer().Serialize(myObject);
Check out the MSDN page for more info.
I did the following when I was working on a Project using PlotKit. I create a webservice to return the data and set the response format to Jason...this was while ago...should also work in 3.5
Here is a sample
<WebMethod()> _
<Script.Services.ScriptMethod(UseHttpGet:=True, ResponseFormat:=ResponseFormat.Json)> _
Public Function GetSales(ByVal a As String) As Generic.List(Of Sale)
Dim _conn As SqlConnection = New SqlConnection(connstr)
Dim _dr As SqlDataReader
Try
Dim _cmd As SqlCommand = New SqlCommand("select * from sales", _conn)
_conn.Open()
_dr = _cmd.ExecuteReader(CommandBehavior.CloseConnection)
If _dr.HasRows Then
Dim s As Sale
Dim c As New Generic.List(Of Sale)
While _dr.Read
s = New Sale
With s
.Month = _dr("monthname")
.TheSale = _dr("sale")
End With
c.Add(s)
End While
Return c
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
_conn.Close()
End Try
End Function
End Class
Here is the object class...notice I am serializing the object.
<Serializable()> _
Public Class Sale
Private _month As String
Private _sale As String
Public Property Month() As String
Get
Return _month
End Get
Set(ByVal value As String)
_month = value
End Set
End Property
Public Property TheSale() As String
Get
Return _sale
End Get
Set(ByVal value As String)
_sale = value
End Set
End Property
End Class
Check out the DataContractJsonSerializer, and this article on MSDN
public static string DStoJSON(DataSet ds)
{
StringBuilder json = new StringBuilder();
foreach (DataRow dr in ds.Tables[0].Rows)
{
json.Append("{");
int i = 0;
int colcount = dr.Table.Columns.Count;
foreach (DataColumn dc in dr.Table.Columns)
{
json.Append("\"");
json.Append(dc.ColumnName);
json.Append("\":\"");
json.Append(dr[dc]);
json.Append("\"");
i++;
if (i < colcount) json.Append(",");
}
json.Append("\"}");
json.Append(",");
}
return json.ToString();
}
Probably most useful to you is the dataset loop instead of the stringbuilder. You could loop these into an object, then use the javascript serializer library.
Or even better, if you are using asp.net mvc, you can just do this:
return Json(List<myobject>, JsonRequestBehavior.AllowGet);
but this way is quick & easy! -- I didn't quite test this! the appended comma might be wrong (or code can be improved) and the final row comma needs to be handled
I use the mvc way & never looked back :)

Resources