Breezejs: display name override

I am going to configure verification messages. It works fine using the messageTemplates property. However, it uses% displayName% to display the property name, and I cannot find out how to override this value? Is there any way to do this?

+7
source share
7 answers

This is not YET well documented, but you can simply set the displayName property on any dataProperty, and this will override the auto-generated display name and will be used for all validation messages for this property. So

var custType = myEntityManager.metadataStore.getEntityType("Customer"); var dp = custType.getProperty("companyName"); dp.displayName = "My custom display name"; 

Also see "Customize Message Templates" at the bottom of this page: Breeze Validation

+7
source

I also wanted to do this, but I wanted to use the [DisplayName] attribute from my EF model. I could not find anyone who would have an example of this, after I found a way that I thought I would share.

First, I expanded the metadata returned from my BreezeController:

 [HttpGet] public string Metadata() { // Extend metadata with extra attributes JObject metadata = JObject.Parse(contextProvider.Metadata()); string nameSpace = metadata["schema"]["namespace"].ToString(); foreach (var entityType in metadata["schema"]["entityType"]) { string typeName = entityType["name"].ToString(); Type t = Type.GetType(nameSpace + "." + typeName); foreach (var prop in t.GetProperties()) { foreach (var attr in prop.CustomAttributes) { string name = attr.GetType().Name; foreach (var p in entityType["property"]) { if (prop.Name == p["name"].ToString()) { if (attr.AttributeType.Name == "DisplayNameAttribute") { DisplayNameAttribute a = (DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute)); p["displayName"] = a.DisplayName; break; } } } } } } return metadata.ToString(); } 

Then I added a little javascript after loading the metadata to pop the display names from the extended metadata where Breeze wants to find them.

 manager.fetchMetadata().then(function (md) { angular.forEach(md.schema.entityType, function (et) { var etype = manager.metadataStore.getEntityType(et.name); angular.forEach(et.property, function (p) { var prop = etype.getProperty(p.name); prop.displayName = p.displayName; }); }); console.log("starting app"); angular.bootstrap($("#app"), ["app"]); }); 

I use angular, so if you cannot, you can ignore the angular stuff and probably get this idea. This seems to work pretty well. This should be fairly easy to extend to other attributes of the model, as well as to the regular expression validation attribute. I will probably be working on this.

FYI, some of this code is not optimized and probably can be reorganized, a little prepared, but I just got it working and thought I would share. If anyone has any suggestions for a better way, let me know. Hopefully Breeze will expand metadata in a more reliable way in the future. It looks like a hack.

+13
source

Following the jpcoder request for suggestions, here comes my improved part of the server:

 JObject metadata = JObject.Parse(contextProvider.Metadata()); string nameSpace = metadata["schema"]["namespace"].ToString(); foreach (var entityType in metadata["schema"]["entityType"]) { string typeName = entityType["name"].ToString(); Type t = Type.GetType(nameSpace + "." + typeName); IEnumerable<JToken> metaProps = null; if (entityType["property"].Type == JTokenType.Object) metaProps = new[] { entityType["property"] }; else metaProps = entityType["property"].AsEnumerable(); var props = from p in metaProps let pname = p["name"].ToString() let prop = t.GetProperties().SingleOrDefault(prop => prop.Name == pname) where prop != null from attr in prop.CustomAttributes where attr.AttributeType.Name == "DisplayNameAttribute" select new { Prop = p, DisplayName = ((DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute))).DisplayName }; foreach (var p in props) p.Prop["displayName"] = p.DisplayName; } 
+3
source

Looking at http://www.breezejs.com/sites/all/apidocs/files/a40_entityMetadata.js.html#l1452 ,

could be improved by renaming the existing "name" value to nameOnServer (to satisfy the getDataProperty call) and inserting the DisplayNameAttribute value into "name"?

0
source

The necessary change to the server code is that if your model classes are in different assemblies, you cannot use

 Type t = Type.GetType(nameSpace + "." + typeName); 

