External Control of system or config setting - asp.net

What is the alternative option to pass the connection string in below vb code to get rid of external Control of system setting
Protected ConnectString As String
ConnectString = Session ("Oracle_ConnectString").ToString()
Dim OracleConnection_A As New Oracle.DataAccess.Client.OracleConnection(ConnectString)
It says never allow untrusted data and validate untrusted input using central data validation to fix the flaw.. please guide to fix this error
Thanks

As a general rule, for desktop or web, we always used the project property->settings, and used this:
I WOULD NOT use session() as that can be rather flakey.
Any setting you use above? Well, now you can use either the configeration manager, or just use the built in class that VS generates for you!!!
So in code, use the settings class (which is automatic created for you).
Then your code to say load up a grid would look like this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid
End If
End Sub
Sub LoadGrid()
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand("SELECT * FROM Fighters", conn)
conn.Open()
Dim rstData = New DataTable
rstData.Load(cmdSQL.ExecuteReader)
GridView1.DataSource = rstData
GridView1.DataBind()
End Using
End Using
End Sub
So, I used the My.Settings for this.
And if you look, that setting is shoved into web.config for you.
And REALLY nice is that project settings has a connection string wizard/builder that you can use - so no need to build + create the connection string - VS will do all the dirty work for you.
And, if you want, I suppose you can use the confirmation manager.
So, in the code you have "Imports System.Configuration"
So now this:
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand("SELECT * FROM Fighters", conn)
can be this:
Using conn As New SqlConnection(ConfigurationManager.ConnectionStrings("TEST4").ConnectionString)
Using cmdSQL As New SqlCommand("SELECT * FROM Fighters", conn)
ETC.
So, you can manually enter the connection strings into the web.config, but I would suggest that using the My.Settings class (which is automatic built for you) is a far easier approach here. The nice part is the project->properties settings can also have simple number settings, tax rates - even the company name or whatever. Once again, this is really like app-settings in a desktop application. And while sometimes I don't like these obfuscated class systems? For application settings? I think it is a great idea, and better yet it means the years of doing this say for desktop applications now is exactly the same approach for web based applications.
but, no, I don't suggest using session() for connection strings - a bad idea, and bad place since session() can be lost quite easy - especially if you using memory based vs sql server based ones.

Related

Making use of service references in vb.net

I've been trying to make use of this API in order to create a small app that will be run at a set interval in order to monitor a value. I've been told to do it in vb.net using service references and have so far managed to make use of the method that returns the last publication time, but when I try to retrieve the actual information from the table I receive an error:
"Exception: Compression is Not Enabled,This Web Service expects
clients to support GZIP,Deflate Compression"
So far i've been finding it difficult to find any info that is applicable to my current setup so i'm not sure how to progress. Is there anything i'm missing or any resources that would help me get my head around this?
Here is the current code i'm using to get the values.
Private Sub Soap(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim svc As New FlowInfo.InstantaneousFlowWebServiceSoapClient()
Dim str As String = svc.GetLatestPublicationTime().ToString
MessageBox.Show(str)
Dim body As FlowInfo.EDPReportBE = svc.GetInstantaneousFlowData()
End Sub

Is there any other way to store data from database, other than using dataset or datatable in ASP.NET?

Like the title suggest, I would like to ask, is there any other way to store data from database, other than using dataset or datatable in ASP.NET?
I'm currently using something like this:
Public Function openDataTable(ByVal query As String) As DataTable
Try
If con.State <> ConnectionState.Closed Then con.Close()
con.Open()
dt = New DataTable
adap = New SqlDataAdapter(query, con)
adap.Fill(dt)
con.Close()
Catch ex As Exception
MsgBox.Message)
End Try
Return dt
End Function
dt = conn.openDataTable("Select * From Employee")
It worked fine for me, but I would like to know, is there any other way to do it?
And if there is another way, would someone be so kind as to give me an example? Thanks.
In .net framework 3.5 and above you can use linq with entity framework.
Start here:
Getting Started with LINQ in C#
Entity Framework
A very good Entity framework Tutorial: http://www.codeproject.com/Articles/363040/An-Introduction-to-Entity-Framework-for-Absolute-B
Introduction to LINQ: http://msdn.microsoft.com/en-us/library/bb397897.aspx
Getting Started with LINQ in Visual Basic
Yes. You could:
Run SQL Statements directly
Use Linq to SQL
Use Entity Framework

SqlDataSource reuse on different pages

I am using ASP.NET. I have a ReportPage1 and ReportOutputPage1. These are different aspx files and has different MasterPages. However, I need the same SqlDataSource object to use on both pages. On ReportPage I need SqlDataSource to call StoredProcedure and import data to CSV file, but on ReportOutputPage I need to use SqlDataSource to call the same StoredProcedure and populate GridView.
ReportPage1 is "main" page - a button click from this page opens ReportOutputPage1 and displays it in new window. ReportPage is PreviousPage for ReportOutputPage1.
Above is example for Report1. The same idea is for Report2 (with SqlDataSource2) and for Report3 (SqlDataSource3) etc. - 10 different reports.
How to reuse SqlDataSource for every two pages (ReportPage & ReportOutputPage)?
First suggestion I found in web - using masterpage for both ReportPage and ReportOutputPage. This doesn't work, as I have already have different masterpages for ReportPage and ReportOutputPage, as well as then I need to create 10 different MasterPages for each Report.
Second suggestion was to define SqlDataSource on ReportPage and then reuse it using PrevousePage on ReportOutputPage, but this doesn't work for my special case (I am using Ajax staff and Partial page postbacks and I am loosing PreviousPage, also SqlDataSource could not be serialized to save it in ViewState or similar).
Create UserControl. Probably this could work, but it is time consuming to create UserControl every time for new Report (10 reports - 10 usercontrols?).
Simply Copy & Paste SqlDataSource (I did it for one Report) could work, but I would like something more like code reuse. Someone could simply forget to modify SqlDataSource in two different places if necessary.
Can you, please, give me some suggestions how to reuse code (particularly, SqlDataSource) for Report & ReportOutput pages?
Could you define the need for using the same SqlDataSource? If they are two different pages and it sounds like two different uses why not use two different SqlDataSource? The pages are separate anyhow, your not going to be able to share an object on one with the other.
I would suggest you look at adding a data layer to your application for database interaction and binding your data to the datagrid at request time. That way you build your database interaction once and reuse that over different pages.
The other option is you simply use two SqlDataSources and copy/paste them to both the pages. If your trying to make a selection or some sort of criteria apply to your second page then consider using query strings and QueryStringParameters in your SqlDataSource.
Hope this helps.
Edit: Pop this in App_Code somewhere, pass in your specific usage requirements.
Public Shared Function GetData(connString As String, command As String, Optional params As SqlParameter() = Nothing) As DataTable
Dim conn As New SqlConnection(connString)
Dim da As New SqlDataAdapter(command, conn)
Dim dt As New DataTable
da.SelectCommand.CommandType = CommandType.StoredProcedure
da.SelectCommand.CommandTimeout = 6000 '6 seconds.
If Not IsNothing(params) Then
For Each p As SqlParameter In params
da.SelectCommand.Parameters.Add(p)
Next
End If
Try
conn.Open()
da.Fill(dt)
Return dt
Catch ex As Exception
Throw ex
Finally
conn.Close()
End Try
End Function
Then bind the datatable to your gridview, not sure how your outputing to file.
Private Sub BindData(gridview As GridView, data As DataTable)
gridview.DataSource = data
End Sub
You can now re-use the database interaction from the code behind:
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
BindData(MyGridView,GetData(ConnectionStrings(connName).ConnectionString, _
"dbo.SomeSprocOrOther", _
New SqlParameter(){New SqlParameter("paramName","paramValue")})
End Sub

Sqlcommand are old fashion new one is Dataset

I wrote this type of command for my application.BUT my lecturer told me those things are Old fashion,USE new things like DATASET.. I wanted to know you guys is that correct ? Those kind of thigs are outdated ? Date Set is new way to do this ?
protected void btn_edit_Click(object sender, EventArgs e)
{
using(SqlConnection con = new SqlConnection(CONN_STR))
{
con.Open();
using(SqlCommand cmd = new SqlCommand("UPDATE tbl_BinCardManager SET ItemName = #ItemName WHERE ItemNo = #ItemNo"), con)
{
// TODO: fill in param values with real values
cmd.Parameters.AddWithValue("#ItemName", "my item name");
cmd.Parameters.AddWithValue("#ItemNo", 1);
cmd.ExecuteNonQuery();
}
}
}
The classes you are using are the nuts and bolts of pretty much all data access technologies in .NET. There are abstractions around it such as DataSets, LINQ to SQL, Entity Framework, etc. But in the end they all use SqlConnection and friends.
In fact, of the 3 technologies I mentioned, DataSets are the ones that have been largely discarded and have little or no support outside of the .NET 2.0-era tooling.
DataSet used DataReader internally to populate date. Also dataset works in disconnected mode, but your code is not outdated by any means.
Your teacher is may be talking about using ORM.
NO, your code is not at all Old fashioned..its perfectly simple for your requirement.
use DATASET when its really needed.. like, when you want to take some data offline, and modify it and again reflect back the changes to database..
In fact SqlCommand command is not an alternative for DATASET..
DATASET is something which can hold tables retrieved from database or locally created..
SqlCommand is something which helps you get/insert/update data from/to database table
even if you are using DATASET you still need SqlCommand.. then there is no question of Sqlcommand being oldfashioned and Dataset being the new one

Sql data reader in classes

Hi
On several pages of our website, I want to check if the currently logged in user has accepted our terms and conditions in the past. This boolean value is stored in the application database. Rather than creating a sql data reader afresh on each relevant page, I thought I could put it in a class and then assign the true/false to a variable. This is what I have so far and it does exactly what I want it to:
Public Shared ReadOnly Property termsCompleted As String
Get
Dim selectTerms As String = "SELECT Terms FROM tblPersonal WHERE Ref=#Ref"
Dim dbconn As String = ConfigurationManager.ConnectionStrings("ApplicationServices").ConnectionString
Using myConnection As New SqlConnection(dbconn)
myConnection.Open()
Dim cmdTerms As New SqlCommand(selectTerms, myConnection)
cmdTerms.Parameters.AddWithValue("#Ref", myUser.ToString())
Dim readerTerms As SqlDataReader = cmdTerms.ExecuteReader()
readerTerms.Read()
termsCompleted = readerTerms.Item(0)
readerTerms.Close()
myConnection.Close()
End Using
End Get
End Property
I am them using the following on each page that is relevant to deny access and redirect (in the page_load):
If Variables.termsCompleted = False Then
Response.Redirect("Terms.aspx")
End If
While this works ok, i'm interested in how secure it is, and is there a better way to do this?
Thanks
Have you considered retrieving the information once during Session_Start, and carrying it around in Session so that you can interrogate it any time you want?
If you can't retrieve the data during authentication/authorization, you would retrieve the data in the same way as you show above.
To put the value into Session: Session["termsCompleted"] = "true";
To read the value from Session: if (Session["termsCompleted"] == "true")....
As an alternative, you could add the information to HttpContext.Current.User.
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs when a new session is started
Dim selectTerms As String = "SELECT Terms FROM tblPersonal WHERE Ref=#Ref"
If Request.IsAuthenticated = True Then
Dim dbconn As String = ConfigurationManager.ConnectionStrings("ApplicationServices").ConnectionString
Using myConnection As New SqlConnection(dbconn)
myConnection.Open()
Dim cmdTerms As New SqlCommand(selectTerms, myConnection)
cmdTerms.Parameters.AddWithValue("#Ref", Variables.myUser)
Dim readerTerms As SqlDataReader = cmdTerms.ExecuteReader()
readerTerms.Read()
Session("termsCompleted") = readerTerms.Item(0)
readerTerms.Close()
myConnection.Close()
End Using
End If
End Sub
And in the code-behind:
If Session("termsCompleted") = False Then
Response.Redirect("Terms.aspx")
End If
Unfortunately this is redirecting to the terms.aspx page every time regardless of what is in the database. From debugging it's picking up the reader item as 'False' even when it's true..
Thanks
Create a base page and have each page inherit from that. In this base page you can do the data access once to perform this check. Then store it in session state.
I don't think you have a security issue...I think it's more of a best practice issue. It's not good practice to put your data access requests in a property. In projects I work on, I typically will have a class that has functions that handle my data access with a buisiness layer that makes the calls to my data access. An n-tier project design may not fit your project...I'm just speaking from my experience.
If you need to reuse the bit flag, just store it in Session.
This logic doesn't really belong on a page. If accepting the terms of use is a requirement for accessing parts of your site then you should handle it that way. This problem is a very similar situation to having an administrator section of a site that only a few users can access.
Ideally this is something you would handle before the request gets to the page. There are (at least) two ways to approach this.
You could write a custom HTTP module that subscribes to the AuthorizeRequest event. It will check whether this page requires that you accept terms of agreement or not and if so checks to see if the user has or not. If not it will redirect the user to the terms of use page.
The other option is to put this code into your Global.ascx file. You would want to subscribe to the AuthorizeRequest event and perform your logic there.
I don't think it matters which option you chose (though the second one may be a little more straight forward to implement). The benefit is that this concern is handled outside of the page itself. This way as you add new pages to your site, you can't forget to add your validation code to it. If you ever decide that in addition to accepting terms of agreement users need to do something else, you now have one place to change instead of going through all of the pages, etc.
You should also take advice of some of the other answers and store this value into the Session to avoid having to to do a database request every time a page loads.
More information:
Http Modules and handlers
How To Create an ASP.NET HTTP Module Using Visual C# .NET (VB should be the same concept with VB syntax).
Application, Page and Control lifecycle (to help you better understand how ASP.NET application lifecycle works and what else is possible).

Resources