Error building Custom Sitemap - asp.net

I'm trying to build a custom sitemap
I look into code on this site
http://harriyott.com/2007/03/adding-dynamic-nodes-to-aspnet-site
I have convert it into vb.net as far as I could
here is my code
Partial Class Main
Inherits StaticSiteMapProvider
Dim conn As New ConnectionVB
Dim _rootNode As SiteMapNode = Nothing
Dim _siteMapFileName As String
Dim SiteMapNodeName As String = "siteMapNode"
Public Sub DynamicSiteMapProvider()
End Sub
Public Shadows Function RootNode() As SiteMapNode
Return BuildSiteMap()
End Function
Public Overrides Sub Initialize(name As String, attributes As NameValueCollection)
//Me.Initialize(name, attributes)
_siteMapFileName = attributes("siteMapFile")
End Sub
Protected Overrides Function GetRootNodeCore() As SiteMapNode
Return RootNode()
End Function
Protected Overrides Sub clear()
SyncLock Me
_rootNode = Nothing
//Me.clear()
End SyncLock
End Sub
Public Overrides Function BuildSiteMap() As SiteMapNode
SyncLock Me
If _rootNode Is Nothing Then
clear()
Dim siteMapXml As XmlDocument = LoadSiteMapXml()
Dim rootElement As XmlElement = CType(siteMapXml.GetElementsByTagName(SiteMapNodeName)(0), XmlElement)
AddDynamicNodes(rootElement)
GenerateSiteMapNodes(rootElement)
End If
End SyncLock
Return _rootNode
End Function
Private Function LoadSiteMapXml() As XmlDocument
Dim siteMapXml As XmlDocument = New XmlDocument()
siteMapXml.Load(AppDomain.CurrentDomain.BaseDirectory + _siteMapFileName)
Return siteMapXml
End Function
Protected Sub AddDynamicNodes(rootElement As XmlElement)
Dim teams As XmlElement = AddDynamicChildElement(rootElement, "", "FootballTeams", "List of football team")
End Sub
Protected Function AddDynamicChildElement(parentElement As XmlElement, url As String, title As String, description As String) As XmlElement
Dim childElement As XmlElement = parentElement.OwnerDocument.CreateElement(SiteMapNodeName)
childElement.SetAttribute("url", url)
childElement.SetAttribute("title", title)
childElement.SetAttribute("description", description)
parentElement.AppendChild(childElement)
Return childElement
End Function
Protected Sub GenerateSiteMapNodes(rootElement As XmlElement)
_rootNode = GetSiteMapNodeFromElement(rootElement)
AddNode(_rootNode)
CreateChildNodes(rootElement, _rootNode)
End Sub
Protected Sub CreateChildNodes(parentElement As XmlElement, parentNode As SiteMapNode)
For Each XmlElement As XmlNode In parentElement.ChildNodes
If XmlElement.Name = SiteMapNodeName Then
Dim childNode As SiteMapNode = GetSiteMapNodeFromElement(CType(XmlElement, XmlElement))
AddNode(childNode, parentNode)
CreateChildNodes(CType(XmlElement, XmlElement), childNode)
End If
Next
End Sub
Protected Function GetSiteMapNodeFromElement(rootElement As XmlElement) As SiteMapNode
Dim newSiteMapNode As SiteMapNode
Dim url As String = rootElement.GetAttribute("url")
Dim title As String = rootElement.GetAttribute("title")
Dim description As String = rootElement.GetAttribute("description")
newSiteMapNode = New SiteMapNode(Me, (url + title).GetHashCode().ToString(), url, title, description)
Return newSiteMapNode
End Function
End Class
I got this kind of error
System.ArgumentException: Provider name cannot be null or empty.
I don't have any idea what the cause of this error
could someone help me??
Appreciate all help
thanks
PS : Sorry if my English messed up

Please make sure that you have add this in web config.
<system.web>
<siteMap defaultProvider="main">
<providers>
<add siteMapFile="Web.sitemap" name="main" type="System.Web.XmlSiteMapProvider"/>
</providers>
</siteMap>

Related

Why does RedirectToRoutePermanent add "count=0" to querystring?

