How to retrieve custom settings from web.config - asp.net

I have a web.config with some Custom Settings in it(not in appsettings) which look like this:
<ldapSettings>
<add key="server" value="xxxxxx"/>
<add key="portNumber" value="28400"/>
<add key="protocolVersion" value="3"/>
<add key="secure" value="true"/>
</ldapSettings>
How can I use the server address for my code?
I tried following
dim pfad As String
pfad = System.Configuration.ConfigurationManager.GetSection("ldapSettings")
Dim blas As String
blas =pfad["server"]
But it doesn't work. What am I missing?

You need to cast the return value of GetSection("ldapSettings") because it does not return string:
Dim ldap As ldapSettings = CType(ConfigurationManager.GetSection("ldapSettings"), ldapSettings)
Dim server As String = ldapSettings.server

First of all, you will need to define a class for your custom configuration section in order to tell ASP.NET what properties it has, like so:
Public Class ldapSettings
Inherits ConfigurationSection
Private Shared LSettings As ldapSettings = TryCast(ConfigurationManager.GetSection("ldapSettings"), ldapSettings)
Public Shared ReadOnly Property Settings() As ldapSettings
Get
Return LSettings
End Get
End Property
<ConfigurationProperty("server")>
Public Property Server() As String
Get
Return Me("server")
End Get
Set(value As String)
Me("server") = value
End Set
End Property
<ConfigurationProperty("portNumber")>
Public Property PortNumber() As String
Get
Return Me("portNumber")
End Get
Set(value As String)
Me("portNumber") = value
End Set
End Property
<ConfigurationProperty("protocolVersion")>
Public Property ProtocolVersion() As String
Get
Return Me("protocolVersion")
End Get
Set(value As String)
Me("protocolVersion") = value
End Set
End Property
<ConfigurationProperty("secure")>
Public Property Secure() As Boolean
Get
Return Me("secure")
End Get
Set(value As Boolean)
Me("secure") = value
End Set
End Property
End Class
Then, you will need to change your web.config file slightly. The XML layout of the custom section should look like this instead:
<configSections>
<section name="ldapSettings" type="Your_Assembly_Name.ldapSettings"/>
</configSections>
<ldapSettings
server="xxxxxx"
portNumber="28400"
protocolVersion="3"
secure="true"
/>
And then finally, you can get a setting using the following line:
Dim Secure As Boolean = ldapSettings.Settings.Secure
Sorry about the VB.NET, you can use this tool to convert if you need to: http://www.developerfusion.com/tools/convert/csharp-to-vb/
Info mainly sourced from here:
http://haacked.com/archive/2007/03/11/custom-configuration-sections-in-3-easy-steps.aspx

I found out a much simpler solution
here is what i did:
Private config As NameValueCollection
config = DirectCast(ConfigurationManager.GetSection("ldapSettings"), NameValueCollection)
Dim server As String
server = config.[Get]("server")

ConfigurationManager.AppSettings("keyname")
usually works for me

You can get help from following link
http://msdn.microsoft.com/en-us/library/610xe886%28v=vs.80%29.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1

Related

Custom HTTPHandler is not getting called

