Access page property from a generic ajax call to a library - c#

I'm using telerik tools and have a tool that runs code server side from a class library on an ajax call.
This control can come from any page. And I can access the page by the telerik object that's passed in.
Now, some of these pages have a property that I want to access, but I want to keep it generic.
I can cast the page as a specific page type and expose the property, but that would require an update to the class library every time that property is added to a page.
What I'm wondering is if there is a way for me to check to see if a property exists on the page, then access it if it does?
((Telerik.Web.UI.ControlItemContainer)((RadComboBox)o)).Page
This is how I access the page, which just returns a page object. I want to check to see if that page object contains a property without casting it.
Or if I can cast the page with using gettype(), that would work as well.
Thanks

You could use reflection:
System.Reflection.PropertyInfo propInfo =
theObjectYouWantToReflect.GetType().GetProperty("YourPropertyName");
if (propInfo != null)
{
object value = propInfo.GetValue(Page, null);
// ...
}

Related

Get QueryString from inside a WebControl

I have a page which contains a dynamic number of custom WebControls. What I want to do is get the containing page's query string via "Request.QueryString".
If I understand the problem correctly I need the containing page's HttpRequest object?
Is there a way to do this?
I probably should point out that I don't want to pass the QueryString from the containing page to the WebControl. I want to access the QueryString directly from the WebControl.
Consider the following link:
HttpContext.Current.Request.QueryString
You should be able to access the query string from a custom web user control (ascx) in the same way as you do from the page, i.e:
Request.QueryString...
From a custom control, you can either access it via:
Page.Request.QueryString
//or
HttpContext.Current.Request.QueryString
BTW: the last option (System.Web.HttpContext.Current...) also works from any non-web-control classes (e.g. business logic).
you can access the httpContext from anywhere using
HttpContext.Current
From there you can find the Request and the querystring
No need to to anything in particular, Request object is directly available also to webcontrols:
this.Request.QueryString

How to get actual JavaScript value in onclick from webbrowser control?

I'm looking for a way to get the JavaScript code defined inside of onclick.
I'm using .NET 2.0 C# Visual Studio 2005.
Example:
<span id="foo" onclick+"window.location.href='someURL'>click here</span>
My goal is to get the string "window.location.href='someURL'".
Scenario:
A user clicks on web page element, the tag shown above for instance, inside of WebBrowser control. Then the clicked tag is refereed to HtmlElement object.
In WebBrowser control I then call HtmlElement object's getAttribute("onclick"), it just gives me "System.__ComObject".
I've searched how to deal with it then found that it can be casted then get the value.
if (tag.GetAttribute("onclick").Equals("System.__ComObject"))
{
Console.WriteLine("dom elem >>>>>>>>>>> " + tag.DomElement.ToString());
mshtml.HTMLSpanElementClass span = (mshtml.HTMLSpanElementClass)tag.DomElement;
Console.WriteLine("js value ===>" + span.onclick);
}
Output:
dom elem >>>>>>>>>>> mshtml.HTMLSpanElementClass
js value ===> System.__ComObject
As it shown, span.onclick still give me System.__ComObject, what am I doing wrong?
In Why does HtmlElement's GetAttribute() method return “mshtml.HTMLInputElementClass” instead of the attribute's value? this guy said it worked in his case, and I've followed it, but mine is somewhat not working...
UPDATE
Research, research.....
I can add reference VisualBasic.dll to my C# project then call the method to find out who is this System.__ComObject really is.
Console.WriteLine(Microsoft.VisualBasic.Information.TypeName(span.onclick));
Output:
JScriptTypeInfo
It looks like this is a JScript type... how can I access this object?
More detail
The above description is based on my current project. The project is to create something like Selenium IDE. It uses WebBrowser control instead.
Selenium IDE creates 3 different things to record an element in the web document.
1. actionType
2. xpath
3. value
For instance,
type, //input[#id=foo], "hello world"
clickAndWait, //link=login, ""
Selenium IDE recognize page load so it changes actionType between "click" and "clickAndWait". My case, I want to make it simple.
If I click on the element and if it is anchor tag or has page load kind of javascript
such as onclick=window.location.href='blah' then I want to set the actionType to "clickAndWait".
There are number of ways you can do it.
There is an Event object in DOM, which will give you information about which element generated this event.
You can look at here, http://msdn.microsoft.com/en-us/library/ff975965%28v=VS.85%29.aspx
This one is good, you can use this easily, you will get the event object as method parameter which you can investigate parameters to find out the source of the event. http://support.microsoft.com/kb/312777
Another alternative is to use a custom navigation url and act upon it
Override BeforeNavigate event
Check for Navigation url if it contains "mycommand:click" or "mycommand:clickandwait" 3. If it contains any of this, then set cancel as true. (this will stop navigation by browser).
Then you can navigate your webbrowser code from your C# code and pass cancel as true.
Another Alternative method is to use External object, WebBrowser allows you to set an ObjectForScripting which you can access within Javascript of HTML.
ObjectForScripting in .NET 2.0
[ComVisible(true)]
public class MyClass
{
// can be called from JavaScript
public void ShowMessageBox(string msg){
MessageBox.Show(msg);
}
}
myBrowser.ObjectForScripting = new MyClass();
// or you can reuse instance of MyClass
And you can call,
window.external.ShowMessageBox("This was called from JavaScript");
Cast the element object to mshtml.IHTMLDOMNode, then read the attributes via IHTMLDOMNode.attributes. HtmlElement.GetAttribute is getting the IDispatch interface of the jscript function generated from the embedded attribute.
As per Sheng Jiang's response, here is some working sample:
IHTMLElement element = YourCodeToGetElement();
string onclick = string.Empty;
IHTMLDOMNode domNode = element as IHTMLDOMNode;
IHTMLAttributeCollection attrs = domNode.attributes;
foreach (IHTMLDOMAttribute attr in attrs)
{
if (attr.nodeName.Equals("onclick"))
{
string attrValue = attr.nodeValue as string;
if (!string.IsNullOrEmpty(attrValue))
{
onclick = attr.nodeValue;
break;
}
}
}
You can try to parse webBrowser1.DocumentText property using HtmlAgilityPack and then get desired result using XPath.
If you don't HAVE to do it with C# (you can do it with JS and create a Postback) you should take a look at THIS question.
You can parse it yourself easily, by first reading obj.outerHtml. That should give you the entire html for that obj, then search it for the value onclick="????" and extract the ???? part.

ScriptManager, Page, static methods... how do I get the current ScriptManager without Page?

I'm trying to extend ScriptManager to simplify dealing with resources that have multiple resource files (e.g. more than one script file as well as css). The goal is that I will be able to add a single ScriptReference to Scripts and have it load more than one resource related to that reference name.
What I'm getting stuck on is, how does your basic ScriptManager know what to do with stuff when when using static methods that do not include a Page parameter? For example:
ScriptManager.ScriptResourceMapping.AddDefinition("someName", new
ScriptResourceDefinition { Path="/script/somescript.js"});
This adds a definition to (I guess) whatever the active script manager is for the page that's running when you call it. But unlike the old-school methods, like RegisterClientScriptBlock there is no parameter passed that identifies the page. But this stuff must get stored in the ScriptManager object, no? So how does it know?
I could always get a reference to the active one with this:
ScriptManager.GetCurrent(page);
but ideally, I would create new methods that work exactly like Microsoft's. I can't figure out how I could implement something like
ScriptManager.ScriptResourceMapping.AddDefinition(string name,
ScriptResourceDefinition definition,
ResourceType type)
that could figure out the object instance to add the stuff into without having to add a Page parameter. Somehow they're doing it... how can I?
You get the page reference through (Page)(HttpContext.Current.Handler) even in a static context.

How to access the current [web] page (outside of the current page)?

The situation is this:
I have an abstract class used globally that used to reference a Session variable via a public property. We now want to change its behavior to return a property on a master page.
(By simply changing the guts of this particular property, we hope to avoid doing a lot of rewrites)
This is just a snippet of the class:
public abstract class AppSession
{
public static CaseNumber CurrentCaseNo
{
/* OLD METHOD DELETED */
get
{
if (CurrentPage.Master != null)
// property on the master page
return CurrentPage.Master.CurrentCaseNo;
else
throw new Exception("This page has no master page");
}
}
}
Above, "CurrentPage" is not real/valid. I just wrote that there to show context.
Is this even possible?
Thanks!
J
Look at the HttpContext.Current object. I believe it's Handler property will return the currently executing page. It would be easier to read a value stored in the Session that pulling it out of a property since the Session is available off of HttpContext.Current.
Building on David's answer, this can be used statically throughout your application:
Page myPage = System.Web.HttpContext.Current.CurrentHandler as Page;
if( myPage != null )
return ((MyMaster)myPage.Master).CurrentCaseNo;
I think that you would need to work with something that took a "page" object in as a parameter, and from there, you could determine if the page that was passed is your master page. And do what you need from there....
But that adds quite a bit of overhead.
The real question here is what are you trying to avoid? Trying to get rid of session and move to viewstate?

ASP.Net and GetType()

I want to get a type of a "BasePage" object that I am creating. Every Page object is based off BasePage. For instance, I have a Login.aspx and in my code-behind and a class that has a method Display:
Display(BasePage page) {
ResourceManager manager = new ResourceManager(page.GetType());
}
In my project structure I have a default resource file and a psuedo-translation resource file. If I set try something like this:
Display(BasePage page) {
ResourceManager manager = new ResourceManager(typeof(Login));
}
it returns the translated page. After some research I found that page.GetType().ToString() returned something to the effect of "ASP_login.aspx" How can I get the actual code behind class type, such that I get an object of type "Login" that is derived from "BasePage"?
Thanks in advance!
If your code-beside looks like this:
public partial class _Login : BasePage
{ /* ... */
}
Then you would get the Type object for it with typeof(_Login). To get the type dynamically, you can find it recursively:
Type GetCodeBehindType()
{ return getCodeBehindTypeRecursive(this.GetType());
}
Type getCodeBehindTypeRecursive(Type t)
{ var baseType = t.BaseType;
if (baseType == typeof(BasePage)) return t;
else return getCodeBehindTypeRecursive(baseType);
}
After some additional research I found that if I call Page.GetType().BaseType it returns the code-behind type of the Aspx page.
page.GetType().BaseType, it has been said before, but let me elaborate as to why.
Aspx pages inherit from their code-behind pages, meaning that the inheritance hierarchy looks like this:
...
Page
BasePage
Login
ASP_Login
Where the top is the parent and the bottom is the child.
This allows your code behind to be accessible from the aspx page, without requiring all of the generated code related to your actual aspx page to be copied into the base class page.
It depends where you're calling Display() from. If you're calling it from the ASPX, then you'llse "ASP_login.aspx". If you're calling it from the code-behind (i.e. the Page_Load() method) you should get the Login page type.
Instead of passing the Page in, you might consider just using the Page property (i.e. this.Page.GetType()) which should always be the current page/codebehind type, if I recall correctly.
I should also make the point that you might consider moving this sort of stuff out of the ASPX/codebehind and into some sort of service. It's generally a good idea to minimize the amount of things you do in a code behind and, instead, push logic into a presenter class and follow the MVP pattern for ASP.NET Web Forms development.

Categories