Mvc: IDisplayMetadataProvider result seems to be cached somehow?

Created on 30 Aug 2017  路  9Comments  路  Source: aspnet/Mvc

I'm writing an integration test for my globalization infrastructure which works roughly like this:

  1. Surf to the page
  2. Check that the property (which is null, and outputted via the DisplayFor html helper) shows the DisplayFormat.NullDisplayText
  3. Change the culture
  4. Surf again to the page
  5. Check that the property now shows the localized DisplayFormat.NullDisplayText

To make the NullDisplayText work we have the following IDisplayMetadataProvider registered with the ModelMetadataDetailsProviders:

public void CreateDisplayMetadata (DisplayMetadataProviderContext context)
{
  var localizer = _localizationOptions.DataAnnotationLocalizerProvider(
      context.Key.ContainerType ?? context.Key.ModelType,
      _stringLocalizerFactory);

  if (localizer == null)
    return;

  var displayFormatAttribute = context.Attributes.OfType<DisplayFormatAttribute>().FirstOrDefault();
  if (!string.IsNullOrEmpty(displayFormatAttribute?.NullDisplayText))
    context.DisplayMetadata.NullDisplayText = localizer[displayFormatAttribute.NullDisplayText];
}

The CreateDisplayMetadata method is called once when I initially surf to the page, however, after changing the culture and re-visiting the page it is not called again and therefore the nulldisplaytext is not localized.

Any ideas? Is this a bug in the caching algorithm? Is there any workaround?

3 - Done bug

Most helpful comment

FYI @mkArtakMSFT and @danroth27: I've got time to do this one and have moved it into Preview1.

All 9 comments

@rynowak / @dougbu - how does the caching of metadata work? What's the story for how to do localization with these?

Metadata about both types and properties is cached for the application's lifetime. The story for localization is that most localizable strings are Func<string> properties in DisplayMetadata.

Because NullDisplayText is not localizable in data annotations, it is not in MVC either. We could change this but removing the existing property or changing its type (not the only options of course) would be breaking changes.

I think NullDisplayText should be localizeable somehow, a string like "<empty>" just doesn't work with the Chinese culture, or any other culture than English. So it'd be great to have a Func here as well.

Seems like we could easily add a new NullDisplayTextProvider property that is a Func<string> to the DisplayMetadata class, alongside the original property:
https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Metadata/DisplayMetadata.cs#L111

The default implementation could just return the NullDisplayText property, but a developer could set their own function to return localizable text.

While we're at it, we should do the same thing for the two format string properties that are there: DisplayFormatString, EditFormatString.

FYI @mkArtakMSFT and @danroth27: I've got time to do this one and have moved it into Preview1.

Thanks @dougbu!

Misapplied the Done label, sorry.

c9ac2e6c29

Was this page helpful?
0 / 5 - 0 ratings