I'm trying to make a HTTPHandler that will authenticate certain static resources, PDF Files in this case.
I've added the following to my web.config:
<configuration>
<system.web>
<httpHandlers>
<clear />
<add path="*.pdf" verb="*" validate="true" type="AuthenticatedStaticResourceHandler" />
</httpHandlers>
</system.web>
</configuration>
Here's my HTTPHandler class:
Imports Microsoft.VisualBasic
Public Class AuthenticatedStaticResourceHandler
Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim resource As String = String.Empty
Select Case context.Request.HttpMethod
Case "GET"
resource = context.Server.MapPath(context.Request.FilePath)
If Helpers.User.CanAccessPath(context.Request.FilePath, context.User.Identity.Name) Then
SendContentTypeAndFile(context, resource)
Else
FormsAuthentication.RedirectToLoginPage()
End If
End Select
End Sub
Public ReadOnly Property IsReusable As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
Private Function SendContentTypeAndFile(ByVal context As HttpContext, ByVal file As String) As HttpContext
context.Response.ContentType = GetContentType(file)
context.Response.TransmitFile(file)
context.Response.End()
Return context
End Function
Private Function GetContentType(ByVal filename As String) As String
'Used to set the encoding for the reponse stream
Dim resource As String = String.Empty
Dim file As System.IO.FileInfo = New System.IO.FileInfo(filename)
If file.Exists Then
Select Case file.Extension.Remove(0, 1).ToLower()
Case "pdf"
resource = "application/pdf"
Case "jpg"
resource = "image/jpg"
Case "gif"
resource = "image/gif"
Case "png"
resource = "image/png"
Case "css"
resource = "text/css"
Case "js"
resource = "text/javascript"
Case Else
resource = String.Empty
End Select
End If
Return IIf(resource.Length > 0, resource, Nothing)
End Function
End Class
I've set a breakpoint on the Select Case context.Request.HttpMethod line in ProcessRequest, however when I try to access http://localhost/subfolder/subfolder/some.pdf the breakpoint is not triggered. Further, the example PDF I'm attempting to access is buried in a folder that I should not have access to, yet the PDF is served.
This leads me to believe that my HTTPHandler is not being called.
Am I missing something? What am I doing incorrectly?
Most likely, you have to add one extra part to your web.config to support all versions of IIS.
For IIS7 and higher, you need to register your handler in the system.webServer section:
<system.webServer>
<handlers>
<add ... />
</handlers>
</system.webServer>

Can i use a single session variable to store all the field values

