chris78
Goto Top

Javascript engine in .net

Hallo,
ich entwickele eine .net Anwendung mit integrierter javascript engine, dieV8ScriptEngine.
nun möchte ich aus Javascript ein POST REST call starten und den Result in dem Javascript auswerten, gegebenenfalls einen neuen Call starten. Das ganze funktioniert über XMLHttpRequest.
var engine = new V8ScriptEngine();
FetchWrapper fetchWrapper = new FetchWrapper(engine);
engine.AddHostObject("fetchWrapper", fetchWrapper);
engine.AddCOMType("XMLHttpRequest", "MSXML2.XMLHTTP");
Nun möchte ich aber lieber den httpclient von .net benutzen und habe einen Wrapper gebaut, der mir diesen .net httpclient in der javascript engine bereitstellt. Das ganze funktioniert allerdings nur in eine Richtung. Wenn ich den Result haben möchte, bleibt das JSON immer leer.

Hat jemand zufällt ein kleines Beispiel, wie man das umsetzen könnte?, wie gesagt es soll mit REST json funktionieren...

Content-ID: 7536273057

Url: https://administrator.de/contentid/7536273057

Ausgedruckt am: 26.11.2024 um 01:11 Uhr

7426148943
7426148943 15.06.2023 aktualisiert um 14:32:56 Uhr
Goto Top
Moin.
Wenn ich den Result haben möchte, bleibt das JSON immer leer.
Vermutlich weil du den Async-Task nicht abgewartet hast
Ganz einfaches Beispiel ...
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Http;
using System.Text.Json.Nodes;

namespace httpclient {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private async void Form1_Load(object sender, EventArgs e) {
            try {
                // get json
                JsonNode json = await GetJSON(@"https://domain.tld?output=json");  
                if (json != null) {
                    MessageBox.Show((string)json["yourproperty"]);  
                }
            } catch (Exception ex) {
                MessageBox.Show("EXCEPTION:" + ex.Message);  
            }
        }
        // function to fetch json
        private async Task<JsonNode> GetJSON(string url) {
            using (HttpClient client = new HttpClient()) {
                client.DefaultRequestHeaders.UserAgent.Add(System.Net.Http.Headers.ProductInfoHeaderValue.Parse("mycsharpclient"));  
                string jsonstring = await client.GetStringAsync(url);
                JsonNode json = JsonNode.Parse(jsonstring);
                return json;
            }
        }
    }
}
Zeppel
chris78
chris78 15.06.2023 aktualisiert um 14:29:19 Uhr
Goto Top
hallo, vielen dank für die Rückmeldung, der Javascriptcode sieht so aus, funktioniert auch wunderbar mit dem XMLHttpRequest. Dr Ganze Aufruf passiert in der Javascriptengine:
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:8080/readNodes', true);  
xhr.setRequestHeader('Content-Type', 'application/json');  

// Erstellen Sie das zu sendende JSON
var data = {
  "nodeIds": ["ns=2;i=2020", "i=2258"]  
};
xhr.send(JSON.stringify(data));
logToFile("Start stringify"+xhr.send);  
xhr.onreadystatechange = function() {
logToFile("xhr.readyState "+xhr.readyState+"Status" + xhr.status);  
  if (xhr.status === 200) {
    // Die Anforderung war erfolgreich
    var responseText = xhr.responseText;

logToFile("response" +responseText );  
    // Umwandeln des Antworttexts in ein JSON-Objekt
    var responseJson = JSON.parse(responseText);

    var nodeValue = "";  
    for (var i = 0; i < responseJson.length; i++) {
      if (responseJson[i].NodeId == "i=2258") {  
        nodeValue = responseJson[i].Value;
logToFile(nodeValue);
        break;
      }
    }

    var xhr2 = new XMLHttpRequest();
    xhr2.open('POST', 'http://localhost:8080/writeValue', true);  
    xhr2.setRequestHeader('Content-Type', 'application/json');  

    // Erstellen Sie das JSON, das gesendet werden soll
    var data2 = {
        "Nodes": [{  
            "NodeId": "ns=2;i=2006",   
            "Value": "" + nodeValue  
        }]
    };
    xhr2.send(JSON.stringify(data2));

    xhr2.onreadystatechange = function() {
        if (xhr2.readyState === 4) {
            if (xhr2.status === 200) {
                // Die Anforderung war erfolgreich
                console.log("Value was successfully written");  
            } else {
                // Es gab einen Fehler bei der Anforderung
                console.error("Error writing value: " + xhr2.status);  
            }
        }
    };
  }
};


