Skip to content

Instantly share code, notes, and snippets.

@JimBobSquarePants
Last active January 5, 2019 09:55
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JimBobSquarePants/5671406 to your computer and use it in GitHub Desktop.
Save JimBobSquarePants/5671406 to your computer and use it in GitHub Desktop.
Maps an instance of IPublishedContent to a strong typed Model. This would allow you to use models in your views and save logic. In your controller you should be able to use var MyModel = ModelMapper.Map<Type>(renderModel.Content); This could easily be turned into an extension method IPublishedContent. Based on the MVC separation article by Nick …
namespace UmbracoBootstrap.Infrastructure.Extensions
{
#region Using
using System.Diagnostics.CodeAnalysis;
#endregion
/// <summary>
/// Encapsulates a series of time saving extension methods to <see cref="T:System.String">String</see>s.
/// </summary>
public static class StringExtensions
{
/// <summary>
/// Creates a camel cased version of the String.
/// <see>
/// <cref>https://github.com/ServiceStack/ServiceStack.Text/blob/master/src/ServiceStack.Text/StringExtensions.cs</cref>
/// </see>
/// </summary>
/// <param name="expression">The <see cref="T:System.String">String</see> instance that this method extends.</param>
/// <returns>A camel cased version of the String.</returns>
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
public static string ToCamelCase(this string expression)
{
if (string.IsNullOrEmpty(expression))
{
return expression;
}
const int LowerCaseOffset = 'a' - 'A';
int length = expression.Length;
char[] newExpression = new char[length];
bool firstPart = true;
for (var i = 0; i < length; ++i)
{
char current = expression[i];
char next = i < length - 1 ? expression[i + 1] : 'A';
bool currentIsUpper = current >= 'A' && current <= 'Z';
bool nextIsUpper = next >= 'A' && next <= 'Z';
if (firstPart && currentIsUpper && (nextIsUpper || i == 0))
{
current = (char)(current + LowerCaseOffset);
}
else
{
firstPart = false;
}
newExpression[i] = current;
}
return new string(newExpression);
}
}
}
namespace UmbracoBootstrap.Infrastructure.Helpers
{
#region Using
using System;
using System.Reflection;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Web;
using UmbracoBootstrap.Infrastructure.Extensions;
#endregion
/// <summary>
/// Maps published content to models.
/// </summary>
public static class ModelMapper
{
/// <summary>
/// Maps the given <see cref="IPublishedContent"/> to the correct model
/// allowing us to return a strong-typed instance which make views more readable.
/// </summary>
/// <param name="content">
/// The content.
/// </param>
/// <typeparam name="T">
/// The type of model to map the published content to.
/// </typeparam>
/// <returns>
/// The <see cref="T"/>.
/// </returns>
public static T Map<T>(this IPublishedContent content) where T : class, new()
{
// Check first if the document type matches the given model.
if (!content.IsDocumentType(typeof(T).Name))
{
throw new ArgumentException("content");
}
// Create a new instance of the model and assign the properties from
// the content.
T model = new T();
foreach (PropertyInfo property in model.GetType().GetProperties())
{
// Property aliases are camel-cased.
string alias = property.Name.ToCamelCase();
if (content.HasProperty(alias))
{
property.SetValue(model, Convert.ChangeType(content.GetProperty(alias).Value, property.PropertyType));
}
}
return model;
}
}
}
@s6admin
Copy link

s6admin commented Mar 12, 2016

Unless I'm implementing things wrong it doesn't seem like this works with the new PublishedContentModels created by the ModelsBuilder in Umbraco 7.4 because it returns an error:

must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ModelMapper.Map(IPublishedContent)'

Soooooooo close!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment