-1

I am wondering to provide an option in my application to users to be able to customize buttons in ASP.NET CORE with Blazor.

I mean, C# code can be stored in database, and compiled/executed in runtime.

How can I "provide" an object from razor to be manipulated in this "code stored in the database" and after that, make those changes in runtime, after code been executed?

Please share your ideas.

I already tried some things, like this:

using Blazored.Toast.Services; 
using Microsoft.AspNetCore.Components; 
using Microsoft.CSharp;using Newtonsoft.Json; 
using System; 
using System.CodeDom.Compiler; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection;
using System.Threading.Tasks;  

namespace Projeto.Web.Pages.Components {

public class McwEditModel : CustomComponentBase
{
    [Inject]
    public IToastService ToastService { get; set; }

    #region Parameters
    [Parameter]
    public string nome { get; set; }
    #endregion

    public void OnTextChanged(string newValue)
    {


        string source =
          @"public class SomeClass {
                public int OnTextChanged (string newValue) {
                    if (!string.IsNullOrEmpty(newValue))    {
                         ToastService.ShowWarning(newValue);
                }
                }
            } ";


       var compParms = new CompilerParameters
        {
            GenerateExecutable = false,
            GenerateInMemory = true
        };
        var csProvider = new CSharpCodeProvider();
        CompilerResults compilerResults =
            csProvider.CompileAssemblyFromSource(compParms, source);
        object typeInstance =
            compilerResults.CompiledAssembly.CreateInstance("SomeClass");
        MethodInfo mi = typeInstance.GetType().GetMethod("OnTextChanged");
        int methodOutput =
            (int)mi.Invoke(typeInstance, new object[] { newValue });

        InvokeAsync(StateHasChanged);
    }
}}

The problem is that does not work, particularly I am getting the error "System.PlatformNotSupportedException: 'Operation is not supported on this platform.'" on line

" CompilerResults compilerResults =              csProvider.CompileAssemblyFromSource(compParms, source); "

I am using Blazor .NET Core.

Is there any chance or way to achieve what I want?

H H
  • 263,252
  • 30
  • 330
  • 514
thiagovinicius
  • 117
  • 1
  • 12
  • First challenge would be to actually get "C# code stored in database" – H H Dec 04 '19 at 15:56
  • And when that works, what would be the use-case? – H H Dec 04 '19 at 15:57
  • It's not very clear what you are looking to accomplish, but I would think you would want to store your button settings in the database, not c# code. For example. store the color the user wants the button to be, then on load, pull the color for the user and set the button color. – Kyle Dec 04 '19 at 17:49
  • I made an example above, I want to get a custom function c# to do something with value changed after changeText event of a textbox, on Blazor. – thiagovinicius Dec 06 '19 at 12:13
  • Are you using Blazor WebAssembly (Client-side Blazor)? – H H Dec 06 '19 at 18:45
  • Hi @HenkHolterman I am using server side. Do you have any ideas ? – thiagovinicius Dec 07 '19 at 17:05
  • You should at leat post your .csproj file, this dependes a lot on versions, platform etc. On the docs page, core 3.1 is missing. – H H Dec 07 '19 at 22:56
  • Hi @HenkHolterman I already solved it, thanks for your help. – thiagovinicius Dec 09 '19 at 16:52

1 Answers1

0

I solved it using using Microsoft.CodeAnalysis package.

I needed to create a

public class Globals

    {
        [Inject]
        public IToastService ToastService { get; set; }

        public string newValue { get; set; }

        public dynamic objeto { get; set; }
    }

and inside my method I did:

public void OnTextChanged(string newValue){

        Aql aql = new Aql { EaqcCodigo = "1", EaqcDescricao = "AQL" };

        var globals = new Globals { ToastService =  ToastService, newValue = newValue, objeto= aql };


        CSharpScript.RunAsync("ToastService.ShowWarning(newValue + \"- desc:\" + objeto.EaqcDescricao + \"- cod:\" + objeto.EaqcCodigo);", ScriptOptions.Default.WithReferences("Microsoft.CSharp"), globals).Wait();
    }

with this, now I can pass a dynamic object and also make any codes in a string field on database and retrieve this wherever I want, to customize a lot of things, ie: change of fields (in a custom generic and dynamic component)

thiagovinicius
  • 117
  • 1
  • 12