I'm using ASP.NET 4.0 Routing and am reading route info from database and adding the routes as below. In a nutshell, my custom object "RouteLookup" contains the route information including the ID of another RouteLookup that it may or may not be redirected to. Here's an example of two RouteLookup entries in the db:
RouteLookupID RouteName RelativePath RequestHandler RouteHandler IsSecure RedirectedToRoute
13 PrivacyRoute about/privacy privacy.aspx NULL 0 0
14 PrivacyRoute1 privacy privacy.aspx NULL 0 13
RouteLookupID 14 is a legacy route that needs to be permanently redirected to RouteLookupID 13. The problem I'm running up against is when I request "http://mydomain.com/privacy" from the browser and watch Fiddler results, it actually redirects TWICE and adds a "count=0" as a querystring parameter! I have NO IDEA where this parameter is coming from as I have no process, httphandler, etc that is adding that explicitly.
What the heck is happening here? Any ideas are greatly appreciated and the rest of the relevant code is below.
I have a class, BaseRoute, which inherits from Route, so I can pass my custom RouteLookup object along with it to be examined in the custom RouteHandler which I've named BaseRouteHandler.
Public Class PageRouter
Private Shared db As New QADBDataContext
''''''' Is called from Global Application_Start
Public Shared Sub MapRoutes(routeColl As RouteCollection)
Dim routeLookups As IEnumerable(Of RouteLookup) = From rt In db.RouteLookups Select rt
For Each rtLookUp As RouteLookup In routeLookups
Dim parameterizedURL As String = BuildParameterizedVirtualPath(rtLookUp)
' Determine handler and route values
If rtLookUp.RouteHandler Is Nothing Then
RouteTable.Routes.Add(rtLookUp.RouteName, New BaseRoute(parameterizedURL, New BaseRouteHandler(), rtLookUp))
Else
RouteTable.Routes.Add(rtLookUp.RouteName, New BaseRoute(parameterizedURL, Activator.CreateInstance(Type.GetType("QA." + rtLookUp.RouteHandler)), rtLookUp))
End If
Next
End Sub
Protected Shared Function BuildParameterizedVirtualPath(rtLookUp As RouteLookup) As String
Dim parameterizedURL As String = rtLookUp.RelativePath
For Each param As RouteParameter In rtLookUp.RouteParameters
parameterizedURL &= "/{" + param.Name + "}"
Next
Return parameterizedURL
End Function
Public Shared Sub RedirectToRoutePermanent(rtData As RouteData)
Dim route As BaseRoute = DirectCast(rtData.Route, BaseRoute)
Dim rtLookup As RouteLookup = route.RouteLookup
Dim newRtLookupID As Integer = rtLookup.RedirectedToRoute
Dim newRtLookup As RouteLookup = (From rt In db.RouteLookups Where rt.RouteLookupID = newRtLookupID).SingleOrDefault
HttpContext.Current.Response.RedirectToRoutePermanent(newRtLookup.RouteName, rtData.Values.Values)
End Sub
End Class
Custom Route class:
Public Class BaseRoute
Inherits Route
Private _routeLookup As RouteLookup = Nothing
Public Sub New(url As String, routeHandler As IRouteHandler, routeLookup As RouteLookup)
MyBase.New(url, routeHandler)
_routeLookup = routeLookup
End Sub
Public ReadOnly Property RouteLookup As RouteLookup
Get
Return _routeLookup
End Get
End Property
End Class
Custom RouteHandler:
Public Class BaseRouteHandler
Implements IRouteHandler
Protected _baseRoute As BaseRoute = Nothing
Protected _rtLookup As RouteLookup = Nothing
Protected Overridable Sub InitializeContext(ByVal requestContext As System.Web.Routing.RequestContext)
_baseRoute = DirectCast(requestContext.RouteData.Route, BaseRoute)
_rtLookup = _baseRoute.RouteLookup
End Sub
Public Function GetHttpHandler(ByVal requestContext As System.Web.Routing.RequestContext) _
As System.Web.IHttpHandler Implements System.Web.Routing.IRouteHandler.GetHttpHandler
InitializeContext(requestContext)
EnforceURLStandard(requestContext)
PerformRedirectIfNeeded(requestContext)
Return GetPageHandler(requestContext)
End Function
Protected Overridable Sub PerformRedirectIfNeeded(ByVal requestContext As System.Web.Routing.RequestContext)
If _rtLookup.RedirectedToRoute > 0 Then
PageRouter.RedirectToRoutePermanent(requestContext.RouteData)
End If
End Sub
Protected Sub EnforceURLStandard(ByVal requestContext As System.Web.Routing.RequestContext)
' Test for:
' * Proper protocol
' * www. exists
' * must be all lowercase
Dim scheme As String = HttpContext.Current.Request.Url.GetComponents(UriComponents.Scheme, UriFormat.UriEscaped)
Dim rightSide As String = HttpContext.Current.Request.Url.GetComponents(UriComponents.HostAndPort Or UriComponents.PathAndQuery, UriFormat.UriEscaped)
Dim newURL As String = Nothing
If Not rightSide.ToLower().StartsWith("www.") AndAlso Not rightSide.ToLower().StartsWith("localhost") _
AndAlso Not rightSide.ToLower().StartsWith("uat") AndAlso Not rightSide.ToLower().StartsWith("ux") Then
newURL = scheme & "://www." & rightSide
End If
If _rtLookup.IsSecure <> requestContext.HttpContext.Request.IsSecureConnection Then
Dim newScheme As String = If(_rtLookup.IsSecure, "https", "http")
newURL = newScheme & rightSide
End If
Dim pattern As String = "[A-Z]"
If Not String.IsNullOrWhiteSpace(newURL) Then
If Regex.IsMatch(newURL, pattern) Then
newURL = newURL.ToLower()
End If
Else
If Regex.IsMatch(HttpContext.Current.Request.Url.ToString(), pattern) Then
newURL = HttpContext.Current.Request.Url.ToString().ToLower()
End If
End If
If Not newURL Is Nothing Then
HttpContext.Current.Response.RedirectPermanent(newURL, True)
End If
End Sub
Protected Overridable Function GetPageHandler(ByVal requestContext As System.Web.Routing.RequestContext) As System.Web.IHttpHandler
Return TryCast(BuildManager.CreateInstanceFromVirtualPath("/" & _rtLookup.RequestHandler, GetType(Page)), Page)
End Function
End Class
Well, figured out what was happening here. RedirectToRoutePermanent doesn't terminate the request like RedirectPermanent(url, true) does. I rewrote the PageRouter.RedirectToRoutePermanent as such, which resolved the issue:
Public Shared Sub RedirectToRoutePermanent(rtData As RouteData)
Dim route As BaseRoute = DirectCast(rtData.Route, BaseRoute)
Dim rtLookup As RouteLookup = route.RouteLookup
Dim newRtLookupID As Integer = rtLookup.RedirectedToRoute
Dim newRtLookup As RouteLookup = (From rt In db.RouteLookups Where rt.RouteLookupID = newRtLookupID).SingleOrDefault
Dim hostAndPort As String = HttpContext.Current.Request.Url.GetComponents(UriComponents.HostAndPort, UriFormat.UriEscaped)
Dim newURL As String = Nothing
Dim scheme As String = If(rtLookup.IsSecure, "https", "http")
newURL = scheme & "://" & hostAndPort
newURL &= "/" & newRtLookup.RelativePath
If rtData.Values.Count > 1 Then
For i As Integer = 1 To rtData.Values.Count - 1
newURL &= "/" & rtData.Values(i)
Next
End If
HttpContext.Current.Response.RedirectPermanent(newURL, True)
End Sub

