Resolved Help converting me Program to Controller with await

juniorProgrammer

New member
Joined
Mar 17, 2022
Messages
4
Programming Experience
3-5
I have this code in a Program and it works correctly. But when i try to insert them into a Controller to be called in api/Controller it didn't work.

C#:
static async Task Main(string[] args)
{
    var result = await searchReviewsByIdProductAsync("hhcbaaczbzj");
    System.Environment.Exit(1);
}

private static async Task<string> searchReviewsByIdProductAsync(string idProduct)
{
    var result = "";
    Console.WriteLine("searchReviewByIdProduct:" + idProduct);

    //define connections
    var conn1Config = new Dictionary<string, object>();

    //config connection 1
    conn1Config.Add("baseUrl", "https://test.ipdb.io");
    BlockchainConnection conn1 = new BlockchainConnection(conn1Config);

    //add connections
    IList<BlockchainConnection> connections = new List<BlockchainConnection>();
    connections.Add(conn1);

    //multiple connections
    var builderWithConnections = BigchainDbConfigBuilder
        .addConnections(connections)
        .setTimeout(20000); //override default timeout of 20000 milliseconds

    // single connection
    var builder = BigchainDbConfigBuilder
        .baseUrl("https://test.ipdb.io");

    if (!AsyncContext.Run(() => builder.setup()))
    {
        Console.WriteLine("Failed to setup");
    };

    // prepare your key
    var algorithm = SignatureAlgorithm.Ed25519;
    var privateKey = Key.Import(algorithm, Utils.StringToByteArray(privateKeyString), KeyBlobFormat.PkixPrivateKey);
    var publicKey = PublicKey.Import(algorithm, Utils.StringToByteArray(publicKeyString), KeyBlobFormat.PkixPublicKey);
    var assets = await AssetsApi<object>.getAssetsAsync(idProduct);

    try
    {
        for (int i = 0; i < assets.Count; i++)
        {

            JsonSerializer serializer = new JsonSerializer();
            //ReviewsAsset review = (ReviewsAsset)serializer.Deserialize((Newtonsoft.Json.Linq.JObject)assets[i].Data, typeof(ReviewsAsset));
            var json = assets[i].Data.ToString().Substring(0, assets[i].Data.ToString().Length);

            string jsonCliente = JsonConvert.SerializeObject(assets[i].Data);

            //var dictionary = serializer.Deserialize<Dictionary<string, object>>(assets[i].Data);

            result += assets[i].Data.ToString() + "@|@";
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("Error: " + e.Message);
    }

    return result;
}

Here the code in a controller

C#:
 [System.Web.Http.HttpGet]
        public async Task<string> searchReviewsByIdProductAsync(string id)
        {
            var result = "";

            try
            {
                //define connections
                var conn1Config = new Dictionary<string, object>();

                //config connection 1
                conn1Config.Add("baseUrl", "https://test.ipdb.io");
                BlockchainConnection conn1 = new BlockchainConnection(conn1Config);

                //add connections
                IList<BlockchainConnection> connections = new List<BlockchainConnection>();
                connections.Add(conn1);

                //multiple connections
                var builderWithConnections = BigchainDbConfigBuilder
                    .addConnections(connections)
                    .setTimeout(20000); //override default timeout of 20000 milliseconds


                if (!AsyncContext.Run(() => builder.setup()))
                {
                    Console.WriteLine("Failed to setup");
                };

                // prepare your key
                var algorithm = SignatureAlgorithm.Ed25519;
                var privateKey = Key.Import(algorithm, Utils.StringToByteArray(privateKeyString), KeyBlobFormat.PkixPrivateKey);
                var publicKey = PublicKey.Import(algorithm, Utils.StringToByteArray(publicKeyString), KeyBlobFormat.PkixPublicKey);
                var assets = await AssetsApi<object>.getAssetsAsync(id);

                if (assets != null)
                {
                    if (assets.Count > 0)
                    {
                        for (int i = 0; i < assets.Count; i++)
                        {

                            JsonSerializer serializer = new JsonSerializer();
                            //ReviewsAsset review = (ReviewsAsset)serializer.Deserialize((Newtonsoft.Json.Linq.JObject)assets[i].Data, typeof(ReviewsAsset));
                            var json = assets[i].Data.ToString().Substring(0, assets[i].Data.ToString().Length);

                            string jsonCliente = JsonConvert.SerializeObject(assets[i].Data);

                            //var dictionary = serializer.Deserialize<Dictionary<string, object>>(assets[i].Data);

                            result += assets[i].Data.ToString() + "@|@";
                        }
                    }
                    else
                    {
                        result = "No Assets";
                    }
                }
                else
                {
                    result = "No Assets";
                }

            }
            catch (Exception e)
            {
                Console.WriteLine("Error: " + e.Message);
                result = e.Message;
            }

            //sw.Stop();

            return result;

        }

The code stop int this line:

!AsyncContext.Run(() => builder.setup())

Any sugestion for what's that happends? Whats the diference bewtween Program-Controller with await methods? I don't not have experience with this type of methods and probably i have a basic error but i don't know.
 
Solution
Works for me:
Screenshot_1.png


I used the basic ASP.NET Core MVC (using .NET Core 6.0) and just changed these 2 files:
HomeController.cs:
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NSec.Cryptography;
using Omnibasis.BigchainCSharp.Api;
using Omnibasis.BigchainCSharp.Builders;
using Omnibasis.BigchainCSharp.Constants;
using Omnibasis.BigchainCSharp.Model;
using Omnibasis.BigchainCSharp.Util;
using System.Diagnostics;
using TestBigChainMvc.Models;

namespace TestBigChainMvc.Controllers
{
    public class HomeController : Controller
    {
        private static String publicKeyString = "302a300506032b657003210033c43dc2180936a2a9138a05f06c892d2fb1cfda4562cbc35373bf13cd8ed373";
        private static String privateKeyString =...
Why do you even need that AsyncContext.Run()? That used to be a workaround when Main() couldn't be declared async in the older versions of C#. See:

Simply just await the call to builder.setup().
 
Why do you even need that AsyncContext.Run()? That used to be a workaround when Main() couldn't be declared async in the older versions of C#. See:

Simply just await the call to builder.setup().

Ok, after change this i think there is not me problem. Yes, it's work, the program don't crash but the connection doesn't work

controller.png


program.png



I am using this public code

 
What error message are you getting? Where is the error coming from?
 
Works for me:
Screenshot_1.png


I used the basic ASP.NET Core MVC (using .NET Core 6.0) and just changed these 2 files:
HomeController.cs:
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NSec.Cryptography;
using Omnibasis.BigchainCSharp.Api;
using Omnibasis.BigchainCSharp.Builders;
using Omnibasis.BigchainCSharp.Constants;
using Omnibasis.BigchainCSharp.Model;
using Omnibasis.BigchainCSharp.Util;
using System.Diagnostics;
using TestBigChainMvc.Models;

namespace TestBigChainMvc.Controllers
{
    public class HomeController : Controller
    {
        private static String publicKeyString = "302a300506032b657003210033c43dc2180936a2a9138a05f06c892d2fb1cfda4562cbc35373bf13cd8ed373";
        private static String privateKeyString = "302e020100300506032b6570042204206f6b0cd095f1e83fc5f08bffb79c7c8a30e77a3ab65f4bc659026b76394fcea8";

        private readonly ILogger<HomeController> _logger;

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

        public async Task<IActionResult> Index(string id)
        {
            //define connections
            var conn1Config = new Dictionary<string, object>();

            //define headers for connections
            var headers1 = new Dictionary<string, string>();

            //config connection 1
            conn1Config.Add("baseUrl", "https://test.ipdb.io/");
            conn1Config.Add("headers", headers1);
            BlockchainConnection conn1 = new BlockchainConnection(conn1Config);

            var conn2Config = new Dictionary<string, object>();
            var headers2 = new Dictionary<string, string>();
            //config connection 2
            conn2Config.Add("baseUrl", "https://test.ipdb.io/");
            conn2Config.Add("headers", headers2);
            BlockchainConnection conn2 = new BlockchainConnection(conn2Config);

            //add connections
            IList<BlockchainConnection> connections = new List<BlockchainConnection>();
            connections.Add(conn1);
            connections.Add(conn2);
            //...You can add as many nodes as you want

            //multiple connections
            var builder = BigchainDbConfigBuilder
                .addConnections(connections)
                .setTimeout(60000); //override default timeout of 20000 milliseconds

            // single connection
            //var builder = BigchainDbConfigBuilder
            //    .baseUrl("https://test.ipdb.io/")
            //    .addToken("app_id", "204d77e0")
            //    .addToken("app_key", "910c0943ce05e76b568395986d3b33d9");

            var success = await builder.setup();
            if (!success)
            {
                throw new ApplicationException("Failed to setup");
            };

            // prepare your key
            var algorithm = SignatureAlgorithm.Ed25519;
            var privateKey = Key.Import(algorithm, Utils.StringToByteArray(privateKeyString), KeyBlobFormat.PkixPrivateKey);
            var publicKey = PublicKey.Import(algorithm, Utils.StringToByteArray(publicKeyString), KeyBlobFormat.PkixPublicKey);
            //Account account = new Account();

            //Dictionary<string, string> assetData = new Dictionary<string, string>();
            //assetData.Add("msg", "Hello!");

            TestAsset assetData = new TestAsset();
            assetData.msg = "Hello!";
            assetData.city = "San Diego";
            assetData.temperature = "74";
            assetData.datetime = DateTime.Now;

            //MetaData metaData = new MetaData();
            //metaData.setMetaData("msg", "My first transaction");
            TestMetadata metaData = new TestMetadata();
            metaData.msg = "My first transaction";

            var createTransaction2 = await TransactionsApi<object, object>
            .getTransactionByIdAsync("a30a6858185b9382fed0053e51a1e6faae490132c307a7cd488097c12a55b763");

            //if(true)
            //{
            // Set up, sign, and send your transaction
            var transaction = BigchainDbTransactionBuilder<TestAsset, TestMetadata>
                .init()
                .addAssets(assetData)
                .addMetaData(metaData)
                .operation(Operations.CREATE)
                .buildAndSignOnly(publicKey, privateKey);
            //.buildAndSign(account.PublicKey, account.PrivateKey);

            //var info = transaction.toHashInput();
            var createTransaction = await TransactionsApi<TestAsset, TestMetadata>.sendTransactionAsync(transaction);

            // the asset's ID is equal to the ID of the transaction that created it
            if (createTransaction != null && createTransaction.Data != null)
            {
                string assetId2 = createTransaction.Data.Id;
                //"2984ac294290ce6f15124140dad652fc8a306aca62c38237174988dfcf31a3e6"
                var testTran2 = await TransactionsApi<object, object>.getTransactionByIdAsync(assetId2);
                ViewData["FirstTransaction"] = assetId2;

            }
            else
            {
                throw new ApplicationException("Failed to send transaction");
            }


            //}

            // Describe the output you are fulfilling on the previous transaction
            FulFill spendFrom = new FulFill();
            spendFrom.TransactionId = createTransaction.Data.Id;
            spendFrom.OutputIndex = 0;

            // Change the metadata if you want
            //MetaData transferMetadata = new MetaData();
            //metaData.setMetaData("msg", "My second transaction");
            TestMetadata transferMetadata = new TestMetadata();
            transferMetadata.msg = "My second transaction";

            // the asset's ID is equal to the ID of the transaction that created it
            // By default, the 'amount' of a created digital asset == "1". So we spend "1" in our TRANSFER.
            string amount = "1";
            BlockchainAccount account = new BlockchainAccount();
            Details details = null;
            // Use the previous transaction's asset and TRANSFER it
            var build2 = BigchainDbTransactionBuilder<Asset<string>, TestMetadata>.
                init().
                addMetaData(metaData).
                addInput(details, spendFrom, publicKey).
                addOutput("1", account.Key.PublicKey).
                addAssets(createTransaction.Data.Id).
                operation(Operations.TRANSFER).
                buildAndSignOnly(publicKey, privateKey);

            var transferTransaction = await TransactionsApi<Asset<string>, TestMetadata>.sendTransactionAsync(build2);

            if (transferTransaction != null)
            {
                string assetId2 = transferTransaction.Data.Id;
                //"2984ac294290ce6f15124140dad652fc8a306aca62c38237174988dfcf31a3e6"
                var testTran2 = await TransactionsApi<object, object>.getTransactionByIdAsync(assetId2);
                ViewData["SecondTransaction"] = assetId2;

            }
            else
            {
                throw new ApplicationException("Failed to send transaction");
            }

            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }

    [Serializable]
    public class TestAsset
    {
        [JsonProperty]
        public string msg { get; set; }
        [JsonProperty]
        public string city { get; set; }
        [JsonProperty]
        public string temperature { get; set; }
        [JsonProperty]
        public DateTime datetime { get; set; }
    }

    [Serializable]
    public class TestMetadata
    {
        [JsonProperty]
        public string msg { get; set; }
    }
}

Index.cshtml:
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
    <p>First: @ViewData["FirstTransaction"]</p>
    <p>Second: @ViewData["SecondTransaction"]</p>
</div>

(The only failure I was seeing was a random crash on line 153 when Data would occasionally be null. From what I can see it was some kind of timing issue. If I deliberately put a half second delay before that line, the transaction would always fully succeed.
 
Solution
Works for me:
View attachment 2104

I used the basic ASP.NET Core MVC (using .NET Core 6.0) and just changed these 2 files:
HomeController.cs:
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NSec.Cryptography;
using Omnibasis.BigchainCSharp.Api;
using Omnibasis.BigchainCSharp.Builders;
using Omnibasis.BigchainCSharp.Constants;
using Omnibasis.BigchainCSharp.Model;
using Omnibasis.BigchainCSharp.Util;
using System.Diagnostics;
using TestBigChainMvc.Models;

namespace TestBigChainMvc.Controllers
{
    public class HomeController : Controller
    {
        private static String publicKeyString = "302a300506032b657003210033c43dc2180936a2a9138a05f06c892d2fb1cfda4562cbc35373bf13cd8ed373";
        private static String privateKeyString = "302e020100300506032b6570042204206f6b0cd095f1e83fc5f08bffb79c7c8a30e77a3ab65f4bc659026b76394fcea8";

        private readonly ILogger<HomeController> _logger;

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

        public async Task<IActionResult> Index(string id)
        {
            //define connections
            var conn1Config = new Dictionary<string, object>();

            //define headers for connections
            var headers1 = new Dictionary<string, string>();

            //config connection 1
            conn1Config.Add("baseUrl", "https://test.ipdb.io/");
            conn1Config.Add("headers", headers1);
            BlockchainConnection conn1 = new BlockchainConnection(conn1Config);

            var conn2Config = new Dictionary<string, object>();
            var headers2 = new Dictionary<string, string>();
            //config connection 2
            conn2Config.Add("baseUrl", "https://test.ipdb.io/");
            conn2Config.Add("headers", headers2);
            BlockchainConnection conn2 = new BlockchainConnection(conn2Config);

            //add connections
            IList<BlockchainConnection> connections = new List<BlockchainConnection>();
            connections.Add(conn1);
            connections.Add(conn2);
            //...You can add as many nodes as you want

            //multiple connections
            var builder = BigchainDbConfigBuilder
                .addConnections(connections)
                .setTimeout(60000); //override default timeout of 20000 milliseconds

            // single connection
            //var builder = BigchainDbConfigBuilder
            //    .baseUrl("https://test.ipdb.io/")
            //    .addToken("app_id", "204d77e0")
            //    .addToken("app_key", "910c0943ce05e76b568395986d3b33d9");

            var success = await builder.setup();
            if (!success)
            {
                throw new ApplicationException("Failed to setup");
            };

            // prepare your key
            var algorithm = SignatureAlgorithm.Ed25519;
            var privateKey = Key.Import(algorithm, Utils.StringToByteArray(privateKeyString), KeyBlobFormat.PkixPrivateKey);
            var publicKey = PublicKey.Import(algorithm, Utils.StringToByteArray(publicKeyString), KeyBlobFormat.PkixPublicKey);
            //Account account = new Account();

            //Dictionary<string, string> assetData = new Dictionary<string, string>();
            //assetData.Add("msg", "Hello!");

            TestAsset assetData = new TestAsset();
            assetData.msg = "Hello!";
            assetData.city = "San Diego";
            assetData.temperature = "74";
            assetData.datetime = DateTime.Now;

            //MetaData metaData = new MetaData();
            //metaData.setMetaData("msg", "My first transaction");
            TestMetadata metaData = new TestMetadata();
            metaData.msg = "My first transaction";

            var createTransaction2 = await TransactionsApi<object, object>
            .getTransactionByIdAsync("a30a6858185b9382fed0053e51a1e6faae490132c307a7cd488097c12a55b763");

            //if(true)
            //{
            // Set up, sign, and send your transaction
            var transaction = BigchainDbTransactionBuilder<TestAsset, TestMetadata>
                .init()
                .addAssets(assetData)
                .addMetaData(metaData)
                .operation(Operations.CREATE)
                .buildAndSignOnly(publicKey, privateKey);
            //.buildAndSign(account.PublicKey, account.PrivateKey);

            //var info = transaction.toHashInput();
            var createTransaction = await TransactionsApi<TestAsset, TestMetadata>.sendTransactionAsync(transaction);

            // the asset's ID is equal to the ID of the transaction that created it
            if (createTransaction != null && createTransaction.Data != null)
            {
                string assetId2 = createTransaction.Data.Id;
                //"2984ac294290ce6f15124140dad652fc8a306aca62c38237174988dfcf31a3e6"
                var testTran2 = await TransactionsApi<object, object>.getTransactionByIdAsync(assetId2);
                ViewData["FirstTransaction"] = assetId2;

            }
            else
            {
                throw new ApplicationException("Failed to send transaction");
            }


            //}

            // Describe the output you are fulfilling on the previous transaction
            FulFill spendFrom = new FulFill();
            spendFrom.TransactionId = createTransaction.Data.Id;
            spendFrom.OutputIndex = 0;

            // Change the metadata if you want
            //MetaData transferMetadata = new MetaData();
            //metaData.setMetaData("msg", "My second transaction");
            TestMetadata transferMetadata = new TestMetadata();
            transferMetadata.msg = "My second transaction";

            // the asset's ID is equal to the ID of the transaction that created it
            // By default, the 'amount' of a created digital asset == "1". So we spend "1" in our TRANSFER.
            string amount = "1";
            BlockchainAccount account = new BlockchainAccount();
            Details details = null;
            // Use the previous transaction's asset and TRANSFER it
            var build2 = BigchainDbTransactionBuilder<Asset<string>, TestMetadata>.
                init().
                addMetaData(metaData).
                addInput(details, spendFrom, publicKey).
                addOutput("1", account.Key.PublicKey).
                addAssets(createTransaction.Data.Id).
                operation(Operations.TRANSFER).
                buildAndSignOnly(publicKey, privateKey);

            var transferTransaction = await TransactionsApi<Asset<string>, TestMetadata>.sendTransactionAsync(build2);

            if (transferTransaction != null)
            {
                string assetId2 = transferTransaction.Data.Id;
                //"2984ac294290ce6f15124140dad652fc8a306aca62c38237174988dfcf31a3e6"
                var testTran2 = await TransactionsApi<object, object>.getTransactionByIdAsync(assetId2);
                ViewData["SecondTransaction"] = assetId2;

            }
            else
            {
                throw new ApplicationException("Failed to send transaction");
            }

            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }

    [Serializable]
    public class TestAsset
    {
        [JsonProperty]
        public string msg { get; set; }
        [JsonProperty]
        public string city { get; set; }
        [JsonProperty]
        public string temperature { get; set; }
        [JsonProperty]
        public DateTime datetime { get; set; }
    }

    [Serializable]
    public class TestMetadata
    {
        [JsonProperty]
        public string msg { get; set; }
    }
}

Index.cshtml:
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
    <p>First: @ViewData["FirstTransaction"]</p>
    <p>Second: @ViewData["SecondTransaction"]</p>
</div>

(The only failure I was seeing was a random crash on line 153 when Data would occasionally be null. From what I can see it was some kind of timing issue. If I deliberately put a half second delay before that line, the transaction would always fully succeed.

thanks, i was change me proyect for another newer proyect MVC .NET Core 6 and works correctly.

me other project was an older project MVC created in 2019.
 
Back
Top Bottom