Convention based url for media? 🤔
# help-with-umbraco
s
Is it possible to have a convention based url for media? It may be a bit of an X, Y problem but my intent is to display airline logos by their two(or three) digit code. So
mycooldomain.com/media/airlines/EZY.png
would output the airline logo for EasyJet.
j
I've actually done this before (although I think we excluded the media directory) for airline logos ironically enough... I have snippets of the code I could share (it's an ooooold repo I happened to have saved for a client I no longer have) but it's in v7 so I don't know how much of it would help you. The premise basically is that we set them to have a custom media type and then hijacked the route to give them a custom controller to render them.
s
Ooh, okay, that could work. Custom controller and just lookup based on file name, or some identifier on the custom type?
j
Hey @Sean Thorne! Keeping in mind that this is v7 and different than how things work in modern Umbraco... We had a custom route for airline logos:
Copy code
private static void AddAirlineLogoRoute(RouteCollection routes)
{
    routes.MapUmbracoRoute( 
        "airlineLogoRoutes",
        "AirlineLogo/{airline}",
        new
        {
            controller = "AirlineLogo",
            action = "GetIcon",
            airline = ""
        },
        new UmbracoVirtualNodeByIdRouteHandler(1072)
    );
}
And then the controller that would use the internal index to look up the airline logos by their custom media type and return them to the file stream - basically matching that image to the media item.
Copy code
public class AirlineLogoController : RenderMvcController
{
    public ActionResult GetIcon(RenderModel model, string airline)
    {

        airline = airline.ToUpper();
        airline = airline.Replace("DOT", ".");

        //first check in Examine as this is WAY faster
        var criteria = ExamineManager.Instance
            .SearchProviderCollection["InternalSearcher"]
            .CreateSearchCriteria("media");
        var filter = criteria.NodeTypeAlias("airlineLogo").And().NodeName(airline);
        var results = ExamineManager
            .Instance.SearchProviderCollection["InternalSearcher"]
            .Search(filter.Compile());
        var result = results.FirstOrDefault();
        if(result== null)
        {
            return HttpNotFound();
        }

        var mediaPath = result.Fields["umbracoFile"];
        
        MediaFileSystem media = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
        MemoryStream outStream = new MemoryStream();


        var fileContents = media.OpenFile(mediaPath);
        var fac = new ImageFactory();
        fac.Load(fileContents);
        fac.Format(new JpegFormat());
        fac.Save(outStream);
        outStream.Seek(0, SeekOrigin.Begin);
        return new FileStreamResult(outStream, "image/jpeg");
    }
}