Getting umbracoFile property within a ModelBuilder model
Hi,
after a looong pause, I'm trying to get back at Umbraco in the "right way" (tm)...
I have created a "File Media" Document Type with a Media Picker property called "Allegato" and I want to override the Url property of the model generated by ModelBuilder in order to return the file media Url (i.e. the "umbracoFile" property of the Media Picker).
Up to now this is the best solution I have found:
public partial class FileMedia
{
public override string Url
{
get
{
try
{
int allegatoID = Int32.Parse(this.Allegato);
var mediaService = ApplicationContext.Current.Services.MediaService;
var allegatoMedia = mediaService.GetById(allegatoID);
return allegatoMedia.GetValue("umbracoFile").ToString();
}
catch (FormatException e)
{
return base.Url;
}
}
}
}
but it uses ApplicationContext.Current property, which should not be done as explained in Common Pitfalls.
The best way to get URL of media is to use Umbraco Helper and TypedMedia:
var media = Umbraco.TypedMedia(1234);
var image = media.Url;
In your case:
public partial class FileMedia
{
public override string Url
{
get
{
int allegatoID = Int32.Parse(this.Allegato);
var media = Umbraco.TypedMedia(allegatoID);
return media.Url;
}
}
}
Don't use services for rendering media items of course.
I have seen UmbracoHelper class, but I don't think I have an Umbraco property ready to use, so the only way I found was to resort to the UmbracoContext singleton (which is one of the pitfall...).
This is the code generated by ModelBuilder:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Umbraco.ModelsBuilder v3.0.7.99
//
// Changes to this file will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Web;
using Umbraco.ModelsBuilder;
using Umbraco.ModelsBuilder.Umbraco;
namespace Umbraco.Web.PublishedContentModels
{
/// <summary>File Media</summary>
[PublishedContentModel("fileMedia")]
public partial class FileMedia : Base
{
#pragma warning disable 0109 // new is redundant
public new const string ModelTypeAlias = "fileMedia";
public new const PublishedItemType ModelItemType = PublishedItemType.Content;
#pragma warning restore 0109
public FileMedia(IPublishedContent content)
: base(content)
{ }
#pragma warning disable 0109 // new is redundant
public new static PublishedContentType GetModelContentType()
{
return PublishedContentType.Get(ModelItemType, ModelTypeAlias);
}
#pragma warning restore 0109
public static PublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<FileMedia, TValue>> selector)
{
return PublishedContentModelUtility.GetModelPropertyType(GetModelContentType(), selector);
}
///<summary>
/// Allegato
///</summary>
[ImplementPropertyType("allegato")]
public string Allegato
{
get { return this.GetPropertyValue<string>("allegato"); }
}
}
}
and this is my last override.cs:
using System;
namespace Umbraco.Web.PublishedContentModels
{
public partial class FileMedia
{
public override string Url
{
get
{
int allegatoID;
if (Int32.TryParse(this.Allegato, out allegatoID))
{
var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
return umbracoHelper.TypedMedia(allegatoID).Url;
}
else
{
return "";
}
}
}
}
}
Uhm... I am not sure to understand.
Where shoud I create the extension method? If I add it to the Model class it won't be able to see Umbraco, IIUIC.
Yet I prefer to override the Url property (it is a cleaner approach to me), and reading again the common pitfall page, I think that using the singleton is not too bad.
In the mean time I wrote a custom Url Provider which does the job way too well, to the point that the properties tab in content items shows some error related to the url colliding some other content... :-D
I think I'll end up using extension methods anyway.
Getting umbracoFile property within a ModelBuilder model
Hi,
after a looong pause, I'm trying to get back at Umbraco in the "right way" (tm)...
I have created a "File Media" Document Type with a Media Picker property called "Allegato" and I want to override the Url property of the model generated by ModelBuilder in order to return the file media Url (i.e. the "umbracoFile" property of the Media Picker).
Up to now this is the best solution I have found:
but it uses
ApplicationContext.Current
property, which should not be done as explained in Common Pitfalls.Is there a better way?
Thanks, Marco
Hi Marco
The best way to get URL of media is to use Umbraco Helper and TypedMedia:
In your case:
Don't use services for rendering media items of course.
Thanks,
Alex
Thanks Alex,
I have seen UmbracoHelper class, but I don't think I have an Umbraco property ready to use, so the only way I found was to resort to the UmbracoContext singleton (which is one of the pitfall...). This is the code generated by ModelBuilder:
and this is my last override.cs:
Hi Marco
Yes, now we need to avoid instantiation of "UmbracoHelper".
What about using extension methods instead overriding class?
You can create .GetMediaUrlById extention method for example.
Alex
Uhm... I am not sure to understand. Where shoud I create the extension method? If I add it to the Model class it won't be able to see Umbraco, IIUIC.
Yet I prefer to override the Url property (it is a cleaner approach to me), and reading again the common pitfall page, I think that using the singleton is not too bad.
Hi Marco
Something like here:
https://github.com/jbreuer/Hybrid-Framework-Best-Practices/blob/master/development/Umbraco.Extensions/Utilities/ExtensionMethods.cs#L53
Ehm... this example uses a static copy of UmbracoHelper, which is a bigger "no no" wrt to the common pitfall Static references to web request instances :-D
Aha, you caught me, Marco, you are absolutely right!!!
So we have to pass UmbracoHelper instance to our method.
In the mean time I wrote a custom Url Provider which does the job way too well, to the point that the properties tab in content items shows some error related to the url colliding some other content... :-D
I think I'll end up using extension methods anyway.
Thanks for you time Alex.
You are welcome, Marco.
Have a nice evening.
Alex
is working on a reply...