Session getting null reference - c#

i'm working on a project where i am using sessions for storing message alerts. when new item is added in a database i store success message in Session["message"] and which is used to show a simple message to user. all this is working file every time new message is stored in this session. but when i moved to another page i want to destroy session and after that i want to show new page.
Function for creating sessions:-
public void Send_Response(string message, string status)
{
Session["message"] = message;
Session["status"] = status;
}
i can access this session in whole code but when i going to destroy this session it throws null reference exception.
here is the code to setting sessions to null:-
public void Set_Null_Session()
{
try
{
Response.Cookies["message"].Value = string.Empty; //not working
//Session.Abandon(); //not working
//Session.Remove("message"); //not working
//Session.Remove("status"); //not working
Session["message"] = " "; //not working
Session["status"] = " "; //not working
Session["message"] = null; //not working
Session["status"] = null; //not working
}
catch (Exception ex)
{
var error = ex.ToString();
}
}
i used Session.Remove("message") , session.Abandon() but nothing is working.
i called Set_Null_Session method in my controller before moving to another page as i want to destroy previous session.

It sounds like Set_Null_Session does not have access to the Session object. Where is that method defined? And where is it called from? You might need to pass the Session or Request object into the method.

Related

Can't get a value out an ASP.NET hidden field

I am going through a YouTube video, to learn ASP.NET. I've gotten it to work for the most part, with a somewhat major caveat: I can't retrieve a value from a hidden field ID. Because of that, I don't have a value to send to a stored procedure to create or update.
The commented out line is the original statement. When I have that then execute
.ExecuteNonQuery, I get the following error:
Procedure or function 'ResourceCreateOrUpdate' expects parameter '#ResourceID', which was not supplied
When I try to display hfResourceID, I have nothing when trying to pass 0, for a create, or the ResourceID value, i.e. 1. That value however, doesn't get there. I know the stored procedure works because I can execute it in SQL Server Management.
I tried moving hfResourceID to a string, then a integer value, but I seem to be having problems creating the if/else: everything is marked as an error. When I hover over the lines, I get the following message, which pretty much leave me clueless:
"Embedded statement cannot be a declaration or labeled statement".
Would I be able to get any pointers on how to clear up my error, please? Thanks.
2017-10-13 # 10:38: code updated
<asp:HiddenField ID="hfResourceID" runat="server" />
protected void btnSave_Click(object sender, EventArgs e)
{
int intResourceID = 0;
bool boolIDHasValue = true;
try
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
catch (Exception ex)
{
lblErrorMessage.Text = ex.Message;
boolIDHasValue = false;
}
if (boolIDHasValue)
{
if (sqlconnODRConnection.State == System.Data.ConnectionState.Closed)
sqlconnODRConnection.Open();
SqlCommand sqlcmdCreateOrUpdate = new SqlCommand("ResourceCreateOrUpdate", sqlconnODRConnection);
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#ResourceID", intResourceID);
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#Status", txtStatus.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#FirstName", txtFirstName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#MiddleName", txtMiddleName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#LastName", txtLastName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#NickName", txtNickName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#Gender", txtGender.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#USCitizen", txtUSCitizen.Text.Trim());
sqlcmdCreateOrUpdate.ExecuteNonQuery();
sqlconnODRConnection.Close();
string strResourceID = hfResourceID.Value;
Clear();
if (strResourceID == "")
lblSuccessMessage.Text = "Saved Successfully";
else
lblSuccessMessage.Text = "Updated Successfully";
FillGridView();
}
}
There are a few issues with the code you copied from that video. But here a snippet as to how it should be done. I've added 3 ways to convert from the HiddenField value to an actual int. Which one you use can depend on how you want to handle errors, 0 values etc. Not included in the snippet, but I like to check for IsNullOrEmpty while using Trim(), that gets rid of spaces that might make the value non-convertible if (!string.IsNullOrEmpty(hfResourceID.Value.Trim())).
int intResourceID = 0;
//this will try to convert but you won't see exeptions when failed
Int32.TryParse(hfResourceID.Value, out intResourceID);
//checks if there is a value in the hiddenfield, but throws yellow screen if not convertible
if (!string.IsNullOrEmpty(hfResourceID.Value))
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
//catch an error when the value is not convertible, can be wrapped with !string.IsNullOrEmpty(hfResourceID.Value)
try
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
catch (Exception ex)
{
//handle the error, can be seen with ex.Message
}
//if the hidden value is still 0 (for whatever reason) you might not want to execute the query
//so the next part will return and stop executing the rest of the code
if (intResourceID == 0)
{
return;
}
//update the database, using 'using' will ensure proper closure of the connection and disposing of any objects
using (SqlConnection connection = new SqlConnection("myConnectionString"))
using (SqlCommand command = new SqlCommand("ResourceCreateOrUpdate", connection))
{
//set the command type and add the parameters
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#ResourceID", SqlDbType.Int).Value = intResourceID;
try
{
//open the database connection and execute the command
connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
//there was an error opening the database connection or with the command, can be viewed with ex.Message
}
}
Your error regarding the embedded statement is because you a declaring
if (strResourceID == "")
int intResourceID = 0;
else
int intResourceID = (Convert.ToInt32(hfResourceID.Value));
When decalring a variable directly after an If or else then you need your curly brackets. So...
if (strResourceID == "")
{
int intResourceID = 0;
}
else
{
int intResourceID = (Convert.ToInt32(hfResourceID.Value));
}
As for your other issues I would need to see your client side code.
Take a look on ASP code, specifically the way you are setting hidden field value. I guess it is properly marked as runat=server but maybe some problem is going on in your asp.net code, try to debug client code by using: console.log function and see the output in your console browser.

ClrZmq returning messages always to first started client

We're creating a WPF app in which we execute python scripts from different Test Stations and show the output in its corresponding output panel, To run the scripts in parallel we are using Task but when we run the scripts in parallel from the stations, We are getting the output of other stations also into the station that is started first, we're using the following code,
private void ZmqStatusListener(string endPoint)
{
using (Context context = new Context())
{
StatusPort = string.Empty;
TestResultPort = string.Empty;
using (Socket server = context.Socket(SocketType.REP))
{
try
{
if (isStatusContextActive == false || isPortChanged == true)
{
server.Bind(endPoint);
isStatusContextActive = true;
}
}
catch (ZMQ.Exception ex)
{
if (ex.Errno != 100)
{
string IPCPort = _globalParameters.GlbParam.GlbParamIpcStartPort;
if (IPCPort == string.Empty)
{
IPCPort = "0";
}
if (endPoint == EditorConstants.PortAddress.PortPrefix + IPCPort)
{
StatusPort = endPoint;
TestReultError = EditorConstants.CommonMessageTypes.TestReultError + ex.Message + EditorConstants.CommonMessageTypes.StackTraceMessage + ex.StackTrace;
}
StopExecOfScript(default(object));
isCancelledtask = true;
ScriptStatusDesc = new ScriptStatusDesc()
{
Status = "Failed",
statusDescription = "Failed"
};
}
}
while (true)
{
string message = server.Recv(Encoding.UTF8);
UpdateTestResults(message);
server.Send(" ACK", Encoding.UTF8);
// if (message == "Test Passed")
//break;
}
}
}
}
and for testing purpose we're breaking the while loop in this code based on a test message we kept in the python script, then we are able to get the output in the respective station correctly but this way we can only run in a synchronous fashion which we don't want as we require to run the test stations in parallel and the while loop should not break as it should be listening for the response.
We were able to solve the issue by getting clues doing a sample app to reproduce the issue and to first know whether our ClrZmq pattern was correct for us or not and it is correct. The resolution we followed is that when we needed to bind that data to its corresponding View's Model object in its ViewModel so had to retrieve View's DataContext which is of Type ISomeXViewModel for the particular TestStation using an Id of that TestStation we did this cos all of our TestStations are dynamically added and we even store it to be accessed wherever necessary. This issue was caused to due multiple instances of UserControls so we explicitly needed to update the TestStation manually with a little more effort.
Sample Code Snippet
private void BindTestResult(string xmlPayLoad)
{
// converting xmlPalLoad to a class/model object
ITestStationViewModel viewModel = (ITestStationViewModel)((IView)DynamicTestStationsGrid.Children[StationNumber].Content).DataContext;
// IView class has DataContext property so I am type casting the Content which is ContentControl to IView type first and later to ITestStationViewModel
viewModel.TestStationModel = xmlPayLoadModel;
}
Thanks.

How do I update a field in the database before my transaction is committed?

I am working on a password change method, this view is enforced by one of many conditions. The first condition is if the LastLoggedin field in the database is null. I have this field set to null in my test database to force the password change events.
I have coded a method to change the password after performing some tests, but I cannot get past the first test because the controller method that the click event calls returns the user back to the log on method, which in turns checks the LastLoggedin field in the database which is still null because I have not yet logged in. I tried to change that value from within my change password method using the following code:
public bool SavePassword(UserModel user, PasswordRecoveryModel password)
{
try
{
string newPass = password.PasswordNew;
string newHash = PasswordManager.EncryptPassword(newPass);
User domainObject = UnitOfWork.UserRepository.GetItem(user.EntityId);
bool hasUsedPassword = UnitOfWork.UserRepository.HasHadPassword(domainObject, newHash, DateTime.Now.AddMonths(-6));
if (hasUsedPassword.Equals(true))
{
return true;
}
User lastLogged = UnitOfWork.UserRepository.GetItem(user.EntityId);
lastLogged.LastLoggedIn = DateTime.Now;
lastLogged.VerifiedOn = DateTime.Now;
UnitOfWork.UserRepository.Update(lastLogged);
lastLogged.VerifiedOn.Equals(DateTime.Now);
lastLogged.LastLoggedIn.Equals(DateTime.Now);
user.Password = newHash;
user = SaveModel(UnitOfWork.UserRepository,
user,
Mapper.User.ModelToDomain,
Mapper.User.DomainToUserModel);
CommitTransaction();
return false;
}
catch (Exception ex)
{
OnServiceException(ex);
throw;
}
}
But I am still not getting anything other than the new password saved in the database, I am verifying this by running a query on my username. How do I update this field so I can get by this test on password change, and is it even acceptable to do this? In our old product it was done in a very complex manner creating a temporary user object ant using that to get past the test and on to the next test. I am trying to simplify the process.
I am new to MVC and programming in general any help would be appreciated.
EDIT found my problem, as usual over thinking the issue, here is the updated code:
if (hasUsedPassword.Equals(true))
{
return false;
}
user.LastLoggedIn = DateTime.Now.ToString();
user.Password = newHash;
user = SaveModel(UnitOfWork.UserRepository,
user,
Mapper.User.ModelToDomain,
Mapper.User.DomainToUserModel);
CommitTransaction();
return true;

Unit testing functions which access Entity Database

Trying to unit test functions which access a entity framework. So i tried to put all the entity code into the test function below? However it stops at the Linq statement; obviously trying to access the database is too much drama for it. Maybe a work around would be too to create a replica database within the unit test function based on sql lite or compact;(Its not a big database anyways) then execution would not have to leave the test function? Is this possible and how would i implement it?
public void RetreiveKeyFnTest()
{
StegApp target = new StegApp(); // TODO: Initialize to an appropriate value
string username = "david"; // TODO: Initialize to an appropriate value
string password = "david1"; // TODO: Initialize to an appropriate value
string ConnectionString = ConfigurationManager.ConnectionStrings["DatabaseEntities"].ToString();
var dataContext = new DatabaseEntities(ConnectionString);
var user = dataContext.Users.FirstOrDefault(u => u.Username.Equals(username) && u.Password.Equals(password));
Assert.IsNotNull(user);
//target.RetreiveKeyFn(username, password);
//Assert.IsInstanceOfType(target.RetreiveLogs,typeof(DataAccess));
//Assert.IsInstanceOfType(target.p);
//Assert.IsNotNull(target.RetreiveLogs.AuthenitcateCredentials(username,password));
//Assert.Inconclusive("A method that does not return a value cannot be verified.");
}
Below is the code i am trying to test:
public void RetreiveKeyFn(string username, string password)
{
BusinessObjects.User p = RetreiveLogs.AuthenitcateCredentials(username,password);
if (p != null)
{
if (RetreiveLogs.RetreiveMessages(p.UserId) == null)
{
DisplayLogs.Text = "Sorry No messages for you recorded in Database, your correspondant might have chose not to record the entry";
}
else
{
MessageBox.Show("LogId = " + RetreiveLogs.RetreiveMessages(p.UserId).LogId + "\n" +
"UserId = " + RetreiveLogs.RetreiveMessages(p.UserId).UserId + "\n" +
"Message Key = " + RetreiveLogs.RetreiveMessages(p.UserId).MessageKey + "\n" + "PictureId = " + RetreiveLogs.RetreiveMessages(p.UserId).PictureId +
" Date & time = " + RetreiveLogs.RetreiveMessages(p.UserId).SentDateTime);
DisplayLogs.Visible = true;
}
}
else
{
MessageBox.Show("Please enter your correct username and password in order to retreive either key, image or both from Databse");
}
}
First, you should be able to access the same database in your test application as the one you're using in your main/actual application. You just need to make sure that your Test project contains your connection string in its own App.config.
The initialization of the context should be done either inside your StegApp(), or you should be able to pass a context to your StegApp() from a different scope. From what I read of your code, your StegApp() will not be able to access the dataContext variable you created.
Your test for null user already happens inside the RetrieveKeyFn() under the AuthenticateCredentials() method so there's no need for the first "Assert.IsNotNull(user)". I would recommend separating your business logic for RetrieveKeyFn from your UI behaviors so that you can easily do unit tests. You can bind the "Messagebox" operations to say a button click event handler which calls just RetrieveKeyFn(). I would suggest maybe something like this:
public class StegApp
{
public DatabaseEntities context;
//other properties
public StegApp()
{
//assuming your DatabaseEntities class inherits from DbContext.
//You should create other constructors that allow you to set options
//like lazy loading and mappings
this.context = new DatabaseEntities();
}
//ASSUMING YOUR RetrieveLogs.RetrieveMessages() function returns
//a Message object. replace this type with whatever type the
//RetrieveLogs.RetrieveMessages() method returns.
public Message RetrieveKeyFn (string username, string password)
{
BusinessObjects.User p = RetreiveLogs.AuthenitcateCredentials(username,password);
if (p != null)
{
var message = RetrieveLogs.RetrieveMessages(p.UserId);
if (message == null)
// handle behavior for no messages. In this case
// I will just create a new Message object with a -1 LogId
return new Message {LogId =-1};
else
return message;
}
else
//handle behavior when the user is not authenticated.
//In this case I throw an exception
throw new Exception();
}
//on your button click handler, do something like:
// try
// {
// var message = RetrieveKeyFn(txtUsername.Text.Trim(), txtPassword.Text.Trim());
// if (message.LogId == -1)
// DisplayLogs.Text = "Sorry No messages for you recorded in Database, your correspondant might have chose not to record the entry";
// else
// {
// MessageBox.Show("Log Id = " + message.LogId)
// etc. etc. etc.
// }
// }
// catch
// {
// MessageBox.Show ("user is not authenticated");
// }
}
When you do your unit test, remember to have the appropriate configuration strings in your test project's App.Config If the app.config does not yet exist, go ahead and create one. You should create tests for all possibilities (i.e. 1) user is valid, you get the message, 2) user is valid, there are no messages, 3) user is invalid).
Here's an example for case 2
[TestMethod]
public void RetrieveKeyFnTest1()
{
StegApp target = new StegApp(); // this creates your context. I'm assuming it also creates your RetrieveLogs object, etc
var username = "UserWithNotMessages"; //this user should exist in your database but should not have any messages. You could insert this user as part of your TestInitialize method
var password = "UserWithNotMessagesPassword"; //this should be the proper password
var message = target.RetrieveKeyFn(username, password);
Assert.AreEqual (-1, message.LogId);
}
I got my unit tests to work fine. The mistake i had was not to copy the app.config file into the test project! Although to be honest i expected Visual studio would have done that anyways.

