Ich bin gerade dabei, Validierungsnachrichten anzupassen. Es funktioniert gut mit der MessageTemplates-Eigenschaft. Allerdings verwendet es% displayName%, um den Namen der Eigenschaft zu rendern, und ich kann nicht herausfinden, wie man diesen Wert überschreibt? Gibt es das überhaupt zu tun?brisejs: überschreiben displayname
Antwort
Dies ist noch nicht gut dokumentiert, aber Sie können einfach die 'displayName'-Eigenschaft auf eine beliebige dataProperty setzen und dies überschreibt den automatisch generierten Anzeigenamen und wird für alle Validierungsnachrichten für diese Eigenschaft verwendet. So
var custType = myEntityManager.metadataStore.getEntityType("Customer");
var dp = custType.getProperty("companyName");
dp.displayName = "My custom display name";
Lesen Sie bitte auch „Anpassen der Nachrichtenvorlagen“ am unteren Rand dieser Seite: Breeze Validation
Ich wollte auch, dies zu tun, aber ich die [Name] Attribut von meinem EF verwenden wollte Modell. Ich konnte niemanden finden, der ein Beispiel dafür hatte, nachdem ich einen Weg gefunden hatte, den ich zu teilen glaubte.
Zuerst dehnte ich die Metadaten aus meinen BreezeController zurückgegeben:
[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();
}
Dann habe ich ein wenig Javascript, nachdem die Metadaten laden die Anzeigenamen aus dem erweiterten Metadaten zu stecken, wo Breeze wollen sie finden.
Ich benutze eckig also, wenn Sie nicht sind, können Sie die eckigen Sachen ignorieren und wahrscheinlich die Idee bekommen. Das scheint ziemlich gut zu funktionieren. Es sollte ziemlich einfach sein, dies auch auf andere Modellattribute wie das Validierungsattribut RegularExpression auszuweiten. Ich werde wahrscheinlich als nächstes daran arbeiten.
FYI, ein Teil dieses Codes ist nicht optimiert und könnte wahrscheinlich umgestaltet werden, ein bisschen putzig, aber ich habe es gerade funktioniert und dachte, ich würde teilen. Wenn jemand Vorschläge für einen besseren Weg hat, lassen Sie es mich wissen. Hoffentlich wird es Breeze erlauben, die Metadaten in Zukunft noch besser zu unterstützen. Das scheint ein bisschen wie ein Hack zu sein.
Mit Blick auf http://www.breezejs.com/sites/all/apidocs/files/a40_entityMetadata.js.html#l1452,
dies durch Umbenennen der bestehenden „name“ Wert nameOnServer verbessert werden könnte (die getDataProperty Anruf zu erfüllen) und der Displayname Wert als „name“ Einfügen?
Nach jpcoder Anfrage für Anregungen, geht hier meinen leicht verbesserten Server-Teil:
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;
}
Eine notwendige Änderung des Server-Code ist, dass, wenn Sie Ihre Modellklassen in unterschiedlichen Baugruppen sind, können Sie nicht
könnenType t = Type.GetType(nameSpace + "." + typeName);
Sie benötigen den Namespace pro Typ (der in den Metadaten ist), und (denke ich) BuildManager zu verwenden, um die entsprechenden Typen in verschiedenen Assemblys zu suchen. Das Mapping von cSpaceOSpaceMapping könnte eleganter erreicht werden, aber ich hatte keine Zeit, die verschiedenen json-Formatierungsoptionen zu recherchieren.
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;
}
}
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();
Während dieser Code die Frage beantworten kann, wäre es besser, etwas _context_ einzubeziehen, _how_ es funktioniert zu erklären und _when_, um es zu benutzen. Nur-Code-Antworten sind auf lange Sicht nicht nützlich. –
Verbesserung jpcoder Antwort ...
Für mich die meisten meiner Display Veränderungen waren „PascalCaseFieldName“ oder „camelCaseFieldName“ mit „Versalien Feldname“ zu ersetzen.Anstatt also jede Eigenschaft DisplayName auf dem Server festzulegen, habe ich eine Standardfunktion zum Festlegen von displayName angewendet.
Endergebnis war viel weniger EF Annotation erforderlich. Mein TypeScript ist:
manager.metadataStore.getEntityTypes().forEach(function (storeEntityType) {
if (!(storeEntityType instanceof breeze.EntityType)) {
throw new Error("loadExtendedMetadata found '" + storeEntityType
+ "' StructuralType that is not an EntityType (e.g. 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(/([A-Z])/g, " $1").substring(1);
});
});
wie ich schon sagte, das kann ich nur die Nachricht anpassen, die ich bereits mache. Aber wie überschreibe ich den Namen der Eigenschaft? Wenn ich eine Eigenschaft namens ProductTitle habe, möchte ich, dass% displayName% zum Beispiel "Produkttitel" anzeigt. – Sam
Mein Fehler, ich hätte Ihren Beitrag sorgfältiger lesen sollen. Ich habe die obige Antwort aktualisiert. –
ausgezeichnet, das ist was ich brauchte! Danke vielmals ! – Sam