Using Bootstrap with Adaptive Cards’ actions in ASP.NET Core
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:
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:
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"); } });
As we can see, btn-danger is applied to the button on the right side.
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"); });