0 Comments

When Adaptive Cards for .NET is used to render a HTML card, the card renderer automatically adds few classes into the actions. Here’s an example where an adaptive card is rendered in ASP.NET Core using the defaults:

image

We can see that the actions automatically get classes like ac-pushButton and ac-action-openUrl. CSS can be used to customize these classes. But if you’re using something like Bootstrap, it’s quite likely that you want to use classes like btn and btn-primary. This post shows how to use Bootstrap’s btn-classes with Adaptive Cards’ HTML renderer in ASP.NET Core.

Modifying the HTML renderer

You can modify the adaptive cards’ HTML renderer to inject the classes you like. The modifications happen through AdaptiveCardRenderer.ActionTransformers.Register. The modifications can be registered for example in the Configure-method of the application:

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddLocalization();
            services.AddDistributedMemoryCache();
            services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(20); });

            AdaptiveCardRenderer.ActionTransformers.Register<AdaptiveOpenUrlAction>((action, tag, context) =>
            {
                tag.AddClass("btn");
                tag.AddClass("btn-primary");
            });

The example above adds “btn” and “btn-primary” classes into each OpenUrl action:

image

Conditional classes

Classes can be added conditionally, based on the card’s schema. Here’s an example where action’s style is used to define the applied CSS classes:

            AdaptiveCardRenderer.ActionTransformers.Register<AdaptiveOpenUrlAction>((action, tag, context) =>
            {
                tag.AddClass("btn");

                if (string.Equals(action.Style, "destructive", StringComparison.InvariantCultureIgnoreCase))
                {
                    tag.AddClass("btn-danger");
                }
                else
                {
                    tag.AddClass("btn-primary");
                }
            });

image

As we can see, btn-danger is applied to the button on the right side.

image

Custom attributes

Register-method can be used for more than just adding custom classes. AddAttribute can be used to add new custom attributes to the button:

            AdaptiveCardRenderer.ActionTransformers.Register<AdaptiveOpenUrlAction>((action, tag, context) =>
            {
                tag.Attr("id", AdaptiveCardRenderer.GenerateRandomId());
                tag.Attr("data-ac-url", action.Url);
            });

Note

Register-method can be called only once per element type. If you have multiple calls to Register<AdaptiveOpenUrl>, the last one wins:

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddLocalization();
            services.AddDistributedMemoryCache();
            services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(20); });

            AdaptiveCardRenderer.ActionTransformers.Register<AdaptiveOpenUrlAction>((action, tag, context) =>
            {
                tag.AddClass("btn");
                tag.AddClass("btn-primary");
            });
            
            AdaptiveCardRenderer.ActionTransformers.Register<AdaptiveOpenUrlAction>((action, tag, context) =>
            {
                tag.AddClass("btn");
                tag.AddClass("btn-danger");
            });

image