I have a code behind page that has several method; one of them is a page method.
[WebMethod]
public static void ResetDate(DateTime TheNewDate)
{
LoadCallHistory(TheNewDate.Date);
}
protected void LoadCallHistory(DateTime TheDate)
{ bunch of stuff }
The method LoadCallHistory works fine when the page loads and I can call it from other methods inside the page. However, in the web method part, it gets underlined in red with the error "an object reference is required for the non-static field".
How do you access functions from the page method part of the code?
Thanks.
You cannot call a non-static method from a static context without having an instance of the class. Either remove static from ResetDate or make LoadCallHistory static.
However, if you remove static from ResetDate you must have an instance of it to use that method. Another approach is to create an instance of the class inside ResetDate and use that instance to call LoadCallHistory, something like this:
[WebMethod]
public static void ResetDate(DateTime TheNewDate)
{
var callHistoryHandler = new Pages_CallHistory();
callHistoryHandler.LoadCallHistory(TheNewDate.Date);
}
The error message indicates that ResetDate has the keyword static and LoadCallHistory does not. When using static either both of the methods needs to be static or the called method needs to be static, the caller cannot be static if the called method is not.
To quote MSDN on "Static Classes and Static Class Members"
A static class is basically the same
as a non-static class, but there is
one difference: a static class cannot
be instantiated. In other words, you
cannot use the new keyword to create a
variable of the class type. Because
there is no instance variable, you
access the members of a static class
by using the class name itself.
Since this is a static method, it can only call other static methods or new objects.
If your page class is CallHistory (educated guess ;)) you will need to do this:
[WebMethod]
public static void ResetDate(DateTime TheNewDate)
{
var thisPage = new CallHistory();
thisPage.LoadCallHistory(TheNewDate.Date);
}
Or change LoadCallHistory to be static.
Related
I am using the below class named SessionExtensions to set and get complex object (User Class)
public static class SessionExtensions
{
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonSerializer.Serialize(value));
}
public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default : JsonSerializer.Deserialize<T>(value);
}
}
I am trying to inject it into a view to display the first and last name of a user but all examples are using Session.GetString instead of Get<User>
Thanks
You don't inject a static class. It's just available. That's what static means. In particular, extensions will just naturally appear on the types they extend, as long as they're in an available namespace. That last part is probably your issue. For example, if your extension class is in Namspace.To.My.Extensions, then, in your view (or in _ViewImports.cshtml, you need to add #using Namespace.To.My.Extensions.
You 100% do not need to inject IHttpContextAccessor. A view has built-in access to HttpContext already, since it's part of the request pipeline. Session, in particular, is available directly, as well. So all you need is:
#Session.Get<User>("user_login_credentionals").FirstName
I just found a solution to my questions:
First I have to include and inject the following into my view:
#using Microsoft.AspNetCore.Http
#using MenaProjects.Util
#using MenaProjects.Models
#inject IHttpContextAccessor httpContextAccessor
Then i my html code to access my complex object:
#(httpContextAccessor.HttpContext.Session.Get<User>("user_login_credentionals").FirstName)
I've a static page method in web form application and I want to call method on private class level variable from it as shown below. I'm using jQuery to call the page method.
private readonly ICatalogBLL _catalogBLL = new CatalogBLL();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
_catalogBLL.GetSomething();
}
}
[WebMethod]
public static UpdateSomething(int i)
{
//Want to do as below. But can't call it from a static method.
_catalogBLL.UpdateSomething();
}
UPDATE
If I call it as said by John Saunders, won't it use the same instance for requests from different users as it is within a static method?
You can't. The page method is static. Your _catalogBLL is an instance member.
However, since you create a new instance of CatalogBLL on every request, why not do so once more?
[WebMethod]
public static UpdateSomething(int i)
{
CatalogBLL catalogBLL = new CatalogBLL();
catalogBLL.UpdateSomething();
}
You can't call because pagemethods are static...
A static method is simply one that is disassociated from any instance of its containing class. The more common alternative is an instance method, which is a method whose result is dependent on the state of a particular instance of the class it belongs to.
Look at John saunder's answer..
I have 2 projects in my solution.
MVC Web application
Class library
The MVC Web application references the class library.
The class library contains a class that extends the default ASP.Net Controller.
I'm putting a variable in session in the application's Global.asax.
protected void Session_Start(object sender, EventArgs args)
{
HttpContext.Current.Session["DomainName"] = Request.Url.Host;
}
In the class library I'm trying to get the value from the HttpContext.Session, but HttpContext.Session keeps coming up null.
public class MyController : System.Web.Mvc.Controller
{
public MyController () : base()
{
//HttpContext.Session is always null at this point
ViewData["DomainName"] = HttpContext.Session["DomainName"];
}
}
HttpContext.Current.Session doesn't seem to be an option in controllers. Any ideas?
Two issues -- the HttpContext property in the Controller class is the current session. Unfortunately, it's not available in the constructor of the controller. Obviously because it's not passed in the constructor, it has to be set via the property afterwards. You might consider adding a property to hold the domain name and referencing the session from it -- that way it would be available for use when needed.
protected string DomainName
{
get { return this.HttpContext.Session["DomainName"] as string; }
}
The set it in ViewData in your actions or in OnActionExecuting/OnActionExecuted.
protected override void OnActionExecuted( ActionExecutedContext context )
{
ViewData["DomainName"] = this.HttpContext.Session["DomainName"];
// or ViewData["DomainName"] = this.DomainName; // if you used the property
}
If you're just trying to add ViewData from the session, try doing it in the OnActionExecuting method. This is where I typically add ViewData I want for every View.
You just use Session by itself (it's a property of Controller), but that just maps to Controller.HttpContext.Session (in other words, what you're already using), so it won't solve your problem, which must be elsewhere.
I'm not sure why you're putting this in the Session, though, as you can read Request.Url.Host directly during the Action.
When you create cookie then you must write
Response.AppendCookie("Your cookie name");
And if you want to get that then something like this
if (Request.Cookies["Your cookie name"] != null)
{
string value = Request.Cookies["Your cookie name"].Value;
}
and must if there are different solutions
then
machineKey
need to be same which is under
system.web
in web.config and then write
<httpCookies domain=".yourdomainname.com" />
I bumped into an additional question that I needed in regards to this: Using an IEnumerable<T> as a delegate return type
From the above solution, the following was suggested:
class Example
{
//the delegate declaration
public delegate IEnumerable<T> GetGridDataSource<T>();
//the generic method used to call the method
public void someMethod<T>(GetGridDataSource<T> method)
{
method();
}
//a method to pass to "someMethod<T>"
private IEnumerable<string> methodBeingCalled()
{
return Enumerable.Empty<string>();
}
//our main program look
static void Main(string[] args)
{
//create a new instance of our example
var myObject = new Example();
//invoke the method passing the method
myObject.someMethod<string>(myObject.methodBeingCalled);
}
}
Notice that in someMethod, the delegate "method()" is called. Is there anyway to set a class-level delegate that is called later on?
I.e:
class Example {
//the delegate declaration
public delegate IEnumerable<T> GetGridDataSource<T>();
//this fails because T is never provided
private GetGridDataSource<T> getDS;
//the generic method used to call the method
public void someMethod<T>(GetGridDataSource<T> method)
{
getDS = method;
}
public void anotherMethod() {
getDS();
}
}
Depending on what you are trying to achieve and where you have flexibility in your design, there are a number of options. I've tried to cover the ones that I feel most probably relate to what you want to do.
Multiple values of T in a single instance of a non-generic class
This is basically what you seem to want. However, because of the generic nature of the method call, you'll need a class level variable that can support any possible value of T, and you will need to know T when you store a value for the delegate.
Therefore, you can either use a Dictionary<Type, object> or you could use a nested type that encapsulates the class-level variable and the method, and then use a List<WrapperType<T>> instead.
You would then need to look up the appropriate delegate based on the required type.
class Example {
//the delegate declaration
public delegate IEnumerable<T> GetGridDataSource<T>();
//this works because T is provided
private Dictionary<Type, object> getDSMap;
//the generic method used to call the method
public void someMethod<T>(GetGridDataSource<T> method)
{
getDSMap[typeof(T)] = method;
}
//note, this call needs to know the type of T
public void anotherMethod<T>() {
object getDSObj = null;
if (this.getDSMap.TryGetValue(typeof(T), out getDSObj))
{
GetGridDataSource<T> getDS = getDSObj as GetGridDataSource<T>;
if (getDS != null)
getDS();
}
}
Single value of T in a single instance of a non-generic class
In this case, you could store the delegate instance in a non-typed delegate and then cast it to the appropriate type when you need it and you know the value of T. Of course, you'd need to know T when you first create the delegate, which negates the need for a generic method or delegate in the first place.
Multiple values of T in multiple instances of a generic class
Here you can make your parent class generic and supply T up front. This then makes the example you have work correctly as the type of T is known from the start.
class Example<T> {
//the delegate declaration
public delegate IEnumerable<T> GetGridDataSource<T>();
//this works because T is provided
private GetGridDataSource<T> getDS;
//the generic method used to call the method
public void someMethod<T>(GetGridDataSource<T> method)
{
getDS = method;
}
public void anotherMethod() {
if (getDS != null)
getDS();
}
}
You either need to make the type generic as well, or use plain Delegate and cast back to the right type when you need to invoke it. You can't just use T outside a generic context - the compiler will think you're trying to refer to a normal type called T.
To put it another way - if you're going to try to use the same type T in two different places, you're going to need to know what T is somewhere in the type... and if the type isn't generic, where is that information going to live?
During practice of customizing VirtualPathProvider, I found that it the custom VirtualPathProvider can be registered in Global.asax or in AppInitialize method according to MSDN http://msdn.microsoft.com/en-us/library/system.web.hosting.virtualpathprovider.aspx. However, MSDN doesn't clearly describe the method AppInitialize.
Does any static AppInitialize method in App_code folder will be automatically invoked by ASP.NET runtime at start up?
While there is precious little documentation about the AppInitialize() method, you are correct in your assumption that any class in your App_Code folder that contains a method signature like this:
public static void AppInitialize()
will be invoked when the Asp.Net application starts up. Remember that App_Code is a special folder to Asp.Net and everything inside there is treated a little differently. Good luck finding documentation on all the little quirks (like the aforementioned) of the App_Code folder.
Another thing to remember however is that only one class can contain a signature for the AppInitialize() method or else you will get a compiler error at runtime similar to this:
The AppInitialize method is defined
both in 'App_Code.SomeClassOne' and in
'App_Code.SomeClassTwo'.
So while this is perfectly valid:
public class SomeClassOne
{
public static void AppInitialize()
{
HostingEnvironment.Cache["InitializationTimeOne"] = DateTime.Now;
}
}
This will generate the compiler error I mentioned above:
public class SomeClassOne
{
public static void AppInitialize()
{
HostingEnvironment.Cache["InitializationTimeOne"] = DateTime.Now;
}
}
public class SomeClassTwo
{
public static void AppInitialize()
{
HostingEnvironment.Cache["InitializationTimeTwo"] = DateTime.Now;
}
}
I hope this clears things up a bit for you :)