You need a namespace for each type (which is in the metadata) and (I think) to use the BuildManager to search for the corresponding types in different assemblies. Mapping from cSpaceOSpaceMapping can be done more elegantly, but I didn't have time to explore the various json formatting options.

 JObject metadata = JObject.Parse(UnitOfWork.Metadata()); string EFNameSpace = metadata["schema"]["namespace"].ToString(); string typeNameSpaces = metadata["schema"]["cSpaceOSpaceMapping"].ToString(); typeNameSpaces = "{" + typeNameSpaces.Replace("],[", "]|[").Replace("[", "").Replace("]", "").Replace(",", ":").Replace("|", ",") + "}"; JObject jTypeNameSpaces = JObject.Parse(typeNameSpaces); foreach (var entityType in metadata["schema"]["entityType"]) { string typeName = entityType["name"].ToString(); string defaultTypeNameSpace = EFNameSpace + "." + typeName; string entityTypeNameSpace = jTypeNameSpaces[defaultTypeNameSpace].ToString(); Type t = BuildManager.GetType(entityTypeNameSpace, false); IEnumerable<JToken> metaProps = null; if (entityType["property"].Type == JTokenType.Object) metaProps = new[] { entityType["property"] }; else metaProps = entityType["property"].AsEnumerable(); var props = from p in metaProps let pname = p["name"].ToString() let prop = t.GetProperties().SingleOrDefault(prop => prop.Name == pname) where prop != null from attr in prop.CustomAttributes where attr.AttributeType.Name == "DisplayNameAttribute" select new { Prop = p, DisplayName = ((DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute))).DisplayName }; foreach (var p in props) { p.Prop["displayName"] = p.DisplayName; } } 
0
source
  JObject metadata = JObject.Parse(this._context.Metadata()); string EFNameSpace = metadata["schema"]["namespace"].ToString(); string typeNameSpaces = metadata["schema"]["cSpaceOSpaceMapping"].ToString(); typeNameSpaces = "{" + typeNameSpaces.Replace("],[", "]|[").Replace("[", "").Replace("]", "").Replace(",", ":").Replace("|", ",") + "}"; JObject jTypeNameSpaces = JObject.Parse(typeNameSpaces); foreach (var entityType in metadata["schema"]["entityType"]) { string typeName = entityType["name"].ToString(); string defaultTypeNameSpace = EFNameSpace + "." + typeName; string entityTypeNameSpace = jTypeNameSpaces[defaultTypeNameSpace].ToString(); Type t = BuildManager.GetType(entityTypeNameSpace, false); IEnumerable<JToken> metaProps = null; if (entityType["property"].Type == JTokenType.Object) metaProps = new[] { entityType["property"] }; else metaProps = entityType["property"].AsEnumerable(); var props = from p in metaProps let pname = p["name"].ToString() let prop = t.GetProperties().SingleOrDefault(prop => prop.Name == pname) where prop != null from attr in prop.CustomAttributes where attr.AttributeType.Name == "DisplayAttribute" select new { Prop = p, DisplayName = ((DisplayAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayAttribute))).Name }; foreach (var p in props) { p.Prop["displayName"] = p.DisplayName; } } return metadata.ToString(); 
0
source

Improving jpcoder response ...

For me, most of the changes to DisplayName consisted of replacing “PascalCaseFieldName” or “camelCaseFieldName” with “Uppercase Field Name”. Therefore, instead of setting each DisplayName property on the server, I applied the default function to set displayName.

The end result was much less than the required EF annotation. My TypeScript:

  manager.metadataStore.getEntityTypes().forEach(function (storeEntityType) { if (!(storeEntityType instanceof breeze.EntityType)) { throw new Error("loadExtendedMetadata found '" + storeEntityType + "' StructuralType that is not an EntityType (eg a ComplexType)"); } var extEntityType = extendedMetadata.entitiesExtended.find((extendedEntityType) => { return extendedEntityType.shortName + ":#" + extendedEntityType.nameSpace === storeEntityType.name; }); (storeEntityType as breeze.EntityType).getProperties().forEach((storeProperty) => { //Both NavigationProperty & DataProperty have displayName & nameOnServer properties var storeDataProperty = <breeze.DataProperty>storeProperty; var extProperty; if (extEntityType) { extProperty = extEntityType.propertiesExtented.find((extendedProperty) => { return extendedProperty.name === storeDataProperty.nameOnServer; }); } //Smart default: nameOnServer "PascalCaseFieldName" or "camelCaseFieldName" converted to "Upper Case Field Name" storeDataProperty.displayName = (extProperty && extProperty.displayName) || storeDataProperty.nameOnServer.replace(/^./, function (str) { // first ensure the first character is uppercase return str.toUpperCase(); // insert a space before all caps, remove first character (added space) }).replace(/([AZ])/g, " $1").substring(1); }); }); 
0
source

All Articles