use connectionstring from webconfig rather than dataset properties

I built a dataset using the wizzard and added a connection in there.
I now want to use a connection string which is defined in my web config instead of whats set in the dataset.
I have the following code (i've taken a lot of stuff out you don't need to see)
Partial Public Class downloaditems
Inherits System.Web.UI.Page
Private dtmboFeed As dsmbo.mboFeedDataTable
Private tamboFeed As New dsmboTableAdapters.mboFeedTableAdapter
Private itemCount As Integer = 0
Private changedItem As Boolean = False
Private headSource As String
Private footSource As String
Private sideSource As String
Private lastHead As String
Private lastFoot As String
Private lastSide As String
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
feedChecks()
If changedItem = True Then
If itemCount = "3" Then
savetodatabase(headSource, footSource, sideSource)
End If
End If
End Sub
Private Sub checkSite(ByVal URL As String, ByVal Type As String)
Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create(URL)
request.UserAgent = ".NET Framework Test Client"
Dim response As System.Net.HttpWebResponse = request.GetResponse()
Dim sr As System.IO.StreamReader = New System.IO.StreamReader(response.GetResponseStream())
Dim sourcecode As String = sr.ReadToEnd()
Dim compareHead As Integer
Dim compareFoot As Integer
Dim compareSide As Integer
Select Case Type
Case "headSource"
headSource = sourcecode
compareHead = String.Compare(headSource, lastHead)
Case "footSource"
footSource = sourcecode
compareFoot = String.Compare(footSource, lastFoot)
Case "sideSource"
sideSource = sourcecode
compareSide = String.Compare(sideSource, lastSide)
End Select
If Not compareHead = "0" Then
changedItem = True
End If
If Not compareFoot = "0" Then
changedItem = True
End If
If Not compareSide = "0" Then
changedItem = True
End If
itemCount = itemCount + 1
End Sub
Private Sub feedChecks()
Dim lastImport As DateTime
dtmboFeed = New dsmbo.mboFeedDataTable
dtmboFeed = tamboFeed.GetCode()
For Each rFeed As dsmbo.mboFeedRow In dtmboFeed
lastImport = rFeed.LastImport
lastHead = rFeed.HeaderCode
lastFoot = rFeed.FooterCode
lastSide = rFeed.SideCode
Next
If lastImport > System.DateTime.Now.AddDays(1) Then
checkSite("http://www.xxx.me/sss/header.html", "headSource")
checkSite("http://www.xxx.me/sss/footer.html", "footSource")
checkSite("http://www.xxx.me/sss/sidenav.html", "sideSource")
Else
Exit Sub
End If
End Sub
Private Sub savetodatabase(ByVal HeaderCode As String, ByVal FooterCode As String, ByVal SideCode As String)
dtmboFeed = tamboFeed.GetData()
Dim rFeed As dsmbo.mboFeedRow
rFeed = dtmboFeed.NewmboFeedRow
rFeed.HeaderCode = HeaderCode
rFeed.FooterCode = FooterCode
rFeed.SideCode = SideCode
rFeed.LastImport = System.DateTime.Now
rFeed.Verified = "True"
dtmboFeed.AddmboFeedRow(rFeed)
tamboFeed.Update(dtmboFeed)
lblCode.Text = lblCode.Text & "All downloaded"
End Sub End Class
EDIT:
Heres my updated code below as requested. I'm getting an error saying
Error 53 Value of type 'String' cannot be converted to 'System.Data.SqlClient.SqlConnection'.
Code:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim constring As String
constring = ConfigurationManager.ConnectionStrings("ConnectString").ToString()
tamboFeed.Connection = constring
feedChecks()
If changedItem = True Then
If itemCount = "3" Then
savetodatabase(headSource, footSource, sideSource)
End If
End If
End Sub
You can get the connection string as
Dim constring as String
constring = ConfigurationManager.ConnectionStrings("YouconnectionStringNameinWebConfig").ConnectionString
Now first go to your DataSet Design View, Select the table,right click on tableAdapter and Change it's Connection modifier to Public ( see below picture ), now you can access adapter connection property in the codebehind.
tamboFeed.Connection = constring
See the below picture for changing access modifier.
Picture Reference: Link
Updated answer:
The problem is that you have placed you connection string in the AppSettings section in the webconfig, add your connection string to ConnectionString Section. See below code
<connectionStrings>
<add name="ConnectString" connectionString="data source=server;initial catalog=database;persist security info=False;user id=adsadasda;password=asdsadasd;packet size=4096" />
</connectionStrings>
tamboFeed.Connection is of type System.data.SqlClient.SqlConnection so cannot accept a string assignment. So long as the dataset connection modifier is set to Public, you can assign the connection string from the web.config in one line, as follows:
tamboFeed.Connection.ConnectionString = ConfigurationManager.ConnectionStrings("YouconnectionStringNameinWebConfig").ConnectionString

Access sessions in asp.net handler

I am trying to upload images using generic handler as shown below and I have a normal aspx page where I am showing all the uploaded images after uploading.Everything is working fine.
<%# WebHandler Language="VB" Class="Upload"%>
Imports System
Imports System.Web
Imports System.Threading
Imports System.Web.Script.Serialization
Imports System.IO
Public Class Upload : Implements IHttpHandler, System.Web.SessionState.IRequiresSessionState
Public Class FilesStatus
Public Property thumbnail_url() As String
Public Property name() As String
Public Property url() As String
Public Property size() As Integer
Public Property type() As String
Public Property delete_url() As String
Public Property delete_type() As String
Public Property [error]() As String
Public Property progress() As String
End Class
Private ReadOnly js As New JavaScriptSerializer()
Private ingestPath As String
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim r = context.Response
ingestPath = context.Server.MapPath("~/UploadedImages/")
r.AddHeader("Pragma", "no-cache")
r.AddHeader("Cache-Control", "private, no-cache")
HandleMethod(context)
End Sub
Private Sub HandleMethod(ByVal context As HttpContext)
Select Case context.Request.HttpMethod
Case "HEAD", "GET"
ServeFile(context)
Case "POST"
UploadFile(context)
Case "DELETE"
DeleteFile(context)
Case Else
context.Response.ClearHeaders()
context.Response.StatusCode = 405
End Select
End Sub
Private Sub DeleteFile(ByVal context As HttpContext)
Dim filePath = ingestPath & context.Request("f")
If File.Exists(filePath) Then
File.Delete(filePath)
End If
End Sub
Private Sub ServeFile(ByVal context As HttpContext)
If String.IsNullOrEmpty(context.Request("f")) Then
ListCurrentFiles(context)
Else
DeliverFile(context)
End If
End Sub
Private Sub UploadFile(ByVal context As HttpContext)
Dim statuses = New List(Of FilesStatus)()
Dim headers = context.Request.Headers
If String.IsNullOrEmpty(headers("X-File-Name")) Then
UploadWholeFile(context, statuses)
Else
UploadPartialFile(headers("X-File-Name"), context, statuses)
End If
WriteJsonIframeSafe(context, statuses)
End Sub
Private Sub UploadPartialFile(ByVal fileName As String, ByVal context As HttpContext, ByVal statuses As List(Of FilesStatus))
If context.Request.Files.Count <> 1 Then
Throw New HttpRequestValidationException("Attempt to upload chunked file containing more than one fragment per request")
End If
Dim inputStream = context.Request.Files(0).InputStream
Dim fullName = ingestPath & Path.GetFileName(fileName)
Using fs = New FileStream(fullName, FileMode.Append, FileAccess.Write)
Dim buffer = New Byte(1023) {}
Dim l = inputStream.Read(buffer, 0, 1024)
Do While l > 0
fs.Write(buffer, 0, l)
l = inputStream.Read(buffer, 0, 1024)
Loop
fs.Flush()
fs.Close()
End Using
statuses.Add(New FilesStatus With {.thumbnail_url = "Thumbnail.ashx?f=" & fileName, .url = "Upload.ashx?f=" & fileName, .name = fileName, .size = CInt((New FileInfo(fullName)).Length), .type = "image/png", .delete_url = "Upload.ashx?f=" & fileName, .delete_type = "DELETE", .progress = "1.0"})
End Sub
Private Sub UploadWholeFile(ByVal context As HttpContext, ByVal statuses As List(Of FilesStatus))
For i As Integer = 0 To context.Request.Files.Count - 1
Dim file = context.Request.Files(i)
file.SaveAs(ingestPath & Path.GetFileName(file.FileName))
Thread.Sleep(1000)
Dim fname = Path.GetFileName(file.FileName)
statuses.Add(New FilesStatus With {.thumbnail_url = "Thumbnail.ashx?f=" & fname, .url = "Upload.ashx?f=" & fname, .name = fname, .size = file.ContentLength, .type = "image/png", .delete_url = "Upload.ashx?f=" & fname, .delete_type = "DELETE", .progress = "1.0"})
Next i
End Sub
Private Sub WriteJsonIframeSafe(ByVal context As HttpContext, ByVal statuses As List(Of FilesStatus))
context.Response.AddHeader("Vary", "Accept")
Try
If context.Request("HTTP_ACCEPT").Contains("application/json") Then
context.Response.ContentType = "application/json"
Else
context.Response.ContentType = "text/plain"
End If
Catch
context.Response.ContentType = "text/plain"
End Try
Dim jsonObj = js.Serialize(statuses.ToArray())
context.Response.Write(jsonObj)
End Sub
Private Sub DeliverFile(ByVal context As HttpContext)
Dim filePath = ingestPath & context.Request("f")
If File.Exists(filePath) Then
context.Response.ContentType = "application/octet-stream"
context.Response.WriteFile(filePath)
context.Response.AddHeader("Content-Disposition", "attachment, filename=""" & context.Request("f") & """")
Else
context.Response.StatusCode = 404
End If
End Sub
Private Sub ListCurrentFiles(ByVal context As HttpContext)
Dim files = New List(Of FilesStatus)()
Dim names = Directory.GetFiles(context.Server.MapPath("~/UploadedImages/"), "*", SearchOption.TopDirectoryOnly)
For Each name In names
Dim f = New FileInfo(name)
files.Add(New FilesStatus With {.thumbnail_url = "Thumbnail.ashx?f=" & f.Name, .url = "Upload.ashx?f=" & f.Name, .name = f.Name, .size = CInt(f.Length), .type = "image/png", .delete_url = "Upload.ashx?f=" & f.Name, .delete_type = "DELETE"})
Next name
context.Response.AddHeader("Content-Disposition", "inline, filename=""files.json""")
Dim jsonObj = js.Serialize(files.ToArray())
context.Response.Write(jsonObj)
context.Response.ContentType = "application/json"
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
Now I want to add a session variable by generating a random string and add the uploaded images to the newly created random string.
1.I have seen this Question on SO to use System.Web.SessionState.IRequiresSessionState for sessions and how do I create a folder with that and add my images to that folder after doing that how do I access this session variable in my normal aspx page.
2.(Or) the better way is create session variable in aspx page and pass that to handler?If so how can I do that?
3 .I am trying to find the control from my handler.Is that possible?If anyone knows how to get this then also my problem will get resolved so that I am trying to create a session from m aspx page.
Can anyone explain the better way of handling this situation.
I completely agree with jbl's comment.
You can get and set session using HttpContext.Current.Session anywhere on your project.
No matter where you create the session. Just make sure that the session exists before you access it.
Not sure what exactly you are asking here(need some more explanation).
Here is an example, where I used session on HttpHandler. However, it is on c#(hope you can understand).
This is not really an answer but #Knvn wrote a C# example which I couldn't understand so I used a converter to convert it to VB. Posted it here in case it helps someone in the future.
Public Class HttpHandler
Implements IHttpHandler
Implements IRequiresSessionState
Public Sub New()
End Sub
Public Sub ProcessRequest(context As HttpContext)
Dim Request As HttpRequest = context.Request
Dim Response As HttpResponse = context.Response
If SessionHandler.Current.UserID = 0 Then
Response.Redirect("~/Default.aspx")
Else
Try
If Request.Path.EndsWith(".pdf") Then
Dim client As New WebClient()
Dim buffer As [Byte]() = client.DownloadData(HttpContext.Current.Server.MapPath(Request.Path))
Response.ContentType = "application/pdf"
Response.AddHeader("content-length", buffer.Length.ToString())
Response.BinaryWrite(buffer)
Else
Using reader As New StreamReader(HttpContext.Current.Server.MapPath(Request.Path))
Response.Write(reader.ReadToEnd())
End Using
End If
Catch
Response.Redirect("~/Default.aspx")
End Try
End If
End Sub
Public ReadOnly Property IsReusable() As Boolean
' To enable pooling, return true here.
' This keeps the handler in memory.
Get
Return False
End Get
End Property
End Class

convert from httppostedfile to htmlinputfile

how do I convert an httppostedfile to an htmlinputfile? I'm working with an old mess of an app and so far have been able to refactor it so it makes a bit of sense, but this particular mess is too tangled to be worth the effort :S.
Thanks, as usual, for the help
relevant code:
collection:
Imports System.IO
Imports System.Web.UI.HtmlControls
Public Class ArchivosCollection
Inherits CollectionBase
Default Public Property Item(ByVal index As Integer) As HtmlInputFile
Get
Return MyBase.List(index)
End Get
Set(ByVal Value As HtmlInputFile)
MyBase.List(index) = Value
End Set
End Property
Public Function Add(ByVal oArchivo As HtmlInputFile) As Integer
Return MyBase.List.Add(oArchivo)
End Function
Public Function getDataSource() As DataTable
Dim dt As New DataTable
Dim oArchivo As HtmlInputFile
Dim fila As DataRow
Dim orden As Integer = 0
dt.Columns.Add("documento", GetType(System.String))
dt.Columns.Add("tipo", GetType(System.String))
For Each oArchivo In list
If Not oArchivo.Disabled Then
fila = dt.NewRow()
fila("documento") = Trim(Path.GetFileName(oArchivo.PostedFile.FileName))
fila("tipo") = Trim(oArchivo.PostedFile.ContentType)
dt.Rows.Add(fila)
End If
Next
Return dt
End Function
Public Function ExisteArchivo(ByVal Nombre As String) As Boolean
For Each oArchivo As HtmlInputFile In list
If Not oArchivo.Disabled Then
If Path.GetFileName(oArchivo.PostedFile.FileName) = Nombre Then
Return True
End If
End If
Next
Return False
End Function
Public Function EliminarArchivo(ByVal Nombre As String) As Boolean
For Each oArchivo As HtmlInputFile In list
If Not oArchivo.Disabled Then
If Path.GetFileName(oArchivo.PostedFile.FileName) = Nombre Then
oArchivo.Disabled = True
Return True
End If
End If
Next
End Function
End Class
old code:
Private Sub btnAgregarDocumento_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAgregarDocumento.Click
Try
If Not (Me.fleDocumento.PostedFile Is Nothing) Then
If Trim(Me.fleDocumento.PostedFile.FileName) = "" Then
Throw New Exception(rm.GetString("errorDebeEscogerUnArchivo"))
End If
If Not Servicios.isValidUploadType(Me.fleDocumento.PostedFile.FileName, ConfigurationManager.AppSettings("Filtros Upload")) Then
Throw New Exception(rm.GetString("errorExtensionNovalida"))
End If
Dim oArchivosOT As ArchivosCollection
If Session("oArchivosOT") Is Nothing Then
oArchivosOT = New ArchivosCollection
Else
oArchivosOT = Session("oArchivosOT")
End If
If oArchivosOT.ExisteArchivo(Path.GetFileName(Me.fleDocumento.PostedFile.FileName)) Then
Throw New Exception(rm.GetString("errorArchivoYaExiste"))
End If
oArchivosOT.Add(Me.fleDocumento)
Me.dgDocumentos.DataSource = oArchivosOT.getDataSource()
Me.dgDocumentos.DataBind()
Session("oArchivosOT") = oArchivosOT
If Request.QueryString("desde") = "proy" Then
ClientScript.RegisterStartupScript(Page.GetType, "msg", "<script>window.opener.document.Form1.refGridDocs.click();</script>")
End If
Else
Throw New Exception(rm.GetString("errorDebeEscogerUnArchivo"))
End If
Catch exc As Exception
ClientScript.RegisterStartupScript(Page.GetType, "msg", Servicios.MsgBox(exc.Message))
End Try
End Sub
new code (partial):
Dim archivos As HttpFileCollection = Request.Files
Dim colArchivos As ArchivosCollection = IIf(Session("oArchivosOT") Is Nothing, New ArchivosCollection(), Session("oArchivosOT"))
Dim i
For i = 0 To archivos.Count
colArchivos.Add(DirectCast(archivos(i), HtmlInputFile))
Next
Session("oArchivosOT") = colArchivos
The PostedFile property of the HtmlInputFile object is a HttpPostedFile object - you can simply access it for each HtmlInputFile.

How to hide a node from appearing on menu not on breadcrumb (using SqlSiteMapProvider)

I am using wicked code sqlsitemapprovider or it's VB version. Most of the things are going OK! But when I wanted to hide some of the nodes from appearing on menu while staying shown on sitemappath I cannot figure it out. I tried to change the sqlsitemapprovider code but was unsuccessfull. I have found David Sussman's (from sp.net) answer. but it was for a .sitemap file. So how can I manage to do the same with the sql sitemap provider mentioned above.
I added a column named visible to my SiteMap table it's type is bit and then I have done these changes (Sorry for such long code):
Imports System
Imports System.Web
Imports System.Data.SqlClient
Imports System.Collections.Specialized
Imports System.Configuration
Imports System.Web.Configuration
Imports System.Collections.Generic
Imports System.Configuration.Provider
Imports System.Security.Permissions
Imports System.Data.Common
Imports System.Data
Imports System.Web.Caching
''' <summary>
''' Summary description for SqlSiteMapProvider
''' </summary>
<SqlClientPermission(SecurityAction.Demand, Unrestricted:=True)> _
Public Class SqlSiteMapProvider
Inherits StaticSiteMapProvider
Private Const _errmsg1 As String = "Basamak no bulunamadı"
Private Const _errmsg2 As String = "Çift Basamak No"
Private Const _errmsg3 As String = "Üst Basamak Bulunamadı"
Private Const _errmsg4 As String = "Hatalı Üst Basamak"
Private Const _errmsg5 As String = "Bağlantı dizesi bulunamadı veya boş"
Private Const _errmsg6 As String = "Bağlantı dizesi bulunamadı"
Private Const _errmsg7 As String = "Bağlantı dizesi boş"
Private Const _errmsg8 As String = "Hatalı sqlCacheDependency"
Private Const _cacheDependencyName As String = "__SiteMapCacheDependency"
Private _connect As String
'Database connection string
Private _database As String, _table As String
'Database info for SQL Server 7/2000 cache dependency
Private _2005dependency As Boolean = False
'Database info for SQL Server 2005 cache dependency
Private _indexID As Integer, _indexTitle As Integer, _indexUrl As Integer, _indexDesc As Integer, _indexRoles As Integer, _indexParent As Integer, _indexvisible As Boolean
Private _nodes As New Dictionary(Of Integer, SiteMapNode)(16)
Private ReadOnly _lock As New Object()
Private _root As SiteMapNode
'Added...Declare an arraylist to hold all the roles this menu item applies to
Public roles As New ArrayList
Public Overloads Overrides Sub Initialize(ByVal name As String, ByVal config As NameValueCollection)
'Verify that config isn't null
If config Is Nothing Then
Throw New ArgumentNullException("config")
End If
'Assign the provider a default name if it doesn't have one
If [String].IsNullOrEmpty(Name) Then
Name = "SqlSiteMapProvider"
End If
' Add a default "description" attribute to config if the
' attribute doesnt exist or is empty
If String.IsNullOrEmpty(config("description")) Then
config.Remove("description")
config.Add("description", "SQL site map provider")
End If
' Call the base class's Initialize method
MyBase.Initialize(Name, config)
' Initialize _connect
Dim connect As String = config("connectionStringName")
If [String].IsNullOrEmpty(connect) Then
Throw New ProviderException(_errmsg5)
End If
config.Remove("connectionStringName")
If WebConfigurationManager.ConnectionStrings(connect) Is Nothing Then
Throw New ProviderException(_errmsg6)
End If
_connect = WebConfigurationManager.ConnectionStrings(connect).ConnectionString
If [String].IsNullOrEmpty(_connect) Then
Throw New ProviderException(_errmsg7)
End If
' Initialize SQL cache dependency info
Dim dependency As String = config("sqlCacheDependency")
If Not [String].IsNullOrEmpty(dependency) Then
If [String].Equals(dependency, "CommandNotification", StringComparison.InvariantCultureIgnoreCase) Then
SqlDependency.Start(_connect)
_2005dependency = True
Else
' If not "CommandNotification", then extract database and table names
Dim info As String() = dependency.Split(New Char() {":"c})
If info.Length <> 2 Then
Throw New ProviderException(_errmsg8)
End If
_database = info(0)
_table = info(1)
End If
config.Remove("sqlCacheDependency")
End If
' SiteMapProvider processes the securityTrimmingEnabled
' attribute but fails to remove it. Remove it now so we can
' check for unrecognized configuration attributes.
If config("securityTrimmingEnabled") IsNot Nothing Then
config.Remove("securityTrimmingEnabled")
End If
' Throw an exception if unrecognized attributes remain
If config.Count > 0 Then
Dim attr As String = config.GetKey(0)
If Not [String].IsNullOrEmpty(attr) Then
Throw New ProviderException("Unrecognized attribute: " + attr)
End If
End If
End Sub
Public Overloads Overrides Function BuildSiteMap() As SiteMapNode
SyncLock _lock
' Return immediately if this method has been called before
If _root IsNot Nothing Then
Return _root
End If
' Query the database for site map nodes
Dim connection As New SqlConnection(_connect)
Try
Dim command As New SqlCommand("proc_GetSiteMap", connection)
command.CommandType = CommandType.StoredProcedure
' Create a SQL cache dependency if requested
Dim dependency As SqlCacheDependency = Nothing
If _2005dependency Then
dependency = New SqlCacheDependency(command)
ElseIf Not [String].IsNullOrEmpty(_database) AndAlso Not String.IsNullOrEmpty(_table) Then
dependency = New SqlCacheDependency(_database, _table)
End If
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
_indexID = reader.GetOrdinal("ID")
_indexUrl = reader.GetOrdinal("Url")
_indexTitle = reader.GetOrdinal("Title")
_indexDesc = reader.GetOrdinal("Description")
_indexRoles = reader.GetOrdinal("Roles")
_indexParent = reader.GetOrdinal("Parent")
_indexvisible = reader.GetOrdinal("visible")
If reader.Read() Then
' Create the root SiteMapNode and add it to the site map
_root = CreateSiteMapNodeFromDataReader(reader)
AddNode(_root, Nothing)
' Build a tree of SiteMapNodes underneath the root node
While reader.Read()
' Create another site map node and add it to the site map
Dim node As SiteMapNode = CreateSiteMapNodeFromDataReader(reader)
AddNode(node, GetParentNodeFromDataReader(reader))
End While
' Use the SQL cache dependency
If dependency IsNot Nothing Then
HttpRuntime.Cache.Insert(_cacheDependencyName, New Object(), dependency, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, _
New CacheItemRemovedCallback(AddressOf OnSiteMapChanged))
End If
End If
Finally
connection.Close()
End Try
' Return the root SiteMapNode
Return _root
End SyncLock
End Function
Protected Overloads Overrides Function GetRootNodeCore() As SiteMapNode
SyncLock _lock
BuildSiteMap()
Return _root
End SyncLock
End Function
' Helper methods
Private Function CreateSiteMapNodeFromDataReader(ByVal reader As DbDataReader) As SiteMapNode
' Make sure the node ID is present
If reader.IsDBNull(_indexID) Then
Throw New ProviderException(_errmsg1)
End If
' Get the node ID from the DataReader
Dim id As Integer = reader.GetInt32(_indexID)
' Make sure the node ID is unique
If _nodes.ContainsKey(id) Then
Throw New ProviderException(_errmsg2)
End If
' Get title, URL, description, and roles from the DataReader
Dim title As String = IIf(reader.IsDBNull(_indexTitle), Nothing, reader.GetString(_indexTitle).Trim())
'Dim url As String = IIf(reader.IsDBNull(_indexUrl), Nothing, reader.GetString(_indexUrl).Trim())
'Dim url As String = ReplaceNullRefs(reader, _indexUrl)
Dim url As String = String.Empty
If Not (reader.IsDBNull(_indexUrl)) Then
url = reader.GetString(_indexUrl).Trim()
Else
url = ""
End If
'Eliminated...see http://weblogs.asp.net/psteele/archive/2003/10/09/31250.aspx
'Dim description As String = IIf(reader.IsDBNull(_indexDesc), Nothing, reader.GetString(_indexDesc).Trim())
'Added line below and 'ReplaceNUllRefs' func
Dim description As String = ReplaceNullRefs(reader, _indexDesc)
'Changed variable name from 'roles' to 'rolesN' and added line 230 to dump all roles into an arrayList
Dim rolesN As String = IIf(reader.IsDBNull(_indexRoles), Nothing, reader.GetString(_indexRoles).Trim())
Dim rolelist As String() = Nothing
If Not [String].IsNullOrEmpty(rolesN) Then
rolelist = rolesN.Split(New Char() {","c, ";"c}, 512)
End If
roles = ArrayList.Adapter(rolelist)
Dim visible As Boolean = ReplaceNullRefs(reader, _indexvisible)
' Create a SiteMapNode
Dim node As New SiteMapNode(Me, id.ToString(), url, title, description, rolelist, _
Nothing, Nothing, Nothing)
' Record the node in the _nodes dictionary
_nodes.Add(id, node)
' Return the node
Return node
End Function
Private Function ReplaceNullRefs(ByVal rdr As SqlDataReader, ByVal rdrVal As Integer) As String
If Not (rdr.IsDBNull(rdrVal)) Then
Return rdr.GetString(rdrVal)
Else
Return String.Empty
End If
End Function
Private Function GetParentNodeFromDataReader(ByVal reader As DbDataReader) As SiteMapNode
' Make sure the parent ID is present
If reader.IsDBNull(_indexParent) Then
'**** Commented out throw, added exit function ****
Throw New ProviderException(_errmsg3)
'Exit Function
End If
' Get the parent ID from the DataReader
Dim pid As Integer = reader.GetInt32(_indexParent)
' Make sure the parent ID is valid
If Not _nodes.ContainsKey(pid) Then
Throw New ProviderException(_errmsg4)
End If
' Return the parent SiteMapNode
Return _nodes(pid)
End Function
Private Sub OnSiteMapChanged(ByVal key As String, ByVal item As Object, ByVal reason As CacheItemRemovedReason)
SyncLock _lock
If key = _cacheDependencyName AndAlso reason = CacheItemRemovedReason.DependencyChanged Then
' Refresh the site map
Clear()
_nodes.Clear()
_root = Nothing
End If
End SyncLock
End Sub
End Class
and I get this error:
*Özel Durum Ayrıntıları: System.IndexOutOfRangeException: visible
Kaynak Hatası:
Satır 154: _indexRoles = reader.GetOrdinal("Roles")
Satır 155: _indexParent = reader.GetOrdinal("Parent")
Satır 156: _indexvisible = reader.GetOrdinal("visible")
Satır 157:
Satır 158: If reader.Read() Then
Kaynak Dosya: D:\Websites\kaihl\App_Code\SqlSiteMapProvider.vb Satır: 156*
What I want is to tell sqlsitemapprovider to include an attribute within each sitemapnode called visible="true/false". Since this will be an extra attribute for sitemappath and menu (I think) this code would be doing the hiding job in menu not in breadcrumb (according to David Sussman's reply to a similar files .sitemap based thread as I linked above in my question):
Protected Sub Menu1_MenuItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MenuEventArgs) Handles Menu1.MenuItemDataBound
Dim node As SiteMapNode = CType(e.Item.DataItem, SiteMapNode)
' check for the visible attribute and if false
' remove the node from the parent
' this allows nodes to appear in the SiteMapPath but not show on the menu
If Not String.IsNullOrEmpty(node("visible")) Then
Dim isVisible As Boolean
If Boolean.TryParse(node("visible"), isVisible) Then
If Not isVisible Then
e.Item.Parent.ChildItems.Remove(e.Item)
End If
End If
End If
End Sub
how to achieve this? thank you.
Update: I have found something very close at this page but still unable to deploy the solution.
Dim atts As NameValueCollection = Nothing
Dim attributeString As String = reader("attributes").ToString().Trim()
If Not String.IsNullOrEmpty(attributeString) Then
atts = New NameValueCollection()
Dim attributePairs() As String = attributeString.Split(";")
For Each attributePair As String In atts
Dim attributes() As String = attributePair.Split(":")
If attributes.Length = 2 Then
atts.Add(atts(0), attributes(1))
End If
Next
End If
Dim node As New SiteMapNode(Me, id.ToString(), url, title, description, rolelist, _
atts, Nothing, Nothing)
At last I have found a solution. And it is here. Thanks so much to Kadir ÖZGÜR, Sanjay UTTAM, David Sussman.
Checkout this link. he overides the IsAccessibleToUser property on the SiteMapprovider to selectivly show nodes based on the role of the current user. you caould change the condiftion to suit your needs.

Resources