Global objects in C# ASP.Net - always null when read back - c#

In an ASP.Net project, using C#, I have a class (PlcComms.cs) for talking to a Controller (a PLC).
I want the one class object to be globally available, for each web page in my project.
I see from reading various forum posts that I should be able to create a public static object of my class type, i.e. PlcComms, in Global.asax.cs, or in a class in the App_Code folder. I've tried both and I write to the object ok, but when I go to read from it (from a timer in an update panel on the home web page) then it always read back as null.
I'm at a loss to know what to do at this point. can anyone help?
Currently, this is a class I have in the App_Code folder...
namespace SpearheadWeb
{
public static class AppGlobal
{
public static SpearheadWeb.PlcComms PlcCommsObject { get; set; }
}
}
this I have on my web page - it seems to create the object OK...
namespace SpearheadWeb
{
public partial class _Default : Page
{
private PlcComms CurrentPLC;
//some other here including ComPorts
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
try
{
//some settings reading and setup here
CurrentPLC = new PlcComms(Global.CommsSettings.CpuType1,Global.CommsSettings.Network1,ComPorts[0], Global.CommsSettings.IPAddress1, Global.CommsSettings.Path1,UpdatePanel.Controls[0].Controls, 1, Global.CommsSettings.MsUpdate1);
AppGlobal.PlcCommsObject = CurrentPLC;
but in my timer (the timer within an updatepanel) PLCComms1 is always null here...
protected void TimerUpdate_Tick(object sender, EventArgs e)
{
PlcComms PLCComms1 = AppGlobal.PlcCommsObject;

Related

Thread doesn't seem to be running in the background

I have the following code:
public class BaseControlClass : System.Web.UI.UserControl
{
protected delegate void AsyncronousAction();
protected virtual void FAsyncEvent() { } //Overidden on derived classes.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
FPerformAsyncronousTasks(FAsyncEvent);
}
protected virtual void FPerformAsyncronousTasks(AsyncronousAction AsyncCallback)
{
new Thread(delegate()
{
AsyncCallback();
}).Start();
}
}
public class DerivedControlClass : BaseClass
{
protected override void FAsyncEvent()
{
//Contact web service, wait for results, add to local database.
}
}
What I was expecting is for the page to load and the code in FAsyncEvent() in my derived class to run behind the scenes however, the page doesn't finish loading until the code in FAsyncEvent() has completed.
Am I doing something wrong with the threading here?
EDIT Strangely, I have noticed if I do a Clean -> Build then run the code, it works fine and the page finishes loading whilst the web service is being contacted. Subsequent runs though mean the page waits until the thread has finished processing.
Your code keeps the reference to the UserControl alive, which might be preventing the request from continuing. Try passing a static method to the new thread, just as a quick check and see if it helps.

Using Decorator Pattern with an ASP.NET (non-MVC) page

I've only recently started to develop in ASP.NET, though I've been using C# for several years now. My first approach to ASP.NET was using MVC 4, but now I find myself working on a project that uses plain ASP.NET pages. I'm at a loss as to how the general framework works.
Specifically, I have no idea how to implement the Decorator Pattern in an ASP.NET page. I have a Product.aspx page and I have to add a feature to it. I thought that Decorator Pattern would be best based on the task requirements, and I immediately figured out how I would use it in MVC, since the actual logic that is executed lies in the Controller Action: there I would instantiate my decorator object.
But I have no idea how to do it in ASP.NET. As far as I can see, when the browser requests Product.aspx "something" creates an object of class Product (derived from Page), and then it's too late to decorate it.
Is it therefore possible to decorate a whole ASP.NET page (not just an object used by the code behind)? How would I do that?
I am not exactly sure what you wanna decorate, but;
You can create an HttpHandler that lets you do your work on a particular request as follows
public class MyHttpHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.Request.RawUrl.Contains("product.aspx"))
{
// may be you can execute your decorate business here
}
}
public bool IsReusable { get { return false; } }
}
Or may be you can use Global.asax 's OnBeginRequest event like as follows
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterOpenAuth();
RouteConfig.RegisterRoutes(RouteTable.Routes);
base.BeginRequest += OnBeginRequest;
}
private void OnBeginRequest(object sender, EventArgs e)
{
if (Request.RawUrl.Contains("product.aspx"))
{
//execute your business here..
}
}
First of all, according to your comment below the question, I can say that you should implement your showcase as a web user control (ascx)
You can decorate your ShowCase as follows,
public partial class ShowCase : System.Web.UI.UserControl, IShowCase
{
protected void Page_Load(object sender, EventArgs e){}
public void ApplyConfiguration(IConfiguration configuration)
{
throw new NotImplementedException();
}
}
public interface IShowCase
{
void ApplyConfiguration(IConfiguration configuration);
}
public abstract class Decorator : IShowCase
{
protected IShowCase ShowCase;
protected Decorator(IShowCase showcase)
{
ShowCase = showcase;
}
public virtual void ApplyConfiguration(IConfiguration configuration)
{
ShowCase.ApplyConfiguration(configuration);
}
}
public class ShowCaseDecoratorA : Decorator
{
public ShowCaseDecoratorA(IShowCase showcase) : base(showcase){ }
public override void ApplyConfiguration(IConfiguration configuration)
{
base.ApplyConfiguration(configuration);
//depending on the configuration, do something..
ShowCase.Visible = false;
}
}
public interface IConfiguration
{
//configuration
}
Then, from inside the page that uses ShowCase user control, you do something like this,
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
IConfiguration configuration = ConfigurationFactory.Get();
new ShowCaseDecoratorA(this.ShowCase).ApplyConfiguration(configuration);
}
}
I hope this gives you some inspiration..

How to code reuse apsx?

I know in C# I can make a factory but I don't not know how to reuse code in aspx. My code was originally purposed for ARList only, but now has IcnList. I thought about making a switch statement but isn't there something better to code?
The Function
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ARExtractionController arController = new ARExtractionController();
Dictionary<int, string> ARDictionary = arController.GetTickets();
List<int> sortedARList = new List<int>();
foreach (KeyValuePair<int, string> kv in ARDictionary)
{
sortedARList.Add(kv.Key);
}
sortedARList.Sort();
sortedARList.Reverse();
ARList.DataSource = sortedARList;
ARList.DataBind();
ARList.Items.Insert(0, " ");
ARList.AutoPostBack = true;
}
}
If you just want to be able to reuse the code, add a class to your project for utility methods and dump it in there for both pages to use.
If you're trying to reuse code with and associated UI, look into User Controls (ascx files) which allow you to do just that.
It isn't clear which is right for you from the question.
In TicketExtractionWeb, create a BasePage class.
BasePage.cs:
public class BasePage : System.Web.UI.Page
{
// Add methods that are used on all your pages in here.
protected DateTime GetCurrentDate()
{
return DateTime.Now;
}
}
And a page (we'll call it MyPage):
public class MyPage : BasePage
{
protected Page_Load(object sender, EventArgs e)
{
var currentDate = this.GetCurrentDate();
}
}
So when you create another aspx page, it will default to:
public class MyNewPage : System.Web.UI.Page
{
// ...
}
Just change : System.Web.UI.Page to : BasePage
You should be able to inherit from a single page to reuse the code.
Top of aspx file:
<%# Page Language="C#" AutoEventWireup="true" Inherits="MyNamespace.CommonCode" %>
If you want to reuse html , please use a user control file (.ascx) , which can be reused muliple times
when do you need .ascx files and how would you use them?

Web service and global parameter

I start building a new web service for my app and i want to make a global int for example that every time someone call this web service this int will increase in one.
this is what i create in visual studio:
public partial class Form : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
and i try to put static int in the class but it not work.
Put your variable in Application state.
Note you need to make it thread safe.
from http://msdn.microsoft.com/en-us/library/94xkskdf(VS.80).aspx
Application.Lock();
Application["PageRequestCount"] =
((int)Application["PageRequestCount"])+1;
Application.UnLock();

Calling a Web Method from ASPX Code Behind

I'm trying to figure out a way that I can call a Web Method (located as a public static method in the code behind of an aspx page) from another ASPX Code Behind page.
This is the code behind of Page A.aspx
public partial class PageA : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// other code not relevant is here
}
[WebMethod(true)]
public static string GetStringInfo()
{
// do some stuff here to build my string
// return string
}
}
On page B, I need to be able to call GetStringInfo() during page load or some other event to get the information. the GetStringInfo() is fairly complex and for reasons outside of my control, can't be moved elsewhere or rebuilt presently.
How can I consume the web method above from another page's code behind?
I've tried instantiating a copy of the other page (PageB), such as:
public partial class PageB : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
PageA page = new PageA();
page.GetStringInfo();
}
}
The problem here is since it's dynamically compiled, I don't have an easy namespace to reference and access. I've tried adding one, and it ignores it.
This project is on .net 3.5, C#, and is a web site project (not a web application).
Any help is appreciated!
If the GetStringInfo method is static you don't need an instance of PageA to invoke it:
public partial class PageB : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string info = PageA.GetStringInfo();
}
}

Categories