Das ist der Wrapper:
public class FetchWrapper
        {
            private readonly HttpClient _httpClient;
            private readonly V8ScriptEngine _engine;

            private dynamic onSuccessFunc;
            private dynamic onErrorFunc;

            public FetchWrapper(V8ScriptEngine engine)
            {
                _httpClient = new HttpClient();
                _engine = engine;
            
            }

            public void SetOnSuccess(dynamic onSuccess)
            {
                MessageBox.Show("onSuccesscall");  
                this.onSuccessFunc = onSuccess;
            }

            public void SetOnError(dynamic onError)
            {
                this.onErrorFunc = onError;
            }

            public void Fetch(string url, string method, string body, dynamic headersObject)
            {
                Task.Run(async () =>
                {
                    try
                    {
                     
                        HttpRequestMessage request = new HttpRequestMessage
                        {
                            RequestUri = new Uri(url),
                            Method = new HttpMethod(method)
                           
                        };

                        if (body != null)
                        {
                            request.Content = new StringContent(body, Encoding.UTF8, "application/json");  
                            MessageBox.Show(body);
                          
                        }

                        // Process headers
                        if (headersObject != null)
                        {
                            var headers = new Dictionary<string, string>();
                            foreach (var header in headersObject)
                            {
                                headers.Add(header.Key, header.Value);
                            }

                            foreach (var header in headers)
                            {
                                request.Headers.TryAddWithoutValidation(header.Key, header.Value);
                            }
                        }

                        HttpResponseMessage response = await _httpClient.SendAsync(request);
                        string content = await response.Content.ReadAsStringAsync();
                        MessageBox.Show("content:" +content);  
                        // Invoke the JavaScript function
                        if (onSuccessFunc != null)
                        {
                            onSuccessFunc.Invoke(content);
                            LogToFile("onSuccessFunc" + content);  
                        }
                        else
                        {
                            LogToFile("onSuccessFunc is null");  
                        }


                    }
                    catch (Exception ex)
                    {
                        // Invoke the JavaScript function
                        onErrorFunc.Invoke(ex.Message);
                    }
                });
            }
        }
dazu der Javascriptcode, der zwar ausgeführt wird, aber der Result kommt halt nicht an. Vermutlich liegt das am await, aber das Interessiert die Engine scheinbar nicht.
var data = { "nodeIds": ["ns=2;i=2020", "ns=2;i=2023"] };  
var response = await fetchWrapper.fetch('http://localhost:8080/readNodes', 'POST', JSON.stringify(data), {'Content-Type': 'application/json'});  
var nodes = JSON.parse(response);

var nodeValue ="";  
for (var i = 0; i < nodes.length; i++) {
    if (nodes[i].NodeId === "ns=2;i=2023") {  
        nodeValue = nodes[i].Value;
        break;
    }
}

//log(nodeValue); // Gibt den Wert der Node mit der ID "ns=2;i=2023" aus 

var data2 = {"Nodes": [{"NodeId": "ns=2;i=2006", "Value": ""+nodeValue} ] };  
var response2 = fetchWrapper.Fetch('http://localhost:8080/writeValue', 'POST', JSON.stringify(data2), {'Content-Type': 'application/json'});