Read object from web application in WebBrowser control in winforms application - c#

I'm working on creation of a winforms application which contains a WebBrowser user control.
The WebBrowser control navigates to a page in a web application which requests user authentication details. When the user name and password are input and the form submitted, the web application sends a request and, if authentication is successful, populates variables in an applicationValues object.
When the applicationValues object is instantiated, I want to read the object from the web application in the WebBrowser control back into my Winforms application and close the form containing the WebBrowser control.
Currently, this is working (the object gets created successfully in the web application) until the part where the applicationValues object should get passed back to the Winforms application; there I'm stuck.
Can this be done with this control? If not, are there any other approaches or workarounds I should be considering?

It can be done, but it will require some work on your part. First of all, the easiest way to pass data back and forth between the web browser control and whatever page is in it, is via window.external and invoke script. Of course you have to set the objectforscripting attribute in your user control.
Once you have done that you can freely send data 2 ways from javacript to .net via primitive types. Now for your object specifically, it may be worth your time to serialize it into a JSON string and then send it via window.external, and then deserialize into a counterpart object on the .NET side. You could use System.Web.Script.Serialization's JavaScriptSerializer Or of course you could use JSON.net to deserialize as well.
Here is the basic idea taken from the MSDN
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.ObjectForScripting = this;
webBrowser1.DocumentText =
"<html><head><script>" +
"function test(message) { alert(message); }" +
"</script></head><body><button " +
"onclick=\"window.external.Test('called from script code')\">" +
"call client code from script code</button>" +
"</body></html>";
}
public void Test(String message)
{
MessageBox.Show(message, "client code");
}
private void button1_Click(object sender, EventArgs e)
{
webBrowser1.Document.InvokeScript("test",
new String[] { "called from client code" });
}

Related

Close webview xamarin forms

I have implement payment method with return URL and using webview open URL with my app. Recent, I'am issue want auto close webview with response success or fail process payment.
I encountered this case. Here is the solution I found.
After creating the WebElement, we bind the Navigating event to a certain method.
MyPage.Source = link;
MyPage.Navigating += Webview_Navigating;
MyPage WebElment name.
link is my link address
.
Then we perform our transactions here.
private void Webview_Navigating(object sender, WebNavigatingEventArgs e)
{
var url = e.Url;
if (url.Contains("status=1"))
{
int ordID = 0;
//save order
}
}
For me, if the changed link address checkout status=1, the checkout is successful.
You need to call Url property in WebNavigatingEventArgs to catch the changed url
If useful, choose. Good Luck
Sure! You can get response form WebView.
I recommend you use HybridWebView (see: https://github.com/devsmadeofsteel/Plugin.HybridWebView) as alternative.
Examples:
In Xamarin page, create a browser add register a named callback, and add browser to page childs
HybridWebViewControl Browser = new HybridWebViewControl();
//You can load browser content by string or URL, here is string which you can hard code or store in resource files
Browser.ContentType = Plugin.HybridWebView.Shared.Enumerations.WebViewContentType.Internet;
Browser.Source = YourUrl;
Browser.AddLocalCallback(YourCallBackFunctionName, CallBackFunction);
When run, HybridWebViewControl will insert a function with the name you specified in
YourCallBackFunctionName, and the single parameter is string type. So, In JavaScript of the page loaded by YourUrl, you can call back with the specified CallBackFunctionName:
function AnyFunction() {
//...
YourCallBackFunctionName(YourStringParameter);
}
When you call YourCallBackFunctionName(YourStringParameter) in JavaScript, you can get YourStringParameter in CallBackFunction using C#.
So, you could define different CallBackFunctions or pass different parameters with single CallBackFunction, to control the HybridWebView and the page or view which contain it, such as hide HybridWebView or close the page.
Have a try!

Spotify authorization code flow (WPF browser control) C#

I'm using Spotify account service (authorization code flow) to get an authorization code by passing in the required parameters (client_id, response_type and redirect_uri. Its a WPF application so i am using the browser control and navigating the user to
https://accounts.spotify.com/authorize/?client_id=myclientId&response_type=code&redirect_uri=someUri
When i copy paste the link in the browser, i see the right stuff i.e page with the Login to Spotify button but when i am navigating through the browser control in my WPF application, it gives me a file download dialog with Authorize.json file to download with Open and Save options, however in some cases it presents the right page to browser code.
Below is my code:
public winOAuthBrowserForm(string navigateTo)
{
InitializeComponent();
webBrowser.Navigated += webBrowser_Navigated;
webBrowser.Navigate(navigateTo);
}
private void webBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
if(!String.IsNullOrEmpty(e.Uri.Query))
{
//since we are looking for code for authorization that will be exchanged for request token from the server
if (e.Uri.Query.StartsWith("?code=") || e.Uri.Query.Contains("code="))
{
code = HttpUtility.ParseQueryString(e.Uri.Query).Get("code");
this.Close();
}
if (e.Uri.Query.StartsWith("?error=") || e.Uri.Query.Contains("error="))
{
error = HttpUtility.ParseQueryString(e.Uri.Query).Get("error");
this.Close();
}
}
}
And i am calling this control like:
var uri = string.Format(SpotifyAuthUriFormatter, RequestAuthBaseUrl, clientId);
winOAuthBrowserForm form = new winOAuthBrowserForm(uri);
form.ShowDialog();
This is what i see:
UPDATE: When i right click on document and see the properties, i see it changes the URL to something like res://ieframe.dll/navcancl.htm#... I've searched it and found some solutions related to I.E (I'm using latest but you can't be sure that it'll be latest on client machines), some say that its firewall setting. The thing is, it appears sometimes only.
Any ideas? Thanks

Showing a status message generically within ASP.NET webforms

Within my site master I have an area where I would like to display status (info, success, error, warning) messages.
In my code behind I would like to make calls such as:
MessageSuccess("Some success message");
MessageSuccess("Another success message");
MessageWarning("Warning message");
and then have these messages all display when the page is next rendered.
I have tried a couple of approaches where I:
Save a structure in Session
Read the structure in Page_PreRender() and update some HTML controls
Clear the structure in Page_UnLoad()
However some of the time the messages show just fine, but some of the time by the time PreRender comes around Page_Unload() has been called and nothing displayed because the structure is empty.
Has anyone got a generic working solution that I can use with my WebForms project to "nicely" display status messages?
Once I was using something very close to example described in Displaying a Custom Error Message section of the Working with Partial-Page Rendering Events. It works nicely if you are dealing with asynchronous postbacks. The only downside is that it was designed for exception handling and not for success/warning/etc. notifications.
There is a property AsyncPostBackErrorMessage on ScriptManager which you can use to pass any text message back to the client. Client will retrieve the message in endRequest event handler:
Server code:
// inside Page code:
var scriptManager = ScriptManager.GetCurrent(this /* assuming that this is a Page instance */);
scriptManager.AsyncPostBackErrorMessage = "Hello world";
Client code:
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args) {
if (args.get_error() != undefined) {
var errorMessage = args.get_error().message;
args.set_errorHandled(true);
// Do whatever you need to display the message
}
}
Another possible solution would be to add client function calls to the page using ScriptManager.RegisterStartupScript. I can imagine that you can have a NotificationHandler JavaScript object which would have a success, warning, error, etc. functions which you will call from the server side:
protected void Page_PreRender(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this, GetType(), "<Some unique key for script>", "NotificationHandler.success(\"Hello world\")", true);
}

Simplest way to convert C# method to asynchronous call Page/Web Method or jQuery

I have a C# method from a web form that I want to call asynchronously with with either a Page Method, Web Method or possibly jQuery to avoid postback to the server. The method calls other methods and rebuilds a treeview and performs validation and sets some other values as well. Below is an example of the code.
What would be the simpleset way to do this?
Any code samples provided would be greatly appreciated if possible. No update Panels..
protected void btnSubmit_Click(object sender, ImageClickEventArgs e)
{
if (ValidateSelection() == true)
{
int ProductID = Convert.ToInt32(grdGetProducts.SelectedValue.ToString());
if (Convert.ToInt32(ddBetTypeID.SelectedItem.Value) != 2)
{
SubmitProduct(Convert.ToInt32(ddProductTypeID.SelectedItem.Value), currentWeek, Convert.ToInt32(ddProductID.SelectedItem.Value), Convert.ToInt32(ddValue.SelectedItem.Value), Convert.ToInt32(ddCost.SelectedItem.Value), ProductID);
}
if (Convert.ToInt32(ddProductTypeID.SelectedItem.Value) == 2)
{
int price;
price= 1;
//if 1 open side then part 2
if (txtProductID.Text != "0" && txt2ProductID.Text == "0")
{
price= 2;
}
if (ProductID > 2)
{
BuildTree(currentTime, Convert.ToInt32(ddProductID.SelectedItem.Value), currentProduct);
}
}
}
Without an update panel you are certainly going to need a lot of client side javascript.
I do things like this with dynamic tables all the time and the first thing I did was isolate my data and my display. You should start by doing the same.
Figure out what data is being validated and how you can gather it on the client to be sent to a web method. Then you need to write client scripts to do this gathering and posting. After you post with the client script, in the callback of the ajax call, you would then need to do the rendering on the page. Without an update panel this is all on you.
The issue you have without using an update panel is that you are going to have to recreate the treeview structure or manipulate it on the client side. This means replacing all the elements and their event handlers. This can be a very daunting task for the more complicated ASP controls.
What the server would need to send back for rendering would be all of the data the tree needs. It is on you to figure out what that is though.
I have dynamically rendered gridviews before because it is nice to use them to create complex styles. Then it is just a matter of creating rows with the script on the client, based on the data I get from the server; I imagine you can do something similar to this with a treeview.
I have learned a lot about jQuery, ajax and ASP.NET interactions by reading encosia.com. That individual is a wonderful resource.
Things to avoid using jQuery AJAX and ASP.NET
Mistakes: manual JSON serialization
Using jQuery to directly call asp.net page methods
Update Panels are Dangerous

Create new instance of a page and obtain URL

i'm a beginner web programmer. I've been coding desktop applications primarily.
Right now, i have created this web app, in Silverlight, that uses a web service of my own for querying the database. The thing is, one of the app functionalities is the ability to open PDF files. I know that silverlight won't let you do this, but using an IFrame on top of the silverlight application you are able to display a page with de pdf file (using acrobat plug in).
So here's the problem, my silverlight app passes the pdf path to the web service and, in return, the web service would create a new Page and pass the new page URI back so that it can be displayed on the IFrame:
Page Code Behing:
public partial class PDFViewer : System.Web.UI.Page
{
string Filename = string.Empty;
public Uri Uri
{
get { return HttpContext.Current.Request.Url; }
}
public PDFViewer(string filename)
{
Filename = filename;
}
protected void Page_Load(object sender, EventArgs e)
{
Response.ContentType = "Application/pdf";
Response.WriteFile(Filename); //Write the file directly to the HTTP content output stream.
Response.End();
}
}
WebMethod Code:
[WebMethod]
public string GetReport(string filename)
{
PDFViewer viewer = new PDFViewer(filename);
return viewer.Uri.AbsoluteUri;
}
this only returns the Web service URL.
So the main question is: How to create a page instance and obtain that page URL?
The solution to this might be here:
http://forums.silverlight.net/forums/p/76977/372282.aspx
"In my Silverlight app i open a new web browser by passing in query string my id and the page process it, query the db, retrieve the selected object and renders with the response methods."
I just don't know how to do it.
Any help is greatly appreciated.
Pedro
Maybe this will help.
wherever your silverlight object is embedded put an iframe with id="xContainer"
and from your silverlight code just set its scr to the pdf you're trying to display
HtmlPage.Document.GetElementById("xContainer").SetProperty("src", "http://google.com");

Categories