Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AdaptiveImage.Url: Url is too long #2716

Closed
brad302 opened this issue Apr 18, 2019 · 10 comments
Closed

AdaptiveImage.Url: Url is too long #2716

brad302 opened this issue Apr 18, 2019 · 10 comments
Assignees

Comments

@brad302
Copy link

brad302 commented Apr 18, 2019

Adding animated GIF's as a base64 string into an AdaptiveCard when that string is longer than System.Uri permits, obviously, throws an error.

Invalid URI: The Uri string is too long.

On the AdaptiveCard designer online, it has no problem with rendering the GIF and therefore, there is a misalignment with that of the designer and that of the AdaptiveCards SDK. Along with that, we know that browsers can accept a base64 string that is much longer than a url is permitted to be when displaying <img elements on a page.

Given the Url property is set to System.Uri, I can't see a way around this and looking into the underlying classes, Uri is embedded heavily throughout with all types of images that are accepted throughout child classes of AdaptiveElement.

This may have been covered previously but I couldn't find reference to an issue so I have raised one and am wondering if a fix is something that is possible in the near future?

Thanks

Brad

@shalinijoshi19 shalinijoshi19 self-assigned this Apr 25, 2019
@shalinijoshi19
Copy link
Member

Hey @brad302 what platform had you been testing this on again?

@brad302
Copy link
Author

brad302 commented Apr 25, 2019

Thanks @shalinijoshi19, BOT Framework v4, c#, VS 2019 and I haven't got it in front of me but I believe the version is the latest released version, 1.1.2 ... is that what you're after?

@brad302
Copy link
Author

brad302 commented May 9, 2019

@shalinijoshi19, sorry mate but any update from your end?

@shalinijoshi19
Copy link
Member

Hi @brad302 (apologies for missing your response earlier) but i was referring more to the renderer platform which in this case looks like then is WPF(indirectly as consumed by the BotFramework)? Coincidentally @andrewleader is confirming that GIFs in general arent suported on WPF - perhaps addressing this bug could be part of that work? @andrewleader ?

@brad302
Copy link
Author

brad302 commented May 9, 2019

@shalinijoshi19, @andrewleader we’re consuming it via the BotFramework via web chat, predominantly. Is that clearer?

@andrewleader
Copy link
Contributor

andrewleader commented May 9, 2019

Thanks Brad. Interesting, WebChat uses the HTML JavaScript renderer (same one as in the Adaptive Cards Designer website), so GIFs themselves should be working. Maybe WebChat somehow disabled GIF support in their HTML, I'm investigating this...

And your issue with the Url too long happens when you're authoring the card? You're using the .NET C# library to programmatically construct your Adaptive Card, and an exception is thrown there when you're simply trying to set the Image.Url property with a new System.Uri, correct?

@andrewleader andrewleader self-assigned this May 9, 2019
@shalinijoshi19 shalinijoshi19 removed their assignment May 9, 2019
@brad302
Copy link
Author

brad302 commented May 9, 2019

@andrewleader, correct with the C# playback but your adaptive cards designer is fine so no worries on that side of the equation. I think once it got to the web it would render correctly, it’s just getting it there via the SDK in C#.

I put it down to the limitations of System.Uri and the maximum length of string it accepts.

I actually encountered another user with the same issue on Stackoverflow ...

https://stackoverflow.com/q/55663963/5772095

... where I suggested he just resize the images. This worked for him but I’m pretty much at my limits with the size and quality of my animated gif and he had that issue before I experienced mine.

I hope that helps and thanks for looking into this.

@andrewleader
Copy link
Contributor

@brad302 here's two workarounds that should get you unblocked

Workaround 1: Extend the Image class and add a LongUrl property

This is definitely the best workaround. Define the following class, extending AdaptiveImage, adding a LongUrl property (which writes to the same url property in the JSON).

public class AdaptiveImageWithLongUrl : AdaptiveImage
{
    [JsonProperty(PropertyName = "url", Required = Required.Always)]
    public string LongUrl { get; set; }
}

Then, use your new image class and the new property when assigning long urls!

// A data URL that's longer than .NET max length
string actualUrl = "data:image/gif;base64," + string.Join("", new int[120000].Select(i => "A")) + "end";

AdaptiveCard card = new AdaptiveCard("1.0")
{
    Body =
    {
        new AdaptiveImageWithLongUrl()
        {
            LongUrl = actualUrl
        }
    }
};

// Place the JObject in the attachment!
var attachment = new Attachment()
{
    Content = card,
    ContentType = "application/vnd.microsoft.card.adaptive",
    Name = "cardName"
};

Workaround 2: Inject the long url into the serialized JSON

Since cards are just JSON, you can use the object model to construct everything else, serialize it to JSON, and then place the URL into the JSON itself!

// A data URL that's longer than .NET max length
string actualUrl = "data:image/gif;base64," + string.Join("", new int[120000].Select(i => "A")) + "end";

AdaptiveCard card = new AdaptiveCard("1.0")
{
    Body =
    {
        new AdaptiveImage()
        {
            // Use a placeholder URL for now (we'll replace it later)
            Url = new Uri("my:gif")
        }
    }
};

// Serialize the card to JSON
string json = card.ToJson();

// Parse it
JObject jsonObj = JObject.Parse(json);

// Grab the image URL property by looking for our placeholder value
JProperty urlProp = jsonObj.Descendants().OfType<JProperty>().First(i => i.Name == "url" && i.Value.Value<string>() == "my:gif");

// Replace it with our actual long data url
urlProp.Value = JToken.FromObject(actualUrl);

// Place the JObject in the attachment!
var attachment = new Attachment()
{
    Content = jsonObj,
    ContentType = "application/vnd.microsoft.card.adaptive",
    Name = "cardName"
};

@andrewleader
Copy link
Contributor

We're tracking adding support for long data uris to all platforms with #2881, please subscribe to that issue for updates. In the meantime, please use one of the above workarounds!

Thanks so much brad302 for bringing this to our attention!

@brad302
Copy link
Author

brad302 commented May 13, 2019

Thanks @andrewleader, I'll look into implementing your suggested workaround. Funnily enough, I was taking an approach at times to simply do a find and replace in the json string when I wanted to remove complication for updating my card, e.g. %MESSAGE% was a variable in the json and that is what I would find and replace. I moved away from that for good reasons but overlooked the thought of adding it back in as a way to overcome the issue. Poor on my behalf ...! Anyway, thanks again,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants