WebView2, expose JavaScript API under window instead of window.chrome.webview.hostObjects - c#

When using WebView2 it's possible to call C# methods from JavaScript on the web page by exposing a C# class in WebView2 under window.chrome.webview.hostObjects.sync.NameOfMyApiInterface.
Where you can name the NameOfMyApiInterface what ever you like using:
this.MyWebView2Control.CoreWebView2.AddHostObjectToScript("NameOfMyApiInterface", this);
But I've seen those using other 3rd party Chromium browser plugins putting their API directly under window, like window.NameOfMyApiInterface.
Is this possible using WebView2?

Yes. Although calls to CoreWebView2.AddHostObjectToScript will create proxy objects in script on chrome.webview.hostObjects, you can copy those objects wherever you like. You can make a property on window and have it point to the same proxy object.
For example, if you have an object NameOfMyApiInterface that has a property named Property with value "Example":
console.log(chrome.webview.hostObjects.sync.NameOfMyApiInterface.Property); // 'Example'
window.NameOfMyApiInterface = chrome.webview.hostObjects.sync.NameOfMyApiInterface;
console.log(window.NameOfMyApiInterface.Property); // 'Example'
If you call CoreWebView2.AddHostObjectToScript before navigating to the page that will use NameOfMyApiInterface, you can update that page to do the assignment at the top before other script runs. Or if you don't own or can't update the page, you can use CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync to add the line of script that does the assignment to run before any other script in that page.

Related

Get reference to instance of the calling aspx from ashx in ASP.NET WebForm

I'm in the code behind of a generic http handler (.ashx) and I'd like to get a reference to the instance of the calling .aspx page, so I can call some methods/get some properties of it. I can easily call static methods of the page, but I'm not able to get the actual object instance.
Is there a way, without resorting to services/webmethods/whatnot? Thanks!
EDIT:
I call the ashx from the JS inside the aspx page
$.ajax({
url: "handler.ashx",
context: "my content"
}).done(function() {
alert("Done");
});
Then I update an asp:Label with the result of it.
I've found a way to do it anyway (you can do it via JQuery from JS for instance), but now I'm curious if you can do it from the code behind simply calling some pageInstance.setMyLabel(ashxResult) or something like this.
There is no direct way to modify the contents of your calling .aspx-page via server-side code.
You should (like you mention yourself) process the results of the call to your .ashx-handler with javascript.
If you would like to use some results 'serverside' I think the only option is that you write some data to the session-object during the processing of the .ashx-handler.
On the next postback of the .aspx-page you could use that data to accomplish some change. If you would like to do that, please refer to this question also:
How to access Session in .ashx file?
The instance of the page class only exists for as long as it takes to process the request and send the response back to the client. By the time the Javascript code executes and makes a request to the ashx file, the page instance has been destroyed.
ASP.NET Page Life Cycle Overview | Microsoft Docs

Setting Label manually in Sentry

I'm using Sentry for logging errors etc. It works fine when creating a SentryEvent with a supplied Exception object. I'm trying to create ones that do not come from an exception, just a condition that needs to be flagged up on the system.
To this extent I've set the exception to null and everything works fine, except that the issue has '' as its title. I can't find anywhere in the SentryEvent object that I can set as a title to avoid this.
How do I label an event manually?
The "title" or "label" provided in the web interface is the "message" property of the event.
If you are using the official Sentry client "SharpRaven", then use CaptureMessage method instead of CaptureException.
RavenClient.CaptureMessage("Whoops!")
If you're working on your own client, or simply use HTTP requests, then set the "Message" of the event in the JSON blob:
{
"message": "Whoops!"
}

Register ClientScriptBlock only once during multiple postbacks

In my asp.net websites I regular uses the following methods before actually adding either custom pieces of script or registering a js file:
IsClientScriptBlockRegistered(Type, String)
IsClientScriptIncludeRegistered(Type, String)
When a page requires a custom piece of script, somewhere during PageLoad I call IsClientScriptBlockRegisterd() followed by RegisterClientScriptBlock().
if (!Page.ClientScript.IsClientScriptBlockRegistered(typeof(Page), "myKey"))
{
// Start creating ScriptBlock //
// .. //
// Actually Register the script //
ToolkitScriptManager.RegisterClientScriptBlock(this, typeof(Page), "myKey",
sbScript.ToString(), false);
}
The above code is always called once during a postback.
When a user is on the related page, while staying on that page he can cause multiple postbacks (actual postbacks, not callbacks).
During a postback the GetRegisteredClientScriptBlocks method always returns an empty collection. So IsClientScriptBlockRegistered always returns false. Therefore, for each postback I have to recreate the custom scriptblock and re-register it with the page, and re-send it to the client.
Is there a way to register a custom scriptblock and let it exist at the client for as long as the user stays on the related page, or for as long as the users sessions is active?
Thanks in advance.
Assuming you are using ASP.Net WebForms, you may use the following property to ensure whether it is postback or not:
Page.IsPostback()
Alternatively, you may pass some sort of flag/cookie/hidden variable indicating that this particular page does not need any client scripts to be registered.

Calling a javascript function on pre_render

I am using prototype, and i have a function as follows:
MyJSClass.prototype.AddLetters = function()
{
}
I would like to call this from c# based on some conditions i need to evaluate on pre-render.
Hello you can try with this code
ClientScriptManager cs = Page.ClientScript;
String yourScript= "function();";
cs.RegisterStartupScript(this.GetType(), "key script", yourScript, true);
Since you can't directly call JavaScript code from C# - especially before the page is rendered, you need a way of:
communicating the requirement/condition to the JavaScript code
picking up and appropriately dealing with the requirement/condition at the right time.
For 1. I recommend using the ClientScriptManager to insert/modify a variable, although there are other options below.
For 2. you should probably add some javascript which will pick up the communication.
Options for 1.:
Add a field into the page
Add a script into the page (e.g. using the Client ScriptManager) which will set a variable
Inject the script into the page directly at the relevant point for it to run
set a flag in the C# which you then check when you receive an AJAX call (which you might use if it will change according to server-side rules while the page is open...)

How to use Skin.AddPageMessage() method?

I am developing a DNN module and I want to display an info message at the top of my ContentPane, not above the actual module. I have found that DotNetNuke.UI.Skins.Skin.AddPageMessage() should just do the thing. I am not getting the behavior I want though, the message just won't display at all.
There are few overloads of this method, one group accepting a Page object, the other one taking a Skin object.
public static void AddPageMessage(Page page, string heading, string message, ModuleMessage.ModuleMessageType moduleMessageType)
public static void AddPageMessage(Skin skin, string heading, string message, ModuleMessage.ModuleMessageType moduleMessageType)
I did take a look into the DNN source and found out that in the end they're actually using the same private static AddPageMessage(...) method, which just looks for a ContentPane within the provided control and adds a new ModuleMessage to the collection of its controls.
What should I pass as a Page or Skin parameter to get this correclty working?
Thanks ...
The private AddPageMessage method takes a fairly ambiguous "Control" as the first parameter. I believe that needs to be the current Skin, as it does a FindControl for ContentPane.
Doing something like this should get you a reference to the current skin:
var skin = Skin.GetSkin((PageBase)this.Page);
Skin.AddPageMessage(skin, "Header", "Message", ModuleMessageType.GreenSuccess);
the reason why the messages are not showing up is that you turned on "enable partial rendering" in the controlssetting of the modulecontrols.
If you are using AJAX (this is happening if you set the partial rendering to true) the DNN modulemessages are turned off from DNN itselfe.
Its enough if you have turned the partial rendering on just 1 control (dont have to be your control where you are acting from) on your page. DNN will wrap the whole page into ajax script manager and messages are not working anymore.
*EDIT 26.04.2012 10:45:
You can get the current ScriptManager by executing the following Code for example in you Page_Load(). If the manager is null, you dont have ajax enabled and the modulemessages should work. If bIsAjaxEnabled is true the modulemessages are disabled.
ScriptManager manager = AJAX.GetScriptManager(Page);
if (manager != null)
{
bool bIsAjaxEnabled = manager.SupportsPartialRendering;
}

Categories

Resources