Sorry for stupid question,
I just want to pass a JOSN string to the webpage in the webbrowser from my VB/C# code,
and can the javascript in webpage call the VB/C# method through some interface ?
Just like android javascript interface, many thanks
If I understand you correctly,
webBrowser2.ObjectForScripting = new ScriptClass();
webBrowser2.DocumentText = "<html><script>window.external.Test('hello')</script></html>";
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class ScriptClass
{
public void Test(string msg)
{
MessageBox.Show(msg);
}
}
So you're using a WebBrowser control and need to call a JavaScript method within the page it shows? Yeah, you can do this. It's not on the WebBrowser itself, but the HtmlDocument object, exposed by the WebBrowser's Document property, has an InvokeScript() method group, which will allow you to programatically invoke any ECMAScript-compliant method within the DOM of the page, optionally passing a series of parameters as an Object array.
That, in turn, can be used to trigger a call from JavaScript to a JSON web service (which you expose in your main CLR program, and told the page about by passing it the info via InvokeScript()). This is basic JSON/AJAX client-server scripting, all wrapped up into a single program talking to itself. It's not the most efficient way to get things done, but if you already have these layers that get the job done, and just want to release a self-contained app, it works.
Related
Could somebody please let me know how static methods work in regard to calling C# methods from JavaScript using JS interop?
If I have a static method in the code section of a component that references objects in that component, and there are multiple instances of that component on a page, will all instances be affected by the method call?
Or even worse, will this act as a Singleton on my server causing updates to every single client instance of that component?
I'm currently developing an audio recording system that cycles through phrases marked in text, and whenever JavaScript detects 5 frames of silence in the media stream, I want to call a C# method that will highlight the next section of text by changing its CSS class.
If you want to change some styles in your component, you definitely not want to use a static method. Because a static method could not interact with the instance of the component - as you cannot use the this keyword in a static method.
What I think you want to do is first, in C# side, create a classic method in your component C# code. For example create:
public void ChangeStyle()
{
this.ClassToDisplay = DoSomeManipulation();
}
Then, JS will need the instance of the the component. So you can do something like that: (I use the OnAfterRenderAsync because it is shown in Microsoft documentation, but the goal is to do it once)
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
DotNetObjectReference<MyComponent>? dotNetHelper = DotNetObjectReference.Create(this);
await JS.InvokeVoidAsync("JSFile.setDotNetHelper", dotNetHelper);
}
}
Then in JS side, you will need the setDotNetHelper method, with the following content:
class JSFile
{
static dotNetHelper;
static setDotNetHelper(value)
{
JSFile.dotNetHelper = value;
}
}
Now you are ready, you can call whenever you want the ChangeStyle method of your component. To do so, use this instruction in JS:
await dotNetHelper.invokeMethodAsync('ChangeStyle');
Et voilĂ . I am available for clarifications or questions, have a good one!
// Dylan
I have a third party application that I'm interacting with via a WCF service that they're exposing. When my application is loaded, the WCF service is supposed to hook into the callbacks I've defined and give me data back. This is straight-forward in VB but I think my issue is syntax in accomplishing this in C#.
Their documentation states the following: Your user control will need to define an internal event with a signature that matches the event that our service is listening for.
Here are my declarations for the handler, as provided by this services' documentation:
public delegate void MyDel(ref string Param1, ref string Param2);
public event MyDel GetInfo;
The documentation then says that I should be able to call this event in the following fashion, and the data I need from the service will be inside of the output variable I pass in by reference:
string output = "";
string methodName = "SpecificAction"
// this is null and throws an exception
// i've tried wrapping it in an if != null block to no avail
GetInfo(ref methodName, ref output);
Console.WriteLine(output.ToString());
In VB the following works without issue:
Public Event GetInfo (ByRef EventName As String, ByRef XmlString As String)
Dim Output As String = ""
RaiseEvent GetInfo("SpecificAction", Output)
The reason that I think I'm doing something wrong with the C# syntax is, as I said, it seems to work in VB just fine. Any suggestions would be appreciated.
Update
So I'm calling this method from my controls' public constructor, which is failing. If I move this exact code inside of a button click handler, for instance, its returning the data that I expect. I'm guessing my program is initializing and hitting that call before their service has hooked in? Is there a way to wait for that to happen?
After seeing that the above code worked when I removed it from my constructor and placed it in a button click handler, I realized that the issue was probably that I was trying to access the data before the service had hooked into it. By instead placing the code inside of my controls Load event, I was able to get back the data I needed.
I have played around with the Miniprofiler recently. It works fine in our application, and have found some interesting things we're working on.
However, I have a use case, where I need to make a custom injection with a record, where I can set the duration.
In the picture below, you can see the "hack" I've made to show it right now, but I'd like it to show correctly:
My situation
I am consuming a third party API. Every single page has a lot of calls, and is called from different views.
The API has a .NET client, which has a delegate that's called after it's dine:
private static void LogApiRequest(string httpMethod, string url, TimeSpan duration)
The issue is this method obviously is just used for logging, but I'd like to inject a duration here.
Any idea how to do it? :-)
if I understood well, just surround your API's calls with the following code:
ApiClient thirdPartyClient = new ApiClient();
using (profiler.Step("Calling third party API Methods"))
{
thirdPartyClient.MethodX();
}
Or, using custom categories:
ApiClient thirdPartyClient = new ApiClient();
using(MiniProfiler.Current.CustomTiming("3rd Party API","API.MethodY")
{
thirdPartyClient.MethodY();
}
I'm trying to write a code in C# which implements Brute-Force Attack to my temporary webpage in order to try crack the login system.
Something like this:
private void buttonHack_Click(object sender, EventArgs e)
{
while (!found)
{
textBox_pw.Text = guess;
guesser.NextGuess();
webBrowser1.Document.GetElementById("user_id").SetAttribute("value", textBox_ID.Text);
webBrowser1.Document.GetElementById("password").SetAttribute("value", textBox_pw.Text);
webBrowser1.Navigate("javascript:enter();");
guess = new String(guesser.CurrentGuess);
}
}
// 'guess' and 'guesser' are for the BF Attack.
But apparently WebBrowser doesn't 'fire' until the method that it's called inside of returns. I have tried to put the part inside the while loop into the Webbrowser_DocumentCompleted event, so that it would literally loop (as when the page load is completed then do the same again and again...) But this way had its issues, like if the page document gets completed fast then it skips the rest of the code and goes to the top of DocumentCompleted method, and as the result weirdness!!!
So any neat ideas how to fix it?
Generally, Brute-Force attacks are not done by manipulating the web page itself, but rather by generating traffic to the server that does the credential validation (unless of course you are validating on the client in which case a simple javascript code review will suffice).
Code is written that mimics the webbroser control's interaction with the server (in order to tap into SSL-protected traffic).
You can not do a loop like this because .Navigate is an async method. You need to subscribe to the DocumentCompleted event on the brwoser control and do your work there.
Also, I'm unsure wheter .Navigate will take a javascipt: location.
I am in a bit tricky situation. I am using JavaScript's PageMethod functionality where I am invoking a PageMethod which works like a gem. However I am having an issue in accessing the HttpContext's state which returns me a value "SYSTEM" for
HttpContext.Current.User.Identity.Name
which is not the actual current User Name.
I know there are couple options like storing HttpContext.Current in a Session or saving Context's state in some other custom container but given a web farm environment I am assuming that this will not work as expected.
Here is the code I am working on with
function MyFunction(){
PageMethod.MyPageMethod();
}
here is the signature of the server method
[System.Web.Services.WebMethod()]
public static void MyPageMethod()
{
// gives me "SYSTEM"
var user = HttpContext.Current.User.Identity.Name;
}
Also if I use the above code to access user name in OnLoad event of the page then it works fine and returns me the CurrentUserName.
I am trying to get the above code to work in an ASP.NET Webform... :)
So I am wondering if there is a way to access the current actual user in page methods without making use of sessions.
Any help will be deeply appreciated.
NiK...
After quite some reading I think I was trying to do something which is not correct as to how page methods work. It gets quite tricky when your application's authentication system is windows based and these page methods when you invoke from JavaScript will not cause a postback and do not invoke the HttpModules. Instead it just calls that page method.
FYI, we had our own custom HTTPModule to handle security.This is even before any other HttpModule occurs and this was not being invoked while calling the page method as we are not doing a postback or even a partial postback (so the whole "niche" of a HTTPPost was missing). Moreover this led to a conclusion that we were making service calls without any authentication and was potentially a big security issue for us.
The bottom line is it was a bad design, well having said that I would like to mention about the solution/workaround we came up with and here is what we did. So, the only option we had is to do a postback keeping the UI alive and we wanted to update a label's message asynchronously and we achieved it by doing a hack using Sys.Application.add_init.
<script language="javascript" type="text/javascript" >
Sys.Application.add_init(function() {
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);
});
function beginProcess() {
processCurrentItem();
}
var currentItem = 0;
function processCurrentItem() {
if (currentItem < 5) {
currentItem = currentItem + 1;
__doPostBack('updatePanel', currentItem);
}
}
function endRequest() {
processCurrentItem();
}
</script>
The markup we had in place was pretty simple with a label in the update panel and a button that invokes the "beginProcess()" function. Finally in the OnLoad we had the following code in place
protected override void OnLoad(EventArgs e)
{
if (this.IsPostBack)
{
this.lblLabel.Text = "text you may wanna update with";
// Call the Method you may wanna call
// also you may use Request["__EVENTARGUMENT"] to know who caused the
// postback and Request["__EVENTTARGET"] to access the argument you may
// have passed in.
}
}
And this solution is no longer using the JavaScript Page methods. And based on this solution if anyone thinks I am missing something here or think there is any other other way of doing this then do update this post with your suggestions.
NiK