+1-888-365-2779
Try Now
More in this section

Forums / Sitefinity SDK / How to find an Image by the MediaURL using FluentApi

How to find an Image by the MediaURL using FluentApi

7 posts, 0 answered
  1. Duneel
    Duneel avatar
    166 posts
    Registered:
    08 Dec 2010
    21 Mar 2011
    Link to this post
    Hi,

    I have implemented the following Fluent API query to find an image uploaded to Sitefinity by the media URL. For some reason it's throwing an exception (see below). Can someone please tell me what I have done wrong here and is it possible to find an image by the media URL?

    string mediaURL =  "/images/headshots/2011/03/21/17665.jpg" //This is the relative path of the image uploaded
      
    Telerik.Sitefinity.Libraries.Model.Image image = App.WorkWith()
                        .Images()
                        .Where(i => i.MediaUrl == medilURL
                            && i.Status == ContentLifecycleStatus.Live)
                        .Get().FirstOrDefault();

    Exception:
    Field "MediaUrl" not found in Class Telerik.Sitefinity.Libraries.Model.Image. {MediaUrl ["MediaUrl",<42>,line=1,col=125]}
    Original Query: DEFINE EXTENT extnt FOR Telerik.Sitefinity.Libraries.Model.Image; SELECT * FROM extnt AS t1  WHERE t1.appName =  $1 AND (t1.MediaUrl =  $2 AND t1.status =  $3 )



    Thanks,
    Duneel
  2. Geoff
    Geoff avatar
    89 posts
    Registered:
    02 Mar 2011
    22 Mar 2011
    Link to this post
    It seems like a bug in the fluent API to me, but to get around it I get all the content items from the API and then filter the list with another linq query.  For example:

    IEnumerable<Telerik.Sitefinity.Libraries.Model.Image> images = App.WorkWith()
                        .Images()
                        .Where(i => i.Status == ContentLifecycleStatus.Live)
                        .Get().ToList();
     
    Telerik.Sitefinity.Libraries.Model.Image image = images.
                        .Where(i => i.MediaUrl == mediaURL)
                        .Get().FirstOrDefault();
  3. Dido
    Dido avatar
    149 posts
    Registered:
    24 Sep 2012
    24 Mar 2011
    Link to this post
    Hi ,

    The problems stems from the fact that MediaUrl is a helper field that is not persisted. What you are executing would eventually go to the ORM. It will try query the database, but it has no information about 'MediaUrl', what it maps to, what table to get it from, etc. Therefore, OpenAccess spawns an error message as a result of its confusion.

    Since this is a common task, you have a utility method for all content managers -

    public virtual IDataItem GetItemFromUrl(Type itemType, string url, bool published, out string redirectUrl)

    A few notes about the url - it should be rooted local path, or put simply, out of the the
    http://example.com/images/image.png
    you need only the /images/image.png part

    itemType, for images, is typeof(Image). Published should be true, and redirectUrl can be ignored for this example.

    A method that 'soften'-s this procedure would look something like
    protected MediaContent GetMediaContentFromUrl(string path)
    {
        if (string.IsNullOrWhiteSpace(path))
            return null;
        Uri uri;
        if (!Uri.TryCreate(path, UriKind.RelativeOrAbsolute, out uri))
            return null;            
        if (uri.IsAbsoluteUri)
            path = uri.LocalPath;            
        if (VirtualPathUtility.IsAppRelative(path))
            path = VirtualPathUtility.ToAbsolute(path);
      
        if (path.Length <= 1)
            return null;
      
        path = path.Substring(1);
      
        var imagesRoot = Config.Get<LibrariesConfig>().Images.UrlRoot;
        var documentsRoot = Config.Get<LibrariesConfig>().Documents.UrlRoot;
        var videosRoot = Config.Get<LibrariesConfig>().Videos.UrlRoot;
      
      
        Type contentType = null;
        int indx = path.IndexOf('/');
        int rootIndex = indx;
        if (indx != -1)
        {
            string libraryType = path.Substring(0, indx);           
            if (libraryType == imagesRoot)
                contentType = typeof(Image);
            else if (libraryType == documentsRoot)
                contentType = typeof(Document);
            else if ((libraryType == videosRoot))
                contentType = typeof(Video);                
        }
        if (contentType == null)
            return null;
      
        indx = path.LastIndexOf('.');
        if (indx != -1)
        {
            bool showThumbnail = false;
            string extension = path.Substring(indx);
            path = path.Substring(0, indx);
      
            if (extension.Equals(".tmb", StringComparison.OrdinalIgnoreCase))
            {
                indx = path.LastIndexOf('.');
                if (indx == -1)
                    return null;
      
                extension = path.Substring(indx);
                path = path.Substring(0, indx);
                showThumbnail = true;
            }
      
            LibrariesManager manager = LibrariesManager.GetManager();
            indx = path.IndexOf('/', rootIndex + 1);
            if (indx != -1)
            {
                string providerName = path.Substring(rootIndex + 1, indx - rootIndex - 1);
                if (manager.Providers.Contains(providerName))
                {
                    manager = LibrariesManager.GetManager(providerName);
                    //path = path.Substring(indx);
                }
            }
      
            if (!path.StartsWith("/"))
                path = "/" + path;
      
            string redirectUrl;
            MediaContent content = (MediaContent)manager.GetItemFromUrl(contentType, path, true, out redirectUrl);
            return content;
        }
        return null;
    }

    Please note that his method is rather generic and that is why it is that long.

    All the best,
    Dido
    the Telerik team
  4. Andrei
    Andrei avatar
    553 posts
    Registered:
    27 Nov 2008
    31 Mar 2011
    Link to this post
    Dido,

    I have the MediaUrl value. All I want to do is to invoke that document.
    I don't want the user to be taken off to another page.

    In simple terms:
     - I have a button on the screen.
    - I know the MediaUrl.

    All I want is for the user to click that button and the
    Word to start up separately displaying that document without navigating to another
    page.

    Is there a way with the Telerik API to just say do that.

    Currently, I have an iFrame to which I give the MediaUrl as the src
    but I want to do it without the iFrame.

    Thanks,
    Andrei
  5. Andrei
    Andrei avatar
    553 posts
    Registered:
    27 Nov 2008
    31 Mar 2011
    Link to this post
    I think I worked it out.
    I have "Response.Redirect(ResolveUrl(doc.MediaUrl));" 
    and seems to work. It opens Word separately and
    leaves me on the same page.

    But let me know if there is a better way.

    Still need to test it though.

    Thanks,
    Andrei
  6. National Audiovisual Institute
    National Audiovisual Institute avatar
    4 posts
    Registered:
    29 Mar 2011
    26 Mar 2012
    Link to this post
    Above GetMediaContentFromUrl method is not working correctly in Sitefinity 4.4
    It is passing URLs in format: "/library/image.jpg" to GetItemFromUrl and the result is null.

    In version 4.4 you need to shorten it a little bit more. When you pass URL in format "/library/image" (without file extension) it returns correct value.
  7. National Audiovisual Institute
    National Audiovisual Institute avatar
    4 posts
    Registered:
    29 Mar 2011
    26 Mar 2012
    Link to this post
    UPDATE: Sorry. Double post.
7 posts, 0 answered