Session values in HttpContext.Current.Session in C# set and get - c#

I have static class called MailContainer in a MasterPage.
In MailContainer Class, I have defined properties for get /set like below.
public static class MailContainer
{
public static string TheObjectPropertyEmail
{
get
{
return HttpContext.Current.Session["TheObjectPropertyEmail"].ToString();
}
set
{
HttpContext.Current.Session["TheObjectPropertyEmail"] = value;
}
}
}
When I try to assign an value like below on Default.aspx.cs with MasterPage.
MailContainer.TheObjectPropertyEmail = reader["Email"].ToString();
Its throwing the below exception.
System.NullReferenceException: Object reference not set to an instance
of an object.
on this line :
return HttpContext.Current.Session["TheObjectPropertyEmail"].ToString();
How do i fix this ?
Edit #01
public void Aut()
{
sql = #String.Format(" SELECT * FROM doTable ");
sql += String.Format(" WHERE ");
sql += String.Format(" UPPER(user) IN (?); ");
using (OdbcConnection myConnectionString =
new OdbcConnection(ConfigurationManager.ConnectionStrings["ConnMySQL"].ConnectionString))
{
using (OdbcCommand command =
new OdbcCommand(sql, myConnectionString))
{
try
{
if (username != null)
{
command.Parameters.AddWithValue("param1", username.ToString().ToUpper());
command.Connection.Open();
using (OdbcDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
MailContainer.TheObjectPropertyEmail = reader["Email"].ToString();
}
}
}
}
}
catch (Exception ex)
{
throw new ApplicationException("operation failed!", ex);
}
finally
{
command.Connection.Close();
}
}
}
}

Check HttpContext here. This an HttpContext only available in web related projects like
WebForms for asp .net
WebApi
MVC
Now depending on the lifecycle, the HttpContext is or isn't initiallized. We need to know more about your specific exmample on when you call and set, get the session for us to help you.
Cheers!

Related

Update Collection Value with Database in UWP(MVVM)

I have custom collection which contains student_id,student_name,student_mark.And having the table with same columns in the database as well. The design form have some controls for updating the existing student.
Temporarily all the updating operations are done with that custom collection.Lets assume we have 100 students data in collection and database. Any updating operation should reflect in the collection. But what my doubt is how do i update these values with the database before i close the application??
But when i open the application the collection should have all the values which have stored in the database.
But what my doubt is how do i update these values with the database
Firstly, you need to know how to do CRUD operations on MySQL database with uwp app. For this, please reference this sample.
Secondly, according to your description, you have built up a MVVM project to bind a collection data to the view. But you didn't have a data layer for this MVVM structure. For this, you need to create a class for data layer to do GRUD operations, and establish contact with this data service from ViewModel. More details please reference this article.
The class for data layer I wrote according to your description which contains how to read, update and delete data from mysql database is as follows:
public class Student
{
public int Student_id { get; set; }
public string Student_name { get; set; }
public string Student_mark { get; set; }
}
public class DataService
{
static string connectionString;
public static String Name = "Data Service.";
private static ObservableCollection<Student> _allStudents = new ObservableCollection<Student>();
public static ObservableCollection<Student> GetStudents()
{
try
{
string server = "127.0.0.1";
string database = "sakila";
string user = "root";
string pswd = "!QAZ2wsx";
connectionString = "Server = " + server + ";database = " + database + ";uid = " + user + ";password = " + pswd + ";SslMode=None;";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
MySqlCommand getCommand = connection.CreateCommand();
getCommand.CommandText = "SELECT * FROM student";
using (MySqlDataReader reader = getCommand.ExecuteReader())
{
while (reader.Read())
{
_allStudents.Add(new Student() { Student_id = reader.GetInt32(0), Student_name = reader.GetString(1), Student_mark = reader.GetString(2) });
}
}
}
}
catch (MySqlException sqlex)
{
// Handle it :)
}
return _allStudents;
}
public static bool InsertNewStudent(Student newStudent)
{
// Insert to the collection and update DB
try
{
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
MySqlCommand insertCommand = connection.CreateCommand();
insertCommand.CommandText = "INSERT INTO student(student_id, student_name, student_mark)VALUES(#student_id, #student_name,#student_mark)";
insertCommand.Parameters.AddWithValue("#student_id", newStudent.Student_id);
insertCommand.Parameters.AddWithValue("#student_name", newStudent.Student_name);
insertCommand.Parameters.AddWithValue("#student_mark", newStudent.Student_mark);
insertCommand.ExecuteNonQuery();
return true;
}
}
catch (MySqlException sqlex)
{
return false;
}
}
public static bool UpdateStudent(Student Student)
{
try
{
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
MySqlCommand insertCommand = connection.CreateCommand();
insertCommand.CommandText = "Update student Set student_name= #student_name, student_mark=#student_mark Where student_id =#student_id";
insertCommand.Parameters.AddWithValue("#student_id", Student.Student_id);
insertCommand.Parameters.AddWithValue("#student_name", Student.Student_name);
insertCommand.Parameters.AddWithValue("#student_mark", Student.Student_mark);
insertCommand.ExecuteNonQuery();
return true;
}
}
catch (MySqlException sqlex)
{
// Don't forget to handle it
return false;
}
}
public static bool Delete(Student Student)
{
try
{
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
MySqlCommand insertCommand = connection.CreateCommand();
insertCommand.CommandText = "Delete from sakila.student where student_id =#student_id";
insertCommand.Parameters.AddWithValue("#student_id", Student.Student_id);
insertCommand.ExecuteNonQuery();
return true;
}
}
catch (MySqlException sqlex)
{
return false;
}
}
}
For updating the database in TwoWay binding way, we can implement is by invoking the data updating method in
PropertyChanged event as follows:
void Person_OnNotifyPropertyChanged(Object sender, PropertyChangedEventArgs e)
{
organization.Update((StudentViewModel)sender);
}
For the completed demo you can download here.

System.TypeInitializationException when referencing dll

I'm trying to create a Data Framework in the form of a .dll so that I can reference it when creating new projects, as opposed to reinventing the wheel with each project I create.
I have an app.config in which I store my SQL connections, a class that uses the app.config to build my SQL ConnectionString (ConnectionStrings.cs) and a Logic class (Logic.cs) that'll build whatever objects I require from the SQL Server.
Here's the classes in the .dll:
ConnectionStrings.cs:
using System.Configuration;
using System.Data.SqlClient;
namespace DataFramework
{
public static class ConnectionStrings
{
static string _liveConnectionString = ConfigurationManager.ConnectionStrings["LiveDataSource"].ConnectionString;
static string _liveMISConnectionString = ConfigurationManager.ConnectionStrings["LiveDataSource_MIS"].ConnectionString;
static string _devConnectionString = ConfigurationManager.ConnectionStrings["DevDataSource"].ConnectionString;
static string _devMISConnectionString = ConfigurationManager.ConnectionStrings["DevDataSource_MIS"].ConnectionString;
public static SqlConnection CreateLiveConnection
{
get { return new SqlConnection(_liveConnectionString); }
}
public static SqlConnection CreateLiveMISConnection
{
get { return new SqlConnection(_liveMISConnectionString); }
}
public static SqlConnection CreateDevConnection
{
get { return new SqlConnection(_devConnectionString); }
}
public static SqlConnection CreateDevMISConnection
{
get { return new SqlConnection(_devMISConnectionString); }
}
}
}
Logic.cs:
using System;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace DataFramework
{
public class Logic
{
SqlConnection liveConnection = ConnectionStrings.CreateLiveMISConnection;
SqlConnection devMISConnection = ConnectionStrings.CreateDevMISConnection;
public bool IsConnecting { get; set; }
public string ConnectionMessage { get; set; }
public async Task<DataTable> ResultDataTable(bool connectToLive, string commandText, CommandType commandType)
{
DataTable dt = new DataTable();
using (SqlCommand command = new SqlCommand())
{
try
{
command.CommandType = commandType;
command.CommandTimeout = 360000000;
switch (connectToLive)
{
case true:
command.CommandText = commandText;
command.Connection = liveConnection;
if (liveConnection.State == ConnectionState.Connecting)
{
IsConnecting = true;
ConnectionMessage = "Connecting to Data Source...";
}
if (liveConnection.State != ConnectionState.Closed)
liveConnection.Close();
if (liveConnection.State != ConnectionState.Open)
{
liveConnection.Open();
IsConnecting = false;
ConnectionMessage = "";
}
break;
case false:
command.CommandType = commandType;
command.CommandText = "";
command.Connection = devMISConnection;
if (devMISConnection.State == ConnectionState.Connecting)
{
IsConnecting = true;
ConnectionMessage = commandText;
}
if (devMISConnection.State != ConnectionState.Closed)
devMISConnection.Close();
if (devMISConnection.State != ConnectionState.Open)
{
devMISConnection.Open();
IsConnecting = false;
ConnectionMessage = "";
}
break;
}
using (SqlDataReader reader = await command.ExecuteReaderAsync())
{
dt.Load(reader);
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message, "An Error Has Occured", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
}
finally
{
if (devMISConnection.State != ConnectionState.Closed)
devMISConnection.Close();
if (liveConnection.State != ConnectionState.Closed)
liveConnection.Close();
}
}
return dt;
}
}
}
I include this dll as a reference in the app that I'm writing:
using System.Data;
using System.Threading.Tasks;
using System.Windows.Forms;
using DataFramework;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
DataTable dt = new DataTable();
DataFramework.Logic logic = new Logic();
public Form1()
{
InitializeComponent();
}
private async void Form1_Load(object sender, EventArgs e)
{
dt = await Task.Run(() => logic.ResultDataTable(true, "SELECT * FROM MIS.dbo.ETL_Table", CommandType.StoredProcedure));
}
}
}
The code throws the exception here:
SqlConnection liveConnection = ConnectionStrings.CreateLiveMISConnection;
So why, when I'm initializing the class, do I get this issue?
When you reference a DLL (or project) from another project, the app.config from the top most project is used. So, if you have your DataFramework being called from your WinformsApp, then your WinformsApp needs to have the right config settings in it. By default, it will ignore any app.config in the DataFramework. A bit frustrating at times! Copy your settings from your DataFramework app.config in to the WinformsApp app.config and it will work.
Another unrelated observation is that you have the following:
"SELECT * FROM MIS.dbo.ETL_Table", CommandType.StoredProcedure
The command type should be text and not a stored procedure.

Best way to handle exception in ADO.Net repository pattern

i have design small repository pattern for ado.net. now i could not manage to handle exception proper way. i want to push error to calling environment if any occur. if no error occur then result set will be push to calling environment.
i have repository called AdoRepository which extend other repository classes like employee etc. we are calling employee repository function from mvc controller. so i want to push error to mvc controller from employee repository if any occur during data fetch, if no error occur then data will be sent to mvc controller. here is my full code. please have look and share the idea for best design. if possible paste rectified code here.
Base repository
public abstract class AdoRepository<T> where T : class
{
private SqlConnection _connection;
public virtual void Status(bool IsError, string strErrMsg)
{
}
public AdoRepository(string connectionString)
{
_connection = new SqlConnection(connectionString);
}
public virtual T PopulateRecord(SqlDataReader reader)
{
return null;
}
public virtual void GetDataCount(int count)
{
}
protected IEnumerable<T> GetRecords(SqlCommand command)
{
var reader = (SqlDataReader) null;
var list = new List<T>();
try
{
command.Connection = _connection;
_connection.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
list.Add(PopulateRecord(reader));
}
reader.NextResult();
if (reader.HasRows)
{
while (reader.Read())
{
GetDataCount(Convert.ToInt32(reader["Count"].ToString()));
}
}
Status(false, "");
}
catch (Exception ex)
{
Status(true, ex.Message);
}
finally
{
// Always call Close when done reading.
reader.Close();
_connection.Close();
_connection.Dispose();
}
return list;
}
protected T GetRecord(SqlCommand command)
{
var reader = (SqlDataReader)null;
T record = null;
try
{
command.Connection = _connection;
_connection.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
record = PopulateRecord(reader);
Status(false, "");
break;
}
}
catch (Exception ex)
{
Status(true, ex.Message);
}
finally
{
reader.Close();
_connection.Close();
_connection.Dispose();
}
return record;
}
protected IEnumerable<T> ExecuteStoredProc(SqlCommand command)
{
var reader = (SqlDataReader)null;
var list = new List<T>();
try
{
command.Connection = _connection;
command.CommandType = CommandType.StoredProcedure;
_connection.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
var record = PopulateRecord(reader);
if (record != null) list.Add(record);
}
}
finally
{
// Always call Close when done reading.
reader.Close();
_connection.Close();
_connection.Dispose();
}
return list;
}
}
StudentRepository which extend base AdoRepository
-----------------------------------------------
public class StudentRepository : AdoRepository<Student>
{
public int DataCounter { get; set; }
public bool hasError { get; set; }
public string ErrorMessage { get; set; }
public StudentRepository(string connectionString)
: base(connectionString)
{
}
public IEnumerable<Student> GetAll()
{
// DBAs across the country are having strokes
// over this next command!
using (var command = new SqlCommand("SELECT ID, FirstName,LastName,IsActive,StateName,CityName FROM vwListStudents"))
{
return GetRecords(command);
}
}
public Student GetById(string id)
{
// PARAMETERIZED QUERIES!
using (var command = new SqlCommand("SELECT ID, FirstName,LastName,IsActive,StateName,CityName FROM vwListStudents WHERE Id = #id"))
{
command.Parameters.Add(new ObjectParameter("id", id));
return GetRecord(command);
}
}
public IEnumerable<Student> GetStudents(int StartIndex, int EndIndex, string sortCol, string sortOrder)
{
string strSQL = "SELECT * FROM vwListStudents WHERE ID >=" + StartIndex + " AND ID <=" + EndIndex;
strSQL += " ORDER BY " + sortCol + " " + sortOrder;
strSQL += ";SELECT COUNT(*) AS Count FROM vwListStudents";
var command = new SqlCommand(strSQL);
return GetRecords(command);
}
public override Student PopulateRecord(SqlDataReader reader)
{
return new Student
{
ID = Convert.ToInt32(reader["ID"].ToString()),
FirstName = reader["FirstName"].ToString(),
LastName = reader["LastName"].ToString(),
IsActive = Convert.ToBoolean(reader["IsActive"]),
StateID = Convert.ToInt32(reader["StateID"].ToString()),
StateName = reader["StateName"].ToString(),
CityID = Convert.ToInt32(reader["CityID"].ToString()),
CityName = reader["CityName"].ToString()
};
}
public override void GetDataCount(int count)
{
DataCounter = count;
}
public override void Status(bool IsError, string strErrMsg)
{
hasError = IsError;
ErrorMessage = strErrMsg;
}
}
calling StudentRepository from mvc controller like below way
public class StudentController : Controller
{
private StudentRepository _data;
public StudentController()
{
_data = new StudentRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentDBContext"].ConnectionString);
}
// GET: Stuent
public ActionResult List(StudentListViewModel oSVm)
{
StudentListViewModel SVm = new StudentListViewModel();
SVm.SetUpParams(oSVm);
SVm.Students = _data.GetStudents(SVm.StartIndex, SVm.EndIndex, SVm.sort, oSVm.sortdir).ToList();
SVm.RowCount = _data.DataCounter;
return View("ListStudents",SVm);
}
}
I don't get the point of this:
catch (Exception ex)
{
Status(true, ex.Message);
}
Simply not catch the exception and let it bubble up to the caller who, according to you, will know to handle it. No callbacks necessary.
Storing retrieved data in instance state seems like a bad way to go. Rather, return an object with that data. That results in a more straight forward API and has less mutable state.
finally
{
reader.Close();
_connection.Close();
_connection.Dispose();
}
There is a better way to go about this: Wrap resources in a using statement. In particular, part ways with the superstitious double dispose pattern.
Let the caller deal with the exception making sure that you log a decent error message (showing all relevant fields). The Status class will annoy the hell out of support people as it swallows the stack trace and says nothing about the data which has caused the error. DB exceptions are often caused by malformed data so its important to have this data logged when things go wrong.
As an aside, your PopulateRecord and GetDataCount methods should be abstract as the base versions do nothing. Another dev could easily think they don't need to implement these methods and would be left with a class with useless PopulateRecord and GetDataCount methods.

Error when doing two calls from DB

I'm getting the error "Cannot acess to disposable object" when I try to use the same connection. So this is my Oracle context:
public class MyOracleContext
{
DbConnection connection;
public MyOracleContext()
{
connection = new OracleConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
}
public TOut ExecuteCommand<TOut>(IDbCommand command, Func<IDataReader, TOut> mapHelper)
{
TOut result = default(TOut);
try
{
using (connection)
{
using (command)
{
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
using (IDataReader reader = command.ExecuteReader(CommandBehavior.Default))
{
result = mapHelper(reader);
}
}
}
}
catch (Exception _exp)
{
throw new Exception("Error!" + _exp.Message);
}
return result;
}
public IDbCommand GetCommand()
{
OracleCommand cmd = (OracleCommand)connection.CreateCommand();
cmd.BindByName = true;
return cmd;
}
public IDataParameter GetParameter()
{
return new OracleParameter();
}
public bool ExecuteCommand(IDbCommand command)
{
bool result;
try
{
using (connection)
{
command.Prepare();
using (command)
{
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
result = command.ExecuteNonQuery() > 0;
}
}
}
catch (Exception _exp)
{
throw new Exception("Error!" + _exp.Message);
}
return result;
}
public DbParameter GetParameter(string name, object value)
{
OracleParameter para = new OracleParameter(name, value);
para.Size = int.MaxValue;
return para;
}
}
I use the ExecuteCommand to Get results from DB, and the ExecuteCommand to, for eg, Insert. But, when I use the two commands on the same method, it gives me the error "Cannot access to disposable object", when I do Connection.Open, on the method ExecuteCommand . But if i do the inverse order (use first the ExecuteCommand and then use ExecuteCommand), it pass. The problem is that I want to get results from the BD, to compare and then insert. Any idea why? I've been stuck here for hours
You are holding the DbConnection as a property of the class, but then disposing of it after executing a command. If another command is then executed using the same instance, then it's trying to use a disposed connection.
Connections are pooled by .NET, so they're relatively cheap to create. I would just create the command in the ExceuteCommand method:
public TOut ExecuteCommand<TOut>(IDbCommand command, Func<IDataReader, TOut> mapHelper)
{
TOut result = default(TOut);
//try
//{
using (DbConnection connection = new OracleConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
//using (command)
//{
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
using (IDataReader reader = command.ExecuteReader(CommandBehavior.Default))
{
result = mapHelper(reader);
}
//}
}
}
//catch (Exception _exp)
//{
// throw new Exception("Error!" + _exp.Message);
//}
return result;
}
There are two other changes I would suggest:
You should not be disposing the command in this method since it didn't create it. Whatever is responsible for creating a disposable item is
responsible for disposing of it.
Do not catch any exception simply to throw another plain vanilla Exception with just the error message extracted. Either just let the exception bubble up or do something meaningful (log it, add some more context, etc) and then either throw a new exception attaching the original exception as the InnerException or rethrow the exception
Change the "return result;" to inside the using(){ }
Like that:
public TOut ExecuteCommand<TOut>(IDbCommand command, Func<IDataReader, TOut> mapHelper)
{
TOut result = default(TOut);
try
{
using (connection)
{
using (command)
{
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
using (IDataReader reader = command.ExecuteReader(CommandBehavior.Default))
{
return result = mapHelper(reader);
}
}
}
}
catch (Exception _exp)
{
throw new Exception("Error!" + _exp.Message);
}
}

What to put into my Class's Dispose method

I am writing my own data access layer class for the first time so I would like to wrap it inside a (using) parenthesis but that requires the class to implement Idisposable.
The only thing I put in there is
conn.close()
is there something else missing that i should be adding there?
class overview:
public class DAL : IDisposable
{
SqlConnection conn;
SqlCommand cmd;
SqlTransaction transaction;
public int Status = 1;
public DAL()
{
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString);
conn.Open();
}
public void InsertRequest(UserAndRequestInfo UInfo, UserCrops UCrop)
{
}
public void InsertBGs(BreedingGroups BG)
{
}
public void EndTransaction()
{
if (Status == 1)
transaction.Commit();
if (Status < 0)
transaction.Rollback();
}
public void EndConnection()
{
conn.Close();
}
void Dispose()
{
conn.Close();
}
called from:
using (DAL db = new DAL())
{
foreach (var crop in UInfo.UserCropInfo)
{
db.InsertRequest(UInfo, crop);
foreach (BreedingGroups bg in crop.BGs)
{
db.InsertBGs(bg);
}
db.EndTransaction();
}
db.EndConnection(); <---- //If 'using' is there I'll remove this line
}
Also, in this particular case, wouldn't be just better to call an db.EndConnection() method
Yes: Call Dispose() on any disposable variables in your class.
void Dispose()
{
if(cmd != null)
cmd.Dispose();
if(transaction != null)
transaction.Dispose();
if(conn != null)
conn.Dispose();
}
edit: conn.Dispose() will also call conn.Close() so you shouldn't need to also call close it if you call dispose.
This is just a choich for you, to use the using scope in InsertRequest method instead as the following:
public class DAL
{
public void InsertRequest(UserAndRequestInfo UInfo, UserCrops UCrop)
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString))
{
conn.Open();
SqlCommand command = conn.CreateCommand();
SqlTransaction transaction;
// Start a local transaction.
transaction = conn.BeginTransaction("SampleTransaction");
command.Connection = conn;
command.Transaction = transaction;
try
{
command.CommandText = "Insert into ...";
command.ExecuteNonQuery();
command.CommandText = "Insert into ...";
command.ExecuteNonQuery();
// Attempt to commit the transaction.
transaction.Commit();
}
catch (Exception ex)
{
// Attempt to roll back the transaction.
try
{
transaction.Rollback();
}
catch (Exception ex2)
{
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}
}
}
}
public void InsertBGs(BreedingGroups BG)
{
}
}
Note that you don't need to make database connection in Constructure, remove it out.
And use the same concept to implement InsertBGs method.
This is form to call the
DAL db = new DAL();
foreach (var crop in UInfo.UserCropInfo)
{
db.InsertRequest(UInfo, crop);
foreach (BreedingGroups bg in crop.BGs)
{
db.InsertBGs(bg);
}
}

Categories