Session exception error - c#

My code is giving me this error i am not getting why and to do
"Error 13 An object reference is required for the non-static field, method, or property 'System.Web.UI.Page.Session.get'"
I am already using sessions to get a parameter at another page and method and works fine, now i want to use the same paramenter in a Schedualed Job i created for my app but is no working.
public static bool UpdateActivationResult(string recordId, string resultPart, string failureMessage, int reconciliation_count)
{
OracleConnection conn = new OracleConnection();
OracleTransaction transaction = null;
OracleCommand cmd;
string updateQuery = "";
int rowsUpdated = 0;
string notes = "";
string branch = clsUtility.GetHO;
clsUtility.CDFOperations operation = clsUtility.CDFOperations.CanNotActivateCard;
string userLoggedBranch = "";
try
{
userLoggedBranch = Session["userDegaS"].ToString(); //this row is giving me error
clsUtility.WriteLog4Net(recordId + " - " + resultPart + " - " + failureMessage, null, clsUtility.LogType.Debug, "");
using (conn = new OracleConnection(clsUtility.ConnectionString))
{ etc
i want to use this parameter in calling this method
if (reconciliation_count == 5 && !resultPart.Equals("SUCCESS"))
{
Utility.clsUtility.SendNotificationAsHTML(recordId, branch, operation, userLoggedBranch);
}
Any idea where am i doing wrong?

The Session property is a non-static property that is defined on the base Controller in .NET (msnd).
The the code listed with your question, you are trying to access this non-static method from without a static method. That is not possible.
You can solve it three ways:
If the method is within your controller, you can simply make it non-static in order to access the Session property.
You can also pass along the property you need (userLoggedBranch) as a parameter into your method UpdateActivationResult. Whatever action is calling that method will simply have to pass this value.
So something along the lines of:
public static bool UpdateActivationResult(
string recordId,
string resultPart,
string failureMessage,
int reconciliation_count,
string userLoggedBranch) {
// Your method code
Pass along the session itself, or something from which you can access the session (such as HttpContext, or the HttpRequest).

Declare userLoggedBranch as static variable or better is to simply access session in the respective method instead of passing it as a parameter

Related

How can I create an extension method that takes more than 2 parameters?

I have two classes in my Azure Functions project.
MyExtensions.cs:
namespace My.Functions
{
public static class MyExtensions
{
public static async Task<(bool addedcontactmail, string errorline1, string errorline2, string errorline3, string errorline4)> AddEmail(this string emailaddress, PlayFabClientInstanceAPI clientAPI, string language)
{
bool addedcontactmail = false;
string errorline1 = string.Empty;
string errorline2 = string.Empty;
string errorline3 = string.Empty;
string errorline4 = string.Empty;
var request = new PlayFab.ClientModels.AddOrUpdateContactEmailRequest();
request.EmailAddress = emailaddress;
var result = await clientAPI.AddOrUpdateContactEmailAsync(request);
if (result.Error != null)
{
errorline1 = "Error.";
errorline2 = "Please try again.";
}
else
{
addedcontactmail = true;
}
return (addedcontactmail, errorline1, errorline2, errorline3, errorline4);
}
}
}
I have tried to call the extension method AddEmail in my class NewFunstions.cs but it only seems to work if AddEmail takes only two parameters:
If MyExtensions.AddEmail only takes two parameters, then it shows a menu with the return variables:
If MyExtensions.AddEmail takes three parameters:
In NewFunctions.cs, I call the extension method:
var resultcontactemail = await MyExtensions.AddEmail(desiredemail, clientAPI, language);
if (resultcontactemail.)
{
functionsuccessful = resultcontactemail.addedcontactmail;
errorline1 = resultcontactemail.errorline1;
errorline2 = resultcontactemail.errorline2;
errorline3 = resultcontactemail.errorline3;
errorline4 = resultcontactemail.errorline4;
}
As you can see in the picture, it's not possible to choose the return variables addedcontactmail, errorline1, errorline2, errorline3, errorline4 from the menu if the extension method takes three parameters. Why is it not showing the return variables in a menu?
Why is my extension method not working if it takes more than two parameters? Is it possible to create an extension method in Azure Functions that takes more than two parameters?
Remove this inside the first parameter of AddEmail method. It will no longer be a proper extension method, but it will solve your problem.
Continue reading if you want to know what is wrong with your extension method:
this string means you are extending a string, so you must call it from an instance of string. The mistake you are making is that you are calling it from the class MyExtensions.AddEmail. I don't think it makes sense to extend a string for this so I believe my solution will put you back on the right track. See more about it in the docs. Specifically step 5.
Call the methods as if they were instance methods on the type

How to prevent static method from creating a null object

I have a static method that I call that checks if an object should be added and if calls the constructor if it should add it. Then if not it should really do nothing. I thought returning null would achieve this but it is creating an object with none of the properties being populated. This is then causing a runtime eror later.
This is my code:
public static WorkSheets AddSheet(string dataPath, string exportFile, string finalFile, string tabName)
{
if (File.Exists(dataPath + exportFile))
{
if (!tabName.Contains("Forecast") & !tabName.Contains("Sales"))
if (Functions.FileIsGood(dataPath + exportFile)) File.Copy(dataPath + exportFile, dataPath + finalFile, true);
return new WorkSheets(dataPath, exportFile, finalFile, tabName);
}
return null;
}
and my constructor:
public WorkSheets(string dataPath, string exportFile, string finalFile, string tabName)
{
this.ExportFile = dataPath + exportFile;
this.Path = dataPath + finalFile;
this.TabName = tabName;
this.DateError = !Functions.IsTodaysDate(ExportFile);
this.WorksheetDate = File.GetLastWriteTime(ExportFile);
this.SizeError = !Functions.IsCorrectSize(ExportFile);
this.WorksheetSize = new FileInfo(ExportFile).Length;
}
Then I call the method like this:
worksheets.Add(WorkSheets.AddSheet(CurrentWorkbook.DataPath, Constants.PipeExport, Constants.PipeFinalFile, "Pipe"));
The issue I am having is with the return null; what can I do so it doesn't add the null object.
You just need to get the return value from AddSheet in a temporary variable and check if it is null.
If it is null just don't add it to your list of worksheets
WorkSheets sheet = WorkSheets.AddSheet(CurrentWorkbook.DataPath,
Constants.PipeExport,
Constants.PipeFinalFile,
"Pipe"));
if(sheet != null)
worksheets.Add(sheet);
If you prefer to avoid repeating this check every time you add an element to the list then you can create a new class derived from List<T> and write your own Add method that performs the check for null and add to the underlying base class if the element to add is not null.
public class ListWorkSheets : List<WorkSheets>
{
public new void Add(WorkSheets source)
{
if(source != null)
base.Add(source);
}
}
Now you can declare
ListWorkSheets worksheets = new ListWorkSheets();
and use your current syntax without adding a null to your list
worksheets.Add(WorkSheets.AddSheet(CurrentWorkbook.DataPath,
Constants.PipeExport,
Constants.PipeFinalFile,
"Pipe"));
Try some conditional logic before adding the instance to the list.
IE
Worksheet tempWorkSheet = WorkSheets.AddSheet(CurrentWorkbook.DataPath, Constants.PipeExport, Constants.PipeFinalFile, "Pipe");
if (tempWorkSheet != null)
{
worksheets.Add(TempWorkSheet);
}
If your method has a declared return type you have to return that type or null.
You could throw an exception instead.
Or you change the return type to void and declare an out parameter for your result
Alternatively you could save the result of your call that instantiates the object and check for null.
var tmp = WorkSheets.AddSheet(foo);
if(tmp != null) {
worksheets.Add(tmp)
}
I'd recommend one of the following:
What #Steve said: split up your function call and check for null in the return.
Wrap your function call in a try/catch block then have your function return an exception if it can't find the file.
If it's a rare anomaly where a file can't be found then the exception is likely the 'correct' way to go from a methodology standpoint. If it's common for incorrect paths to be attempted, then returning null and having a check like Steve said is probably best. It's more a question of code methodology than technical requirement at that point.

C# - 3 Tier Architecture. Error says No overload for method name takes 0 arguments

I am using 3 tier architecture in my C# Window Form. The thing I want to do is, hide the button if the data is exists. Here are my codes.
Class File
public bool checkIfExists(Variables variables) { // BelPar
SqlCommand check = new SqlCommand();
check.Connection = dbcon.getcon();
check.CommandType = CommandType.Text;
check.CommandText = "SELECT * FROM tbl";
SqlDataReader drCheck = check.ExecuteReader();
if(drCheck.HasRows == true)
{
drCheck.Read();
if (... && .. ||) // conditions where variables are being fetch
{
return false;
}
}
drCheck.Close();
return true;
}
Window Form
btn_save.Visible = !balpayrolldetails.checkIfExists(); // This is where I get the "No overload for method 'checkIfExists' takes 0 arguments.
Any help? Please leave or answer below. Thank you
To call a method, you need to call it by its exact name, which in this case is:
checkIfExists(Variables variables);
This tells us that to use this method, we need to pass it in an object of type Variables to be used in the method execution.
Whichever types are outlined in the method signature must be provided to successfully call a method.
You will need to update your call from
btn_save.Visible = !balpayrolldetails.checkIfExists();
to
btn_save.Visible = !balpayrolldetails.checkIfExists(someVariablesOfTheExpectedType);
Having the method signature:
public bool checkIfExists(Variables variables)
It should be called by passing an object of type Variables to the method:
btn_save.Visible = !balpayrolldetails.checkIfExists(anInstanceOfVariables);
But if it's acceptable for you to call the method parameter-less and your method is written in a way that can tolerate having variables with null value, you can change the signature to this:
public bool checkIfExists(Variables variables=null)
And then you can call it this way:
btn_save.Visible = !balpayrolldetails.checkIfExists();

Does getting current class and method name reduce performance?

I have a logging class which creates an instance of log4net and I can call it from anywhere in my code. I also have a method to find out the class and method name of caller. here is my method:
private static string CurrentMethod()
{
StackTrace stackTrace = new StackTrace();
MethodBase method = stackTrace.GetFrame(2).GetMethod();
string cn = method.ReflectedType.Name;
string mn = method.Name;
string output = "[" + cn + "." + mn + "]";
return output;
}
i found these articles: link1, Link2, Link3, Link4 and so many others, but none of them discuss about the efficiency and performance.
now I have two questions:
1- can I use this method in a big project(about 1000 requests in one second)? I mean how much does this effect the project's efficiency and performance?
2- Os there a better way to write the above method?
Also here is part of my logging class. I guess it can help:
public static class Tools_Log
{
private static ILog logger;
public static ILog GetLogger()
{
return logger ?? (logger = CreateLogger());
}
private static ILog CreateLogger()
{
//Some log4net initialization
return LogManager.GetLogger("WebService");
}
private static string CurrentMethod()
{
StackTrace stackTrace = new StackTrace();
MethodBase method = stackTrace.GetFrame(2).GetMethod();
string cn = method.ReflectedType.Name;
string mn = method.Name;
string output = "[" + cn + "." + mn + "]";
return output;
}
public static string MessageForLogFile(string message, string exeption, double time)
{
string currentMethod;
string executiontime;
string consumer;
string body;
string output;
currentMethod = CurrentMethod();
executiontime = ExecutionTime(time);
body = BodyForLog(message, exeption);
consumer = Consumer();
output = OutPut(currentMethod, executiontime, consumer, body);
return output;
}
}
i call the log class like this:
Tools_Log.GetLogger().Info(Tools_Log.MessageForLogFile("some text", "some text", execution time));
Thanks.
Yes, reflection is always a slower process. If you want the name of the method you can get it quite easily with the CallerMemberNameAttribute. Add a string parameter with an empty default value, and apply that attribute to it, and the compiler will send the name for you.
Also, if you're looking for fast logging, take a look at ETW instead of Log4Net.
Here: https://msdn.microsoft.com/en-us/library/windows/desktop/bb968803(v=vs.85).aspx
And Here: http://blogs.msdn.com/b/vancem/archive/2012/07/09/logging-your-own-etw-events-in-c-system-diagnostics-tracing-eventsource.aspx
EDIT:
As for your question in the comments, unfortunately, you can't get the name of the method 2 levels up, at least, not directly. CallerMemberName is basically just syntax sugar, it tells the compiler to take the name of the calling member, and place it in the parameter, so it works on a single level. However, since it relies on default parameters to do so, if you send the parameter manually, the CallerMemberName functionality doesn't apply, so you can do something like this:
public void UserMethod()
{
IntermediaryMethod();
}
public void IntermediaryMethod([CallerMemberName] caller = "")
{
LogMethod(caller)
}
public void LogMethod([CallerMemberName] caller = "")
{
// Log...
}
If you pass a value by yourself, it won't be overridden, so doing something like this will allow you to get the name of the caller from 2 levels up, while retaining the functionality for a single level.
Performance must be measured and this is done using profilers.
BTW, maybe instead of using StackTrace class, you can use caller information attributes introduced in .NET 4.5.
While [CallerMemberName] attribute doesn't provide class name, [CallerFilePath] provides the full path to the source code file where the caller member is defined (it might be even better for debugging/logging purposes since you know where to investigate a possible bug or error).

Return multiple values from a method

Hi guys i'm having a problem regarding returning multiple values from a method. I'm using 'out' to return other value from a method, here the snippet:
public DataTable ValidateUser(string username, string password, out int result)
{
try
{
//Calls the Data Layer (Base Class)
if (objDL != null)
{
int intRet = 0;
sqlDT = objDL.ValidateUser(username, password, out intRet);
}
}
catch (Exception ex)
{
ErrorHandler.Handle(ex);
OnRaiseErrorOccuredEvent(this, new ErrorEventArgs(ex));
}
return sqlDT;
}
then when i compile having a error like this:
"The out parameter 'return' must be assigned to before control leaves the current method"
Anyone guys can help me solve this.
That means in all possibilities (inside and outside the if, in the catch), your result variable must be assigned.
The best approach would be to give it a default value at the start of the function:
public DataTable ValidateUser(string username, string password, out int result)
{
result = 0;
try
{
//Calls the Data Layer (Base Class)
if (objDL != null)
{
int intRet = 0;
sqlDT = objDL.ValidateUser(username, password, out intRet);
result = intRet;
}
//....
The parameter result of your method is marked as out. Parameters marked with out must be assigned within your method, i.e
result = 5;
This is enforced so callers of your method have the guarantee that the parameter that is passed with out is always set once your method finishes.
You're not setting the result variable in the method.
I'm guessing you want to add an extra line such as
result = intRet;

Categories