Calling ASP.NET page non-static methods from static web methods - c#

I am in need of calling a non-static method in the active(current) asp page that the user is on by using a static WebMethod. How can I do this?
Both of these methods are within the ASP page's cs file.
public void NormalMethod()
{
txtFindingNum.Text = "Ajax is da bomb";
}
[WebMethod]
public static void MyWebMethod()
{
// This is the part I need help with...
DoIt();
}

You can't do it. It doesn't even make sense.
The instance methods of the page are about a specific instance of the page. When you're in the static web method (page method), there is no instance of the page.
If you could call the instance method from the web method, that would mean that the instance method should be a static method. Can you just add static to that method and have it still work? If not, then it depends on the particular instance of the page, and you simply can't call it when there is no instance.
Note that a page instance exists only during the HTTP request that it is serving. By the time your client-side code is calling the web service, that HTTP request is already over, and the page instance is gone.

You can't do it, but the txtFindingNum.Text field is input, and you can change it in client side (it also keep the change in the server after postback), with js or jq, like this:
$("#<%=txtFindingNum.ClientID%>").val("Ajax is da bomb");

Related

Calling Form.Refresh or Reload from static method c#

I have a static method that gets some data from Web Service ("GET"), if i gets HttpWebResponse with some status code (403,401), i have to reset, refresh or reload the Form1_load. Since my method is static, i cannot make instance of Form1. Is there solution for this ?

Use injected service from JS code to static Blazor method

I have an app that uses a jQuery lib to show 'confirmation' dialogs.
When a user clicks 'OK' or 'Cancel' on the dialog, then first a callback is made to my Javascript code. From there I do a call to a Blazor method, based on the decision the user made.
This all looks something like this:
My js code:
$('.alert-yesno).on('click', function() {
// For simplicity I immediately call the Blazor method
DotNet.invokeMethodAsync('[Assembly name]', 'DoSomething')
.then(data => {
// do something...
});
});
Blazor page:
#inject MyService MyService
<button class="alert-yesno">Show dialog</button>
#code
{
[JSInvokable]
public static async Task DoSomething()
{
// How to use the non static MyService here...?
}
}
This all works fine. The Javascript part calls my Blazor method. But how can I use MyService from there? This is injected into the page. Which is good, because it makes use of dependency injection.
I don't want to create a new instance everytime from within the static method, because that way I loose all the auto injected dependencies.
How can I solve this issue?
See https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interop?view=aspnetcore-3.0#instance-method-call for a more complete example, but you can pass a reference to the the .net instance to the javascript code by calling
DotNetObjectReference.Create(myInstance);
Then the javascript code can call the instance method on that object. Since the component (and thus the service which is injected into it) has a potentially different lifespan than the jquery click handler, this might cause some other issues, but the link above should be a good starting point.

ASPX Page Life Cycle when calling [WebMethod]s

I'm calling a number of methods that have been decorated with [WebMethod] via jQuery ajax.
These require a database connection to be set up in an external library that will be the same for each method.
My original code looked like this:
public partial class Server : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// code to set up DB connections
ExternalLibrary.SetupDB();
}
[WebMethod]
public static string AjaxAccessibleMethod()
{
try
{
// get some data from the database via the external library
ExternalLibrary.CallDatabase();
}
catch(Exception ex)
{
// handle errors
}
}
}
This was working, but then started throwing exceptions claiming that the ExternalLibrary's database hadn't been initialized.
Placing breakpoints in my code I found that the Page_Load event wasn't being called when calling my AjaxAccessibleMethod, I also tried moving the DB setup stuff into the Page_Init event but likewise that wasn't called.
Can anyone explain to me the aspx page life cycle when using WebMethods? The fact that this worked initially seems to imply that Page_Load was called, but it no longer is.
Notice that the method you are using as WebMethod is static, this should be the first hint to the fact that Page object is not created at all.
Page Methods is a simple alternative to full blown web services, and as such, its life cycle is more similar to web service than to page. That is, request goes through the general ASP.NET pipeline, with objects like HttpContext, Request and such. But then the difference happens: for page requests and postbacks page object is created and the whole series of page events happens, whereas for page methods page object is not created, and method is simply called as Server.AjaxAccessibleMethod().
There is really no way to mix the two, because this would unnecessarily complicate processing of calls to page methods. So the only path forward for you here is duplicate necessary code:
protected void Page_Load(object sender, EventArgs e)
{
// code to set up DB connections
ExternalLibrary.SetupDB();
}
[WebMethod]
public static string AjaxAccessibleMethod()
{
ExternalLibrary.SetupDB();
...
}

Update a control's value from a static class in ASP.NET

Say that I have an ASP.NET page with a Label control and the following static class which executes a scheduled job:
public static class Job
{
// The Execute method is called by a scheduler and must therefore
// have this exact signature (i.e. it cannot take any paramters).
public static string Execute()
{
// Do work
}
}
When the job is done, the execute method should update the value of the Label control on the page.
I've done some research and the only way seems to be to use HttpContext.Current.CurrentHandler. However, this is undesirable for me since it can potentially return null.
Since the Execute method cannot take any parameters (see comment), passing the Page instance as an argument is not an option.
Is there any other way to update the control from the static class?
NOTE: the Execute method must be static because I'm creating an EPiServer scheduled job, which requires a static Execute method (that doesn't take any parameters).
If the job is not executed synchronously (or even if it is), I think that you may want to consider the order of control.
What I suggest in a case like this is a structure similar to the following:
1) The web page issues the request for the job
2) Somewhere, a unique reference to the job is created and stored (such as GUID or an identity column in a database table)
3) The job is executed asynchronously by code-behind and then the unique identifier is returned to the web page.
4) The web page, on startup, initiates a javascript method (using window.timeout, for example) that on a regular basis, issues an ajax query to the web server to check on the status of the job.
5) When the job is complete, it updates the global reference with the appropriate information.
6) When the javascript sees that the job is complete, it updates the label.
This process allows the user to carry on with other work if necessary and not have to worry about timeouts due to long postback times, etc.
For your specific scenario, you could add a GUID property to the Job class (which would be passed back to the client).
When Execute is complete, you could add this GUID to a static collection (i.e. Dictionary<Guid, string>) which the ajax request would check (the string value could store status or completion information).
When the ajax request fires, it would check this static collection and, when it finds its job, remove it and return the value to the caller.
You can create a static property that is updated by your Execute method and bind the Text property of the Label to the static property in the aspx's OnInit method, Label.Text = Job.StaticProperty, if you need a somewhat dynamic response you could use the Ajax Timer Control to call a method on the aspx page to return the same static value from the aspx Page.
public static class Job
{
public static string UpdatedValue { get; private set; } // Or whatever the property is you wish to expose.
// The Execute method is called by a scheduler and must therefore
// have this exact signature (i.e. it cannot take any paramters).
public static string Execute()
{
// Do work
Job.UpdatedValue = "Execute Completed";
}
}
protected override OnInit(EventArgs e)
{
base.OnInit(e);
this.TextLabel.Text = Job.UpdatedValue;
}
// Using MSDN basic sample
protected void Timer1_Tick(object sender, EventArgs e)
{
this.TextLabel.Text = Job.UpdatedValue;
}
Try with a global variable (static) or raise an event from Execute() method.

Does AutoCompletionExtender Method of AJAX Control Toolkit have to be static?

I have web page which is using AjaxControlToolkit:AutoCompleteExtener on some TextBox.
This extender requires service method, from which it will get data to display:
[System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]
public static string[] GetCompletionList2(string prefixText, int count, string contextKey)
{
return DatabaseSearch.GetUnits().GetSymbolCompletion(prefixText, organizationToSearch);
}
In this method I use some argument = organizationToSearch. But I don't want this argument to be static ! And since the method is static I don't know what to do. If I remove the 'static' keyword from method definition it won't work... And I really don't want change organizationToSearch to static either!
Please help.
It must be static 'cause you're not in the execution of your page. When you're calling an AjaxMethod, your page (webforms) doesn't exists.
As already mentioned, you are in a completly new request and not in the execution of your page anymore (your page has already rendered by this stage)..
You will need to transfer and parameters out and pass them back into the static method..

Categories

Resources