How can I pass data to/from a WebBrowser control? - c#

I've got a basic "wrapper" WinForms app which has a few basic controls and a WebBrowser control (System.Windows.Forms.WebBrowser). This links to a web service which does all the actual "work" of my application.
A requirement has arisen to pass some basic data between the applications. Some of this can be achieved using the DocumentCompleted/Navigated events and using the URL property to see what page was loaded, and redirect the request elsewhere.
However, I'm struggling to work out how I can pass data that is not easily encompassed in the URL.
Is there anyway to set cookies in the request, or at least access cookies from the response?

You can pass and get data by calling methods from passed object as ObjectForScripting.
Try this-
[ComVisible(true)]
public class MyScriptingClass{
private string SomeData;
public string GetSomeData(){
return SomeData + " Something";
}
public void SetSomeData(string some){
SomeData = some;
}
}
And set ObjectForScripting property of your webBrowser control -
webBrowser.ObjectForScripting = new MyScriptingClass();
Now, in your javascript code call the methods like this -
var someVarFromJs = window.external.GetSomeData();
window.external.SetSomeData("Something to set");

Related

How can I tell FindsBy to search elements on this particular sites

I've started learning Selenium Webdriver. It seems pretty easy but I'm not sure how to use PageObject Pattern. I understand the idea, I guess, but I don't know how to map many pages in one project. For example: the site contains many subsites (i.e. login page, create an account page) and I'd like to create PageObject for each of them. When I execute my script, I'm getting messages that elements haven't been found. What should I do? Should I create a separete drviers or what?
Seems that you are doing everything correct: create a new object for each page. Create different objects for common elements that are the same on a lot of pages (like footer, header menu, etc.).
Then to combine page objects, first you need to start somewhere. For example from you main page. So use the MainPageObj to interact wit the main page. As soon as you navigate to another page you need to use a method in your MainPageObj class.
This method must return a page object of the new page. So if you open a Login page from the main page then your method OpenLoginPage() should return LoginPageObj.
Example: MainPageObj and LoginPageObj are page object classes.
MainPageObj class has method:
public LoginPageObj OpenLoginPage()
{
LoginButton.Click();
return new LoginPageObj();
}
So use this method in this way:
MainPageObj mainPage = new MainPageObj ();
LoginPageObj loginPage = mainPage.OpenLoginPage();
Simple?)
If you want to make it more beautifyl then add static class Pages and add static methods for each page object you have to this class. Each method must return a new instance of your specific page object.
Example:
public static class RealSites
{
public static class Kinopoisk
{
public static Kinopoisk.MainPage MainPage
{
get { return new Kinopoisk.MainPage(); }
}
}
}
And in your tests use it this way:
Pages.RealSites.Kinopoisk.MainPage.OpenMoviePage(url);
Pages.RealSites.Kinopoisk.MoviePage.DoSomethigElseMethod();
You can refer this link to understand page object model and after this you can also create for your application
http://www.seleniumeasy.com/selenium-tutorials/simple-page-object-model-framework-example
If you want to learn then selenium easy is best site to learn for beginners.

How to get data from another page

The functionality exists in pageB.aspx and the parameters are passed from pageA. I'm failing to get the result of pageB. What should be done here.
pageA.aspx.cs:
string URI = Server.MapPath("~/pageB.aspx");
NameValueCollection UrlParams = new NameValueCollection();
UrlParams.Add("section", "10");
UrlParams.Add("position", "20");
using (WebClient client = new WebClient())
{
byte[] responsebytes = client.UploadValues(URI, "POST", UrlParams);
string responsebody = Encoding.UTF8.GetString(responsebytes);
}
when the compiler reads byte[], there is a dialog which asks if changes should be made to pageB. On clicking No, nothing happens. The string 'responsebody' is empty.
pageB.aspx.cs::
protected void Page_Load(object sender, EventArgs e)
{
if (int.TryParse(Request.QueryString["section"], out section)
&& int.TryParse(Request.QueryString["position"], out position))
{
ProcessData();
}
}
private string ProcessData()
{
string HTMLContent = string.Empty;
try
{
//some code to render the string.
return HTMLContent;
}
catch (Exception ex)
{
throw ex;
}
}
I would like to get 'HTMLContent' from pageB
Use HttpContext.Current.Request["Key"] instead of Request.QueryString["Key"].
if (int.TryParse(HttpContext.Current.Request["section"], out section)
&& int.TryParse(HttpContext.Current.Request["position"], out position))
{
ProcessData();
}
Having pageA 'load' PageB via a web request is probably not the best idea in the world.
My reasoning for this is that I have seen it done on various projects and you can run into all sorts of problems with the routing of the request and permissions.
Essentially the PageA->PageB request will be treated like a new user loading PageB, cookies, session variables etc will be lost unless you explicitly populate them. firewall rules, routing, load balancing etc will act in odd ways.
Any of these problems could cause your unexpected behavior of PageA
Instead : Move the functionality out of pageB into a service object and call it directly from where needed.
However : Say for some reason you are required to do it via a web request. Perhaps its not always on the same server or something.
It looks from your sample code like you are treating PageB as a webservice. You pass in the parameters and use the whole response. So you could if required expose the underling code, lets call it ServiceB as a WebServiceB and then reference it from PageA via the web request.
This would be 'allowed' as the encapsulation of the data as a WebSerivce make it obvious that PageB is not a page of itself and should not rely on variables such as session, cookies etc which are not explicitly passed in.
Further more the calling code, 'knows' that the webservice could be on any machine in the world and thus won't expect it to know about things unless they are explicitly passed.
If you do change PageB to a service and you still need a stand alone PageB which returns HTML. Simply make a new PageB which calls ServiceB behind the scenes. This allows you to separate your 'view' logic from the data/logic provided by the service
Try using Session if you want to pass any type of data between different pages.
EDIT :
Since Session wont be working in your case, you could also try using WebCache instance to store information and access it across other pages.
This link might help here : MSDN : WebCache
Hope this helps.

How to send debug text from C# class to ASP.NET page

I am working on a C# class that is a part of my ASP.Net Web Site.
Is there a simple way to output some log/debugging text to the top of the page. My class does NOT inherit from Page. I want to display variable values, etc.
The class represents an Exam object that I use in some of my aspx pages. The variables that I want to display are private and therefore inaccessible to my aspx pages.
Anywhere in the context of an http request you can reach the current executing page as follows.
Page page = HttpContext.Current.Handler as Page;
You are free to cast to your own page type. So you can write debug info to labels, textboxes etc.
you can just do this
HttpContext.Current.Response.Write("your message goes here");
or write a helper method
public static void writeOut(string message) {
HttpContext.Current.Response.Write(message);
}
You can try with Response.Write method
var pathOfYourLog = "";
var log = File.ReadAllLines(pathOfYourLog);
YourHttpContext.Response.Write(log);

How do I associate some custom data with current HttpRequest?

I need to somehow attach my custom data to the HttpRequest being handled by my IIS custom modules - so that code that runs in earlier stages of IIS pipeline attaches an object and code that runs in later stages can retrieve the object and use it and no other functionality of IIS pipeline processing is altered by adding that object.
The data needs to persist within one HTTP request only - I don't need it to be stored between requests. I need it to be "reset" for each new request automatically - so that when a new request comes it doesn't contain objects my code attached to the previous request.
Looks like HttpContext.Items is the way to go, although MSDN description of its purpose is not very clear.
Is using HttpContext.Current.Items the way to solve my problem?
This should work - I have done this in a project before.
I have a class which has a static property like this -
public class AppManager
{
public static RequestObject RequestObject
{
get
{
if (HttpContext.Current.Items["RequestObject"] == null)
{
HttpContext.Current.Items["RequestObject"] = new RequestObject();
}
return (RequestObject)HttpContext.Current.Items["RequestObject"];
}
set { HttpContext.Current.Items["RequestObject"] = value; }
}
}
And then RequestObject contains all my custom data so then in my app I can do
AppManager.RequestObject.CustomProperty
So far I have not come across any issues in the way HttpContext.Items works.

Passing parameters from silverlight to ASP.net

I've made a little game in silverlight that records users scores whilst they play.
I decided it would be a lot better if I could implement a leaderboard, so I created a database in mySQL to store all the high scores along with names and dates. I have created some communications to the database in ASP.net. This works and I can simply insert and get data within the code.
It's now time to link the silverlight project with the ASP.net database communications, so I can send the users name and score as variables to my ASP.net code and then it will upload it to the database. That's all I need. Surely there must be an easy way of doing this, I just can't seem to find any ways when researching.
Thanks in advance,
Lloyd
At first you need add Generic Handler to your ASP.Net project.
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string userName = context.Request["user"];
int score = int.Parse(context.Request["score"]);
//And store it in DB
}
}
After you need call this handler from SilverLight app:
string uri = HtmlPage.Document.DocumentUri.ToString();
// Remove the web page from the current URI to get the root URI.
string rootUri = uri.Remove(uri.LastIndexOf('/'),
uri.Length - uri.LastIndexOf('/'));
string diggUrl = String.Format(rootUri + "/" + "test.ashx?user={0}&score={1}", "testuser", "234");
// Initiate Async Network call to Digg
WebClient diggService = new WebClient();
diggService.DownloadStringAsync(new Uri(diggUrl));
here i used Uri Class to send parameter to asp.net, but you can send string format only.
// this code written on Silverlight Button Click Event.
Uri myURI = new Uri(HtmlPage.Document.DocumentUri,String.Format("Report.aspx?brcd={0}&acc={1}&user={2}", Brcd, Acc, User)); HtmlPage.Window.Navigate(myURI, "_blank");
below code is written on Asp.net page_load or page init event
Brcd = Request.QueryString["brcd"];// brcd value accept here.
acc= Request.QueryString["ACC"];`
user= Request.QueryString["User"];
in above code we accept the silverlight parameter in asp.net but in [] bracket put name as it is use in silverlight page because it case sensitive.
By ASP.NET, do you mean an ASP.NET Webforms app?
If so, an ASP.NET Webforms app is a method of building a UI. What you need is an API, for your Silverlight app to use programatically. For this purpose you may want to consider building an ASP.NET Webservice instead, which provides an API over HTTP.
What do you need its to send data to web server from a Silverlight application, right?
You can:
Call Javascript functions from Silverlight and, there, do a postback
Call web services with Silverlight, but make sure its in same server which your SL application came from, or you will face some XSS issues.
An easy way to do this is to have your Silverlight code create a REST URL by encoding the information into the query string, and invoking an .aspx page on the server. The page wouldn't need to return any markup; it would just handle the back-end stuff and return.
Alternatively, you could make a web service call from Silverlight to your back end.
I prefer the latter approach. It's a little more work the first time through, but it's also more general purpose and makes for generally better code in the long run.
Although technically you could use JavaScript, I wouldn't suggest it; why go backwards in tech if you don't have to?

Categories

Resources