Skip to content

Commit

Permalink
Add NopMetadataProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanovM committed Apr 20, 2017
1 parent cf6d8b0 commit 38b7f50
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 36 deletions.
9 changes: 8 additions & 1 deletion src/Presentation/Nop.Web.Framework/Mvc/IModelAttribute.cs
@@ -1,7 +1,14 @@
namespace Nop.Web.Framework.Mvc

namespace Nop.Web.Framework.Mvc
{
/// <summary>
/// Represents custom model attribute
/// </summary>
public interface IModelAttribute
{
/// <summary>
/// Gets name of the attribute
/// </summary>
string Name { get; }
}
}
37 changes: 18 additions & 19 deletions src/Presentation/Nop.Web.Framework/Mvc/NopMetadataProvider.cs
@@ -1,32 +1,31 @@
#if NET451
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Linq;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Nop.Core;

namespace Nop.Web.Framework.Mvc
{
/// <summary>
/// This MetadataProvider adds some functionality on top of the default DataAnnotationsModelMetadataProvider.
/// It adds custom attributes (implementing IModelAttribute) to the AdditionalValues property of the model's metadata
/// so that it can be retrieved later.
/// Represents metadata provider that adds custom attributes to the model's metadata, so it can be retrieved later
/// </summary>
public class NopMetadataProvider : DataAnnotationsModelMetadataProvider
public class NopMetadataProvider : IDisplayMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
/// <summary>
/// Sets the values for properties of isplay metadata
/// </summary>
/// <param name="context">Display metadata provider context</param>
public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
{
var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
var additionalValues = attributes.OfType<IModelAttribute>().ToList();
//get all custom attributes
var additionalValues = context.Attributes.OfType<IModelAttribute>().ToList();

//and try add them as additional values of metadata
foreach (var additionalValue in additionalValues)
{
if (metadata.AdditionalValues.ContainsKey(additionalValue.Name))
throw new NopException("There is already an attribute with the name of \"" + additionalValue.Name +
"\" on this model.");
metadata.AdditionalValues.Add(additionalValue.Name, additionalValue);
if (context.DisplayMetadata.AdditionalValues.ContainsKey(additionalValue.Name))
throw new NopException("There is already an attribute with the name '{0}' on this model", additionalValue.Name);

context.DisplayMetadata.AdditionalValues.Add(additionalValue.Name, additionalValue);
}
return metadata;
}
}
}
#endif
}
54 changes: 39 additions & 15 deletions src/Presentation/Nop.Web.Framework/NopResourceDisplayName.cs
@@ -1,43 +1,67 @@
using Nop.Core;
using System.ComponentModel;
using Nop.Core;
using Nop.Core.Infrastructure;
using Nop.Services.Localization;
using Nop.Web.Framework.Mvc;

namespace Nop.Web.Framework
{
public class NopResourceDisplayName : System.ComponentModel.DisplayNameAttribute, IModelAttribute
/// <summary>
/// Represents model attribute that specifies the display name by passed key of the locale resource
/// </summary>
public class NopResourceDisplayName : DisplayNameAttribute, IModelAttribute
{
#region Fields

private string _resourceValue = string.Empty;
//private bool _resourceValueRetrived;

public NopResourceDisplayName(string resourceKey)
: base(resourceKey)
#endregion

#region Ctor

/// <summary>
/// Create instance of the attribute
/// </summary>
/// <param name="resourceKey">Key of the locale resource</param>
public NopResourceDisplayName(string resourceKey) : base(resourceKey)
{
ResourceKey = resourceKey;
}

#endregion

#region Properties

/// <summary>
/// Gets or sets key of the locale resource
/// </summary>
public string ResourceKey { get; set; }

/// <summary>
/// Getss the display name
/// </summary>
public override string DisplayName
{
get
{
//do not cache resources because it causes issues when you have multiple languages
//if (!_resourceValueRetrived)
//{
var langId = EngineContext.Current.Resolve<IWorkContext>().WorkingLanguage.Id;
_resourceValue = EngineContext.Current
.Resolve<ILocalizationService>()
.GetResource(ResourceKey, langId, true, ResourceKey);
// _resourceValueRetrived = true;
//}
//get working language identifier
var workingLanguageId = EngineContext.Current.Resolve<IWorkContext>().WorkingLanguage.Id;

//get locale resource value
_resourceValue = EngineContext.Current.Resolve<ILocalizationService>().GetResource(ResourceKey, workingLanguageId, true, ResourceKey);

return _resourceValue;
}
}

/// <summary>
/// Gets name of the attribute
/// </summary>
public string Name
{
get { return "NopResourceDisplayName"; }
get { return nameof(NopResourceDisplayName); }
}

#endregion
}
}
3 changes: 2 additions & 1 deletion src/Presentation/Nop.Web/Startup.cs
Expand Up @@ -5,6 +5,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Nop.Core.Extensions;
using Nop.Web.Framework.Mvc;
using Nop.Web.Framework.Mvc.Extensions;
using Nop.Web.Framework.Mvc.Routes;

Expand Down Expand Up @@ -41,7 +42,7 @@ public Startup(IHostingEnvironment environment)
public IServiceProvider ConfigureServices(IServiceCollection services)
{
//add MVC feature
services.AddMvc();
services.AddMvc().AddMvcOptions(options => options.ModelMetadataDetailsProviders.Add(new NopMetadataProvider()));

//add MiniProfiler services
services.AddMiniProfiler();
Expand Down

0 comments on commit 38b7f50

Please sign in to comment.