如何使用JeringTech/JavaScript.NodeJS调用node在.NET API中运行js代码?

gtlvzcf8  于 2023-10-17  发布在  Node.js
关注(0)|答案(2)|浏览(132)

bounty已结束。回答此问题可获得+150声望奖励。赏金宽限期17小时后结束Oliver Drummond希望引起更多的注意这个问题。

我希望能够在我的后端.NET API中执行JavaScript代码,所以我尝试按照这些步骤创建了一个.NET API,如下所示:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Jering.Javascript.NodeJS;
using System.Net;

namespace NodeJSTestAPI.Controllers
{
    [ApiController]
    [Route("testNodeJS/")]
    public class TestNodeJSController : ControllerBase
    {
        private readonly ILogger<TestNodeJSController> _logger;

        public TestNodeJSController( ILogger<TestNodeJSController> logger)
        {
            _logger = logger;
        }

        [HttpGet("invokeTest/")]
        [ProducesResponseType(typeof(object[]), 200)]
        public async Task<IActionResult> InvokeTest(string testString)
        {
            Result? result = await StaticNodeJSService.InvokeFromStringAsync<Result>("module.exports = (callback, message) => callback(null, message);", args: new[] { "success" });

            return Content(result.Message, "application/json");
        }
    }

    public class Result
    {
        public string? Message { get; set; }
    }
}

我希望一旦我从postman请求GET API_URL/testNodeJS/invokeTest/,它就会运行指定的JavaScript代码,但是我得到了一个500错误,下面是例外:

System.Net.Http.HttpRequestException: No such host is known.
 ---> System.Net.Sockets.SocketException (11001): No such host is known.
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Jering.Javascript.NodeJS.HttpNodeJSService.TryInvokeAsync[T](InvocationRequest invocationRequest, CancellationToken cancellationToken)
   at Jering.Javascript.NodeJS.OutOfProcessNodeJSService.TryInvokeCoreAsync[T](InvocationRequest invocationRequest, CancellationToken cancellationToken)
   at Jering.Javascript.NodeJS.OutOfProcessNodeJSService.InvokeFromStringAsync[T](String moduleString, String newCacheIdentifier, String exportName, Object[] args, CancellationToken cancellationToken)
   at NodeJSTestAPI.Controllers.TestNodeJSController.InvokeTest(String testString) in C:\Users\nunebr\Documents\git-workspace\supply-chain-planning-tool\planning-apps-back-end\NodeJSTestAPI\Controllers\TestNodeJSController.cs:line 28
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS
=======
Connection: Keep-Alive
Accept: */*
Accept-Encoding: gzip, deflate, br
Host: localhost:44393
User-Agent: PostmanRuntime/7.33.0
Postman-Token: a1a9a285-d633-41dd-a6d7-e02c04d8024e
MS-ASPNETCORE-TOKEN: b0d6204e-859a-41b1-90e8-0b350697c062
X-Original-Proto: http
X-Original-For: 127.0.0.1:55630

有人知道我在这个问题上可能错过了什么吗?
在另一个单独的说明中,我曾经在不同的笔记本电脑上运行过相同的代码,但是由于我需要更换笔记本电脑,我不能让它再次工作,所以不确定是否是一些网络配置问题阻止了我的.NET API访问调用的NodeJS。
任何帮助将不胜感激。
提前感谢!

qpgpyjmq

qpgpyjmq1#

您的问题可以通过阅读记录的消息来解决。日志记录通过依赖注入启用。
下面是一个在. net7.0下的简单控制台应用程序的示例

using Jering.Javascript.NodeJS;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace ConsoleApp;

internal class Program
{
    static async Task Main(string[] args)
    {
        string javascriptModule = @"
module.exports = (callback, x, y) => { // Module must export a function that takes a callback as its first parameter
    var result = x + y; // Your javascript logic
    callback(null /* If an error occurred, provide an error object or message */, result); // Call the callback when you're done.
}";
        var services = new ServiceCollection();
        services
            .AddNodeJS()
            .AddLogging(opt =>
            {
                opt.SetMinimumLevel(LogLevel.Trace)
                   .AddSimpleConsole();
            });
        StaticNodeJSService.SetServices(services);

        var result = await StaticNodeJSService.InvokeFromStringAsync<int>(javascriptModule, args: new object[] { 3, 5 });

        Console.WriteLine($"Complete with result {result}");
    }
}

为了让它工作,我们需要再添加两个nuget包。

dotnet add ConsoleApp package Jering.Javascript.NodeJS --version 7.0.0.0
dotnet add ConsoleApp package Microsoft.Extensions.Logging.Console --version 7.0.0

如果在破译输出时出现问题,可以将控制台输出附加到问题

oxosxuxt

oxosxuxt2#

我不确定这是否能解决整个问题,但您应该从查看端点配置开始。目前,您的代码需要string testString作为GET方法的参数,但您没有在定义中提供。尝试将代码更改为:

[HttpGet("invokeTest/{testString}")]
        [ProducesResponseType(typeof(object[]), 200)]
        public async Task<IActionResult> InvokeTest(string testString)
        {
            Result? result = await StaticNodeJSService.InvokeFromStringAsync<Result>("module.exports = (callback, message) => callback(null, message);", args: new[] { "success" });

            return Content(result.Message, "application/json");
        }

请注意,我们将{testString}添加到[HttpGet("invokeTest/")]端点定义中,以便允许您的函数实际获取该值。

相关问题