skip to Main Content

I want to be able to execute javascript code in my back-end .NET API, so I tried following these steps and I created a .NET API as follows:

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; }
    }
}

I would expect that once I request GET API_URL/testNodeJS/invokeTest/ from postman it would run the javascript code specified, however I am getting a 500 error with the exception below:

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:UsersnunebrDocumentsgit-workspacesupply-chain-planning-toolplanning-apps-back-endNodeJSTestAPIControllersTestNodeJSController.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

Does anyone know what I might be missing on this issue?

On a separate note, I used to have this same code running fine in a different laptop, however since I needed to change laptop, I can’t make it work again, so not sure if it could be some network configuration issue blocking my .NET API to access the invoked NodeJS.

Any help would be greatly appreciated.

Thanks in advance!

2

Answers


  1. Your problem can be solved by reading the messages that are logged. Logging is enabled through dependency injection.

    Here is an example of a simple console application under .net 7.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}");
        }
    }
    

    To make this work, we need to add two more nuget packages.

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

    If there are problems deciphering the output, you can attach the console output to the question

    Login or Signup to reply.
  2. I’m not sure if this will solve the full issue, but you should start by looking into your endpoint configuration.
    Currently, your code is expecting a string testString as a parameter for your GET method, but you’re not providing one in your definition.
    Try changing your code to:

    [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");
            }
    

    Note that we’re adding {testString} to your [HttpGet("invokeTest/")] endpoint definition in order to allow your function to actually pick that value up.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search