Why do I get "Object reference not set to an instance of an object." when changing pages in asp.net

I have a master page that set ups some variables that I want to use across the site..
protected void Page_Load(object sender, EventArgs e)
{
//Get users name from AD
str_DomainName = HttpContext.Current.User.Identity.Name;
str_CurrentLogin = str_DomainName.Substring(5);
//Display current user information
DirectorySearcher search = new DirectorySearcher("LDAP://DCHS");
search.Filter = String.Format("(SAMAccountName={0})", str_CurrentLogin);
SearchResult result = search.FindOne();
DirectoryEntry entry = result.GetDirectoryEntry();
lbl_CurrentUser.Text = result.Properties["givenName"][0].ToString() + ' ' + result.Properties["sn"][0].ToString();
// Get SID
IntPtr logonToken = WindowsIdentity.GetCurrent().Token;
WindowsIdentity windowsId = new WindowsIdentity(logonToken);
//Set session variabls
this.CurrentFirstName = result.Properties["givenName"][0].ToString();
//this.CurrentEmail = result.Properties["mail"][0].ToString();
//this.CurrentSID = windowsId.User.ToString();
//this.CurrentUserName = str_CurrentLogin;
//this.CurrentFullName = lbl_CurrentUser.Text;
//this.CurrentDomain = str_DomainName;
this.Session.Add("currentEmail", result.Properties["mail"][0].ToString());
}
public String CurrentFirstName
{
get { return (String)ViewState["currentFirstName"]; }
set { ViewState["currentFirstName"] = value; }
}
I then call them in my defalut.aspx page as follows:
protected void Page_PreRender(object sender, EventArgs e)
{
//try
//{
lbl_FullName.Text = Master.CurrentFullName;
lbl_SID.Text = Master.CurrentSID;
testLabel.Text = Master.CurrentEmail;
//}
//catch (Exception ex)
//{ }
}
This works fine.. If I however navigate away from the default page, then I get the following error..
Object reference not set to an instance of an object.
One the lbl_FullName.Text = Master.CurrentFullName; line
If I uncomment the try catch then it works fine, but I don't believe that this is the correct method of avoiding the fault..
I'm only new to ASP, so be nice..
EDIT:
The variabes are being set in Master.cs as follows.
public String CurrentUserName
{
get { return (String)ViewState["currentUserName"]; }
set { ViewState["currentUserName"] = value; }
}
A few questions:
Which side of the expression is generating the error: this.lbl_FullName or this.Master?
If it's the former, then there's something funky going on in your page.aspx.designer.cs file. Make sure the label control has been declared in there (this file is automatically generated by visual studio, but can sometimes not update properly). You should see a single line like this:
protected
global::System.Web.UI.WebControls.Label
lbl_FullName;
If it's the this.Master property then your page is obviously not referencing your masterpage. Check the page directive (the top line of your .aspx file) and make sure that the DynamicMasterPage value is set and that the path is correct.
On a design note, the masterpage isn't the best place to "store variables". The masterpage should literally just be used to initialise the common parts of the page across your site.
If you need to gather information from a user and use it across several pages, use session variables. This is a method of storing objects "in memory" for as long as the user's browser is open.
Items can be added to the session as follows:
this.Session.Add("fullName", fullName);
Items can then be retrieved later from any other page / usercontrol in your site as follows:
string fullName = (string)this.Session["fullName"];
ViewState is per-page. When you navigate to the new page, it isn't set.
Your master page should put these into Session instead.

Categories

Resources