I have 9 pages with 10 fields in each page. Can i use a single session variable to store all the field(textbox,drop downlist,radiobuttons) values of 9 pages? If so could you give me small example inorder to proceed. Im kind of stuck.
Could you? Yes. Should you? Most likely not - though I can't say for sure without understanding what problem you are intending to solve.
Update with one sample solution
OK, I'm going to assume you want to store the values from the controls and not the controls themselves. If so, the easiest solution is stuff them in using some meaningful token to separate them. Like:
Session("MyControlValueList") = "name='txt1',value='hello'|name='txt2', value'world'"
To retrieve you would split them into a string array:
myArray = Session("MyControlValueList").Split("|")
And then iterate through to find the control/value you want.
So strictly speaking that's an answer. I still question whether it is the best answer for your particular scenario. Unfortunately I can't judge that until you provide more information.
Create a custom class with all the fields you want to save, then populate an instance of that and save that instance as a session variable.
I have something similar, but not identical - I'm saving various shipping address fields for an order, and I'm allowing the admins to update the order, either the shipping information or the order line items. Since that information is kept on separate tables, I store the shipping information in a session variable, and then compare it to what's on the form when they hit the "Update" button. If nothing has changed, I skip the update routine on the SQL Server database.
The easiest way for me to do this was to create a "OrderInfo" class. I saved the shipping information to this class, then saved that class to a session variable. Here's the code showing the class -
Public Class OrderInfo
Private v_shipname As String
Private v_add1 As String
Private v_add2 As String
Private v_city As String
Private v_state As String
Private v_zipcd As String
Private v_dateneeded As Date
Private v_billingmeth As Integer
Public Property ShipName() As String
Get
Return v_shipname
End Get
Set(value As String)
v_shipname = value
End Set
End Property
Public Property Add1() As String
Get
Return v_add1
End Get
Set(value As String)
v_add1 = value
End Set
End Property
Public Property Add2() As String
Get
Return v_add2
End Get
Set(value As String)
v_add2 = value
End Set
End Property
Public Property City() As String
Get
Return v_city
End Get
Set(value As String)
v_city = value
End Set
End Property
Public Property State() As String
Get
Return v_state
End Get
Set(value As String)
v_state = value
End Set
End Property
Public Property ZipCd() As String
Get
Return v_zipcd
End Get
Set(value As String)
v_zipcd = value
End Set
End Property
Public Property DateNeeded() As Date
Get
Return v_dateneeded
End Get
Set(value As Date)
v_dateneeded = value
End Set
End Property
Public Property BillingMeth() As Integer
Get
Return v_billingmeth
End Get
Set(value As Integer)
v_billingmeth = value
End Set
End Property
End Class
Here's the code for when I tested the concept to see if I could store a custom class in a session variable. This routine gets the order record, populates the fields in an instance of the custom class, and on the web form, as well. I save that instance to a session variable, then I initialize another new instance of that custom class, load the session variable to it. I then display the field values from the "retrieved" custom class, and what showed on the label matched what it should be -
Protected Sub LoadOrderInfo(ByVal ordID As Integer)
Dim connSQL As New SqlConnection
connSQL.ConnectionString = ConfigurationManager.ConnectionStrings("sqlConnectionString").ToString
Dim strProcName As String = "uspGetOrderInfoGeneral"
Dim cmd As New SqlCommand(strProcName, connSQL)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("OrderID", ordID)
If connSQL.State <> ConnectionState.Open Then
cmd.Connection.Open()
End If
Dim drOrderInfo As SqlDataReader
drOrderInfo = cmd.ExecuteReader
If drOrderInfo.Read Then
Dim orgOrder As New OrderInfo
orgOrder.ShipName = drOrderInfo("shipName")
orgOrder.Add1 = drOrderInfo("ShipAdd1")
orgOrder.Add2 = drOrderInfo("ShipAdd2")
orgOrder.City = drOrderInfo("ShipCity")
orgOrder.State = drOrderInfo("ShipState")
orgOrder.ZipCd = drOrderInfo("ShipZip")
orgOrder.DateNeeded = drOrderInfo("DateNeeded")
orgOrder.BillingMeth = drOrderInfo("BillingMethodID")
If Session.Item("orgOrder") Is Nothing Then
Session.Add("orgOrder", orgOrder)
Else
Session.Item("orgOrder") = orgOrder
End If
' I could just as easily populate the form from the class instance here
txtShipName.Text = drOrderInfo("shipName")
txtAdd1.Text = drOrderInfo("ShipAdd1")
txtAdd2.Text = drOrderInfo("ShipAdd2")
txtCity.Text = drOrderInfo("ShipCity")
txtState.Text = drOrderInfo("ShipState")
txtZipCd.Text = drOrderInfo("ShipZip")
selDate.Value = drOrderInfo("DateNeeded")
ddlBillMeth.SelectedValue = drOrderInfo("BillingMethodID")
End If
cmd.Connection.Close()
Dim retOrder As New OrderInfo
retOrder = Session.Item("orgOrder")
lblWelcomeMssg.Text = retOrder.ShipName & ", " & retOrder.Add1 & ", " & retOrder.City & ", " & retOrder.DateNeeded.ToShortDateString & ", " & retOrder.BillingMeth.ToString
End Sub
This might not be practical or desirable, given the number of fields you are trying to hold onto that way, but I'm not here to judge, so this is one possibility. I've worked with other projects where you create a table, and save that table as a session variable, so whatever structure you put into an object is retained if you save that object as a session variable.

ASP.net 2010 (VB) Object reference not set to an instance of an object

Morning All,
I am using VS2010 with VB and im trying to get a ping test working in my web application. In order to do this and test that it works i have simply created a button that when clicks should ping a specified IP address.
I believe that the code for the button should work fine. The only issue i have is the following error message on my web page...
System.NullReferenceException: Object reference not set to an instance of an object.
It bugs on the cole line...
Console.WriteLine("Address: {0}", vPingReply.Address)
I thought that this was due to 'Properties' needing to be set up for the .Address and .Status objects. Im not too sure if i have added these correctly as i have added some properties but i still have the same issue when i run the page?
Can someone please take a look and advise?
Here is my full code...
Imports Microsoft.VisualBasic
Imports System.Text
Imports System.Net.NetworkInformation
Imports System.Net.NetworkInformation.PingReply
Partial Class Ping
Inherits System.Web.UI.Page
Private mSend As PingReply
Private Property Send(p1 As String) As PingReply
Get
Return mSend
End Get
Set(value As PingReply)
mSend = value
End Set
End Property
Private mAddress As PingReply
Private Property Address(p2 As String) As PingReply
Get
Return mAddress
End Get
Set(value As PingReply)
mAddress = value
End Set
End Property
Private mStatus As PingReply
Private Property Status(p3 As String) As PingReply
Get
Return mStatus
End Get
Set(value As PingReply)
mStatus = value
End Set
End Property
Protected Sub btnPing_Click(sender As Object, e As System.EventArgs) Handles btnPing.Click
Dim vPing As New Ping
Dim vPingReply As PingReply = vPing.Send("xxx.xx.xxx.xx")
Console.WriteLine("Address: {0}", vPingReply.Address)
Console.WriteLine("Status: {0}", vPingReply.Status)
End Sub
End Class
Any help is much appriechiated.
Betty.
You cannot access the content of Address property if the Status is not Success
Dim vPing As New Ping
Dim vPingReply As PingReply = vPing.Send("xxx.xx.xxx.xx")
if vPingReply.Status = IPStatus.Success Then
Console.WriteLine("Address: {0}", vPingReply.Address)
End If
Console.WriteLine("Status: {0}", vPingReply.Status)
The docs says
If the value of Status is not Success, you should not use the values
returned by the RoundtripTime, Options or Buffer properties. The
RoundtripTime property will return zero, the Buffer property will
return an empty array, and the Options property will return null.
but I found that the Address property is null (Nothing in VB) also if the Send is for a non-existant ip address or DNS name
However, looking better at your code, it is clear that all the calls made inside the btnPing_Click method are handled by your class Ping not to the framework class Ping. And your class uses variables not correctly initialized. I suggest to remove those methods from your class or just rename the class with something different.
Another option (not recommended) is this
Private Property Send(p1 As String) As PingReply
Get
' Specify the full namespace to remove ambiguity between this class and framework class
Dim p = new System.Net.NetworkInformation.Ping()
mSend = p.Send(p1)
Return mSend
End Get
Set(value As PingReply)
mSend = value
End Set
End Property
Private Property Address() As String
Get
if mSend IsNot Nothing Then
Return mSend.Address
else
Return string.Empty
End If
End Get
' Meaningless ???
'Set(value As PingReply)
' mAddress = value
'End Set
End Property
Private mStatus As PingReply
Private Property Status() As String
Get
if mSend IsNot Nothing Then
Return mSend.Status.ToString()
else
Return string.Empty
End If
End Get
' Meaningless ???
'Set(value As PingReply)
' mStatus = value
'End Set
End Property

Connect reusable ASP.NET WebControl to a method for loading data

I'm trying to create a control that can extend other webcontrols and set some properties like visible and enabled, based on user permissions.
Here's an example where your user role would need to include the "CanSave" permission:
<asp:Button ID="btn1" runat="server" Text="Save"/>
<myControls:PermissionsExtender runat="server" ControlToSet="btn1" Permission="CanSave"/>
I'm trying to keep this reusable, that's why the PermissionExtender is in a separate project that can not have any dependencies to other projects. To make a decision, the control of course needs to get this info from somewhere else (database or something). I made another control and, using events, the above extender will be set by a master control, so only that needs to know where to look up the information.
The master control now needs to be configured to know where the information about roles and permissions will be coming from. My idea was to have an interface inside the reusable project, and implement that somewhere else, then configure my control to go and find the class that implements the method I need and load it through reflection. But I'm unclear how this could work. I would probably place the master control in the masterpage and supply it a class name like PermissionClass="SecurityLibrary.PermissionsClass". Kinda like ObjectDatasource does it, but other suggestions are welcome.
The method signature would be like:
bool HasPermission(string permission)
It would know the current users role and using that combination, looks up if the role includes the permission.
How can I wire up a call from the control to a method inside my main project that can supply the necessary information without making them dependent.
I think I've got something that will work for you (tested fine for me but I may have misunderstood part of what you were looking for). With this implementation the asp.net designer code will look like this:
<web:PermissionMasterControl runat="server" ID="masterController" PermissionClass="SecurityLibrary.RandomPermissionClass" />
<asp:Button ID="btnSave" runat="server" Text="save" />
<web:PermissionExtender runat="server" ControlToSet="btnSave" Permission="CanSave" MasterControllerID="masterController" />
Now for the SecurityLibrary. Pretty straight forward, I included a simple "RandomPermissionClass" that randomly returns true/false.
Namespace SecurityLibrary
Public MustInherit Class PermissionClass
Public MustOverride Function HasPermission(ByVal permission As String) As Boolean
End Class
Public Class RandomPermissionClass
Inherits PermissionClass
Private rand As New Random()
Public Overrides Function HasPermission(permission As String) As Boolean
Return If(rand.Next(2) = 0, False, True)
End Function
End Class
End Namespace
Now we have the "myControls" library, which contains no references to SecurityLibrary. I created two controls and a delegate. The controls are "PermissionMasterControl" and "PermissionExtender". The delegate is what is used to actually perform the check against the reflected object.
Namespace myControls
Public Delegate Function HasPermissionDelegate(ByVal permission As String) As Boolean
Public Class PermissionMasterControl
Inherits System.Web.UI.Control
Public Property PermissionClass As String
Get
Return If(ViewState("PermissionClass") Is Nothing, "", ViewState("PermissionClass").ToString())
End Get
Set(value As String)
ViewState("PermissionClass") = value
End Set
End Property
Private ReadOnly Property PermissionDelegate As HasPermissionDelegate
Get
If _permissionDel Is Nothing Then
If Not String.IsNullOrEmpty(PermissionClass) Then
Dim t = Type.GetType(PermissionClass, False)
If t IsNot Nothing Then
_permissionObj = Activator.CreateInstance(t)
Dim mi As MethodInfo = _
t.GetMethod("HasPermission", BindingFlags.Public Or BindingFlags.Instance)
_permissionDel = [Delegate].CreateDelegate(GetType(HasPermissionDelegate), _permissionObj, mi)
End If
End If
End If
Return _permissionDel
End Get
End Property
Private _permissionObj As Object = Nothing
Private _permissionDel As HasPermissionDelegate = Nothing
Public Function HasPermission(ByVal permission As String) As Boolean
If PermissionDelegate Is Nothing Then
Throw New NullReferenceException("The specified permission class (" + PermissionClass + ") could not be loaded/found.")
End If
Return PermissionDelegate(permission)
End Function
End Class
Public Class PermissionExtender
Inherits System.Web.UI.Control
Public Property ControlToSet As String
Get
Return If(ViewState("ControlToSet") Is Nothing, "", ViewState("ControlToSet").ToString())
End Get
Set(value As String)
ViewState("ControlToSet") = value
End Set
End Property
Public Property Permission As String
Get
Return If(ViewState("Permission") Is Nothing, "", ViewState("Permission").ToString())
End Get
Set(value As String)
ViewState("Permission") = value
End Set
End Property
Public Property MasterControllerID As String
Get
Return If(ViewState("MasterControllerID") Is Nothing, "", ViewState("MasterControllerID").ToString())
End Get
Set(value As String)
ViewState("MasterControllerID") = value
End Set
End Property
Protected ReadOnly Property MasterController As PermissionMasterControl
Get
If _mastercontroller Is Nothing Then
_mastercontroller = Me.Page.FindControl(MasterControllerID)
End If
Return _mastercontroller
End Get
End Property
Protected ReadOnly Property ManagedControl As Control
Get
If _controlToSet Is Nothing Then
_controlToSet = Me.NamingContainer.FindControl(ControlToSet)
End If
Return _controlToSet
End Get
End Property
Private _controlToSet As Control = Nothing
Private _mastercontroller As PermissionMasterControl = Nothing
Protected Overrides Sub OnLoad(e As System.EventArgs)
MyBase.OnLoad(e)
Dim bResult As Boolean = MasterController.HasPermission(Permission)
ManagedControl.Visible = bResult
End Sub
End Class
End Namespace

MembershipProvider and RequiresQuestionAndAnswer

We provide a website template for our customers to use as the basis of their websites. Our website has a custom membership provider.
We have had a problem raised by one customer. The customer sends out invitations to prospective members by email with a url to login the member. During registration they set their security question / answer.
However sometimes the prospective member loses the email (and therefore their password) but still tries to join the site.
The customer requested that the member be allowed to reset their password without the usual security question / answer when registration was not complete.
Unfortunately the MembershipProvider doesn't provide the username when requesting whether the question / answer are required. However it does call GetUser() just before.
To get this feature working I added a method (StartingPasswordRecovery) to my MembershipProvider to flag that password reset was active, calling it from the OnVerifyingUser event in the PasswordRecovery page.
While this code works I'm not convinced that it's very robust.
Can anyone point me towards a better solution.
Here's the relevant code I added to my membership provider.
Private _hasUserDefinedQuestionAndAnswer As Boolean
Private _isResettingPassword As Boolean
Public Overloads Overrides Function GetUser(ByVal username As String, ByVal userIsOnline As Boolean) As System.Web.Security.MembershipUser
...
_hasUserDefinedQuestionAndAnswer = ...
...
End Function
Public Overrides ReadOnly Property RequiresQuestionAndAnswer() As Boolean
Get
If Me._isResettingPassword Then
Me._isResettingPassword = False
Return Me.pRequiresQuestionAndAnswer And Me._hasUserDefinedQuestionAndAnswer
End If
Return Me.pRequiresQuestionAndAnswer
End Get
End Property
Public Sub StartingPasswordRecovery()
Me._isResettingPassword = True
End Sub
I'm not sure if i've understood you correctly, but couldn't you use the User-Profile to determine if a user requires question and answer or not?
web.config:
<profile defaultProvider="YourProfileProvider">
<providers>
<clear/>
<add name="YourProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ConnectionStringToDB" applicationName="/YourApp"></add>
</providers>
<properties>
<add name="RequiresQuestionAndAnswer" defaultValue="false" />
</properties>
</profile>
Custom membership-provider:
Public Overrides ReadOnly Property RequiresQuestionAndAnswer As Boolean
Get
If HttpContext.Current.User.Identity.IsAuthenticated Then
Dim userRequiresQuestionAndAnswer = _
CType(HttpContext.Current.Profile.GetPropertyValue("RequiresQuestionAndAnswer"), Boolean)
Return userRequiresQuestionAndAnswer
Else
Return MyBase.RequiresQuestionAndAnswer
End If
End Get
End Property
You could set it in your user-management page for every user individually:
HttpContext.Current.Profile.SetPropertyValue("RequiresQuestionAndAnswer", userRequiresQuestionAndAnswer)
HttpContext.Current.Profile.Save()
Edit:
according to your comment, i've modified the code a little bit. I hope that helps to get it working:
in custom membership-provider:
Public Overloads Overrides ReadOnly Property RequiresQuestionAndAnswer As Boolean
Get
If HttpContext.Current.User.Identity.IsAuthenticated Then
Return RequiresQuestionAndAnswer(Membership.GetUser.UserName)
Else
Return MyBase.RequiresQuestionAndAnswer
End If
End Get
End Property
Public Overloads ReadOnly Property RequiresQuestionAndAnswer(ByVal userName As String) As Boolean
Get
Dim profile As ProfileBase = ProfileBase.Create(userName)
If Not profile Is Nothing Then
Dim userRequiresQuestionAndAnswer = _
CType(profile.GetPropertyValue("RequiresQuestionAndAnswer"), Boolean)
Return userRequiresQuestionAndAnswer
Else
Return MyBase.RequiresQuestionAndAnswer
End If
End Get
End Property
where your PasswordRecovery-Control is:
Protected Sub VerifyingUser(ByVal sender As Object, ByVal e As LoginCancelEventArgs)
Dim login As WebControls.Login = DirectCast(Me.LoginView1.FindControl("Login1"), WebControls.Login)
Dim userName = DirectCast(login.FindControl("PwdRecovery"), PasswordRecovery).UserName
Dim RequiresQuestionAndAnswer = DirectCast(Membership.Provider, YourMembershipProvider).RequiresQuestionAndAnswer(userName)
'....'
End Sub

Resources