Page_Load is been fired when WebMethod is called through javascript PageMethods - c#

I have an aspx page. I've added a ScriptManager to it, and set EnablePageMethods=true, and created a static method marked as [WebMethod] on the server-side.
I have always worked with WebMethods, and I've never seen this error before.
On javascript, PageMethods is accessible. But when I call my method, the Page_Load method is fired, instead of the WebMethod.
I've searched and found other people had this issue as well. But no answers.... Any ideas?
HTML:
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"></asp:ScriptManager>
JS:
PageMethods.Test()
C#:
[WebMethod]
public static void Test()
{
}

So after founding the culprit of why controls in my update panel was calling post back twice I found it was because of a page method being called.
After finding LcSalazar solution I did disabled Friendly URLs and everything was working. But I find the Friendly URLs to be more clean so I found a solution .
On your master page add the following .
<script type="text/javascript">
$(function () {
try {
if (PageMethods.get_path().indexOf('.aspx') == -1)
PageMethods.set_path(PageMethods.get_path() + '.aspx');
} catch (e) {
}
})
</script>
Once the page methods path includes the .aspx the page_load doesn't fire again.
Alternatively look into using ASP.Net Web Api . Better practice as well when it comes to reusable methods instead of declaring the methods in you Base Page or every page you are trying to use it .

I discovered that the problem on my case is that I'm using friendly URL's. Since PageMethods references the server-side page by its address, there you have the issue. It's been discussed here, on CodePlex: http://aspnetfriendlyurls.codeplex.com/workitem/3.
Apparently there are workarounds for this, but I ended up making a manual ajax call to a generic handler (.ashx).

When you submit a form that has runat server it processes the full .net lifecycle. Which fires the Page_Load of your .cs class. If you want to make it strictly want to fire the webmethod I suggest using an ajax call to your webmethod.

Disable friendly urls. Comment this out in App_Start\RouteConfig.cs
routes.EnableFriendlyUrls(settings);

Related

How to update page url on page refresh?

I am looking for a way to change page url (change one of the url key's value) when the user refreshes the page. I am doing this to reflect changes on the contents of the page. I have tried several methods but they all have a loop problem. Below is one of the methods:
In my html page:
<body onLoad="CheckPageLoad();">
<input type="hidden" name="trial" id="trial" value="hello" />
</body>
In the page.asp page: (inside a script tag)
function CheckPageLoad() {
if ($("#trial").val() == "hello") {
// This is a fresh page load
alert('Load');
$("#trial").val("hi");
} else {
// This is a page refresh
window.location = url;
alert('Refresh');
}
}
Issues:
Every time the page is refreshed, the Load alert is always displayed. I thought the load is done once. It looks like every time the page is refreshed, it reloads so the value always remains to be hello.
I tried using the script tag only and the new url is opened but keeps looping. (This is the main problem)
Any suggestion to update the above method or use another method to do the refresh is appreciated. Below are other methods I also tried:
window.onbeforeunload = unloadPage();
function unloadPage() {
//do something
//works but loops
}
Thanks
I put the following code into a basic page and it demonstrates why you are getting the described behaviour:
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
function CheckPageLoad() {
if ($("#trial").val() == "hello") {
// This is a fresh page load
alert('Load');
$("#trial").val("hi");
} else {
// This is a page refresh
alert('Refresh');
window.location = window.location + '?id=1';
}
}
</script>
</head>
<body onLoad="CheckPageLoad();">
<input type="hidden" name="trial" id="trial" value="hello" />
</body>
</html>
When you set the window.location it changes the url (well duh!) which therefore means you are loading a new page. When the page is refreshed you get a "Refresh" alert before a "Load". This demonstrates that the page is posting back first, but the onload event causes the page to navigate to another location, therefore loading it again. It is my understanding that updating anything in the URL ultimately is a new request/newly loaded page.
You might find the following useful regarding the viewstate in asp (seeing as you suggested you are using an asp page): http://msdn.microsoft.com/en-us/library/ms972976.aspx
My suggestion would be to completely remove the window.location = url; part of your code in favour of looking at the data which was posted back instead. This means that you aren't unnecessarily loading the page twice on postback and allows you to access the data from any updated inputs.

How to call javascript function and c# code on asp:button?

When a user clicks a button on ASP.net page, I need to
Save file from asp:fileUpload in a folder on a server - I guess this needs to be done in C#, like in How to correctly use the ASP.NET FileUpload control
Run a javascript function like in How to call javascript function from asp.net button click event
Is there a way to combine C# and Javascript to achieve what I need? If not, how should I do it?
Try using the onClientClick property of the asp:button element.
Ex, on your .aspx file:
<script type="text/javascript">
function myFunction()
{
alert('hi');
}
</script>
...
<asp:button id="Button1"
usesubmitbehavior="true"
text="Open Web site"
onclientclick="myFunction()"
runat="server" onclick="Button1_Click" />
And in your code behind (.aspx.cs)
void Button1_Click (object sender, EventArgs e)
{
if (this.FileUpload1.HasFile)
{
this.FileUpload1.SaveAs("c:\\" + this.FileUpload1.FileName);
}
}
More info at
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.onclientclick.aspx
Note that no JavaScript actually "runs" until the server-side code (C# in this case) has entirely completed and the resulting page is returned to the client. Once that page renders on the client, then JavaScript runs on the client.
So in order to execute your JavaScript code, all you need to do is include it in the page being returned to the client. There are a number of ways to do this, and the options depend on whether you're using WebForms or MVC.
You might use something like RegisterStartupScript in WebForms, for example. Or, you could just have the JavaScript code exist in a PlaceHolder control with Visible=false and only make the control visible in the response which intends the JavaScript code to run. (Roughly the same method is also easily usable in MVC by just wrapping the JavaScript code in a server-side condition to determine whether to render it or not.)
The main thing to remember is that you're not "running the JavaScript code from C#" or anything like that. There's a hard separation between server-side and client-side code. The server-side code ultimately builds the page that it sends back to the client, and that page can include JavaScript code to run on that client.

Differences between ScriptManager and ClientScript when used to execute JS?

Can somebody explain for me what the differences are between ScriptManager and ClientScript?
ClientScript works well when I use it in Button_Clicked event, but it doesn't work when I use it in the GridView_RowUpdated of a GridView. (The GirdView is wrapped inside an update panel). Then I tried ClientScript and it worked perfectly in this case.
You've pretty much identified the primary difference. The ScriptManager is meant to be used with async postbacks, which is why it works with the UpdatePanel. The ClientScript class is for synchronous postbacks. So, if you're going to be posting back from an UpdatePanel, be sure to use the ScriptManager instead of ClientScript.
ScriptManager
9 years after this question was asked, I'm finding myself doing some software archeology and I'm writing up my own notes about ASP.NET's idioms, hence this answer, which I hope actually answers the question, as I felt ShellyFM's answer was incorrect, as this statement: "ClientScript class is for synchronous postbacks" is untrue)
ClientScriptManager
The Page.ClientScript property exposes an instance of ClientScriptManager.
Each Page instance has its own single instance of ClientScriptManager.
ClientScriptManager stores a list of <script> elements. These <script> elements are automatically rendered inside the <asp:form runat="server"> element, located immediately after where ViewState controls are rendered in <div class="aspNetHidden">.
These <script> elements can be registered using different methods:
RegisterClientScriptBlock
RegisterClientScriptInclude
RegisterClientScriptResource
For example:
RegisterClientScriptBlock adds an inline script directly to the page.
// Page code:
this.ClientScript.RegisterClientScriptBlock( type: typeof(TestPage), key: " Script1", script: "function foo(){}", addScriptTags: true );
// *.aspx code:
<form id="form1" runat="server">
</form>
// Rendered result:
<form method="post" action="./TestPage.aspx" id="form1">
<div class="aspNetHidden"><!-- ViewState is rendered here --></div>
<script type="text/javascript">function foo(){}</script>
</form>
RegisterClientScriptInclude will add a <script src=""></script> element without any inline script:
RegisterClientScriptResource will add a <script> that gets its content from an <EmbeddedResource> from a .NET Assembly's GetManifestResourceStream. The script is referenced using src="/WebResource.axd?d=..." instead of being rendered inline.
The /WebResource.axd file doesn't exist in your filesystem. It's a reserved URL pattern that ASP.NET handles by itself by-default.
The Page.BeginFormRender method directly calls ClientScriptManager.RenderClientScriptBlocks() and passes it the HtmlTextWriter, so ClientScriptManager is not a WebControl.
Somewhat surprisingly, ClientScriptManager does not offer a way to remove or un-register a script - nor can you enumerate existing registrations: you can only replace an existing registration - and only if you know the String key that was used to register it in the first place.
ScriptManager
The ScriptManager class was added in ASP.NET AJAX which was an extension to ASP.NET 2.0 released in 2007.
It was built-in to ASP.NET in ASP.NET 4.0 in 2010 (instead of being an extension).
It lives in System.Web.Extensions.dll (in both ASP.NET 2.0 and 4.0), while ClientScriptManager lives in System.Web.dll, which indicates it's more central and integral to ASP.NET than ScriptManager.
ScriptManager itself is a WebControl (it derives from System.Web.UI.Control) so it's responsible for rendering HTML directly via its .Render() method, whereas ClientScriptManager was invoked directly by Page's BeginFormRender.
The ScriptManager does not have any instance methods for registering <script> elements to render to the page.
It does have static methods for registering scripts to a Page instance, but all it does is call into Page.ClientScript.RegisterClientScriptBlock, Page.ClientScript.RegisterClientScriptInclude, or Page.ClientScript.RegisterClientScriptResource.
The <asp:ScriptManager> control must be placed inside your <asp:Form> and must be placed before any other WebControls that depend on ScriptManager-registered scripts. You also cannot have more than 1 <asp:ScriptManager> control on a page.
So if ScriptManager simply wraps ClientScriptManager, what does it actually do itself?
Well, unlike ClientScriptManager, the ScriptManager does let you remove a script registration and get a list of current registrations.
...provided those scripts were registered with ScriptManger and not ClientScriptManager and that you removed the offending script before ScriptManager.RegisterScripts() is called (which happens inside Page's PreRender event btw).
Additionally, ScriptManager handles the automatic creation of JavaScript code for ASMX and WCF client proxies and renders those as registered scripts too.
This is what the <asp:ScriptManager><Services> collection is for. For each <asp:ServiceReference /> child element it will generate a <script> containing functions that wrap XMLHttpRequest calls to each [WebMethod] method.
[WebMethod] methods exist in .asmx classes, though your WebService subclass also needs [ScriptService] applied.
[WebMethod] can also be static methods on your Page subclass, though you need to set EnablePageMethods="true" to use those.
TL;DR:
ClientScriptManager is integral to ASP.NET WebForms and renders pre-registered <script> elements inside your <form>.
ScriptManager is an optional extension to ASP.NET WebForms (as a part of ASP.NET AJAX) and essentially extends ClientScriptManager to allow for removing registrations and also generates JavaScript to make it easier to call [WebMethod] methods defined in .asmx WebService or a "Page method" (which is a static method on a Page subclass, also with [WebMethod]).

how to write javascript in asp.net in code behind using C#

How can I write JavaScript code in asp.net in code behind using C#?
For example:
I have click button event when I click the button I want to invoke this java script code:
alert("You pressed Me!");
I want to know how to use java script from code behind.
Actually, this is what you need:
string myScriptValue = "function callMe() {alert('You pressed Me!'); }";
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "myScriptName", myScriptValue, true);
Copy all of javascript into string and then register it into your aspx page in code-behind. Then in aspx page, you can call the javascript function whenever you want. You should write this code in Page_Load method in C# page.
Have a look at the ScriptManager class' RegisterClientScriptBlock and RegisterStartupScript methods.
One way to put some javascript onto the page into a specific location do this:
ASP.Net
<script type="text/javascript">
<asp:Literal id="litScript" runat="server" />
</script>
C#
litScript.Text = "alert("Hello!");"
Of course, you can put anything in there, and I'd recommend a javascript library.
Using the Scriptmanager is also an option.
Not an answer, but a suggestion.
Mixing your js within your code-behind can come back to haunt you, I agree with Adrian Magdas.
Anytime you need to make a simple change/update to your javascript you'll have to re-build your project, which means re-deploying instead of simply pushing out a single .js file.
Something like:
btnSomething.ClientClick = "alert('You pressed me!');";
You might also want to read up on the ScriptManager control and outputting blocks of script.
The right answers usually is "You don't". It's better to define your code in a .js file and use jQuery to hook-up the desired events.
$(document).ready(function() {
$('#myBtn').click(function() {
alert('Handler for .click() called.');
});};
If you want to register a script that will be used in connection with an UpdatePanel (AJAX) use ScriptManager class as Sani Huttunen pointed.
Otherwise you should use the class ClientScriptManager (methods Page.ClientScript.RegisterClientScriptBlock or Page.ClientScript.RegisterStartupScript)
As other user pointed, normally registering a script on the code behind can and should be avoided. It's not a very nice practice and you should do it only in cases where you have no other option.
Response.Write("<script language='javascript'>alert('You pressed Me!');</script>");

Detect if a page is within a iframe - serverside

How can I detect server-side (c#, asp.net mvc) if the loaded page is within a iframe? Thanks
This is not possible, however.
<iframe src="mypage?iframe=yes"></iframe>
and then check serverside if the querystring contains iframe=yes
or with the Referer header send by the browser.
Use the following Code inside the form:
<asp:HiddenField ID="hfIsInIframe" runat="server" />
<script type="text/javascript">
var isInIFrame = (self != top);
$('#<%= hfIsInIframe.ClientID %>').val(isInIFrame);
</script>
Then you can check easily if it's an iFrame in the code-behind:
bool bIsInIFrame = (hfIsInIframe.Value == "true");
Tested and worked for me.
Edit: Please note that you require jQuery to run my code above. To run it without jQuery just use some code like the following (untested) code to set the value of the hidden field:
document.getElementById('<%= hfIsInIframe.ClientID %>').value = isInIFrame;
Edit 2: This only works when the page was loaded once. If someone have idea's to improve this, let me know. In my case I luckily only need the value after an postback.
There is no way of checking this that will fit your requirement of "secure" as stated in your comment on #WTP's answer.
I don't think the server-side can do this, so why not put a hidden control in your page that will be in the iframe? When the URL in the iframe loads, you can add some client-side code to set the hidden input to indicate you are in an iframe. The easiest check would be on the client-side in an onload method, like this:
// Set hidden input
someHiddenInput.value = self != top
It's more secure than the querystring, but it still might not be enough security for you.
My 2 cents.
Old question but why not a more simplistic approach like
var isFramed = self !== parent

Categories