IGridDataProvider erweitert [Compilerfehler]
IGridDataProvider
hat eine neue Methode GetQuery
erhalten. Diese liefert die Abfrage inklusive aller Filter aber ohne das Select
der Daten für die Spalten. In der Regel also Abfragen auf konkrete Datentabellen. Beispiel IQueryable<OrmCRMCompany>
oder IQueryable<OrmBABase>
. Bei Ansichten die keine Datensätze anzeigen die entsprechenden anderen Datentypen.
Attachment Handling
Der Umgang mit Dateianhänge wurde angepasst. Genaueres im Unterkapitel Attachment Handling
Überarbeitung des FormHandlings
Aus technischen Gründen, musste das FormHandling komplett überarbeitet werden. Daher müssen eigene Renderer und eigene Dialoge angepasst werden.
Folgende Nugets können deinstalliert werden
Von Business App werden folgende Nugets nicht mehr beötigt und können, wenn im Projekt keine Abhängigkeit vorhanden ist, deinstalliert werden.
- Elasticsearch.Net
- NEST
ConfigurationBase.DynamicallyGenerated jetzt automatisch
Das Property wird jetzt von BA.Core automatisch ermittelt und muss und kann nicht mehr zugewiesen werden.
=> In dynamischen Konfiguratione die Zeile
configuration.DynamicallyGenerated = true;
entfernen. Der Compiler weist im Zweifel auf den Fehler hin.
ConfigurationBase-Events jetzt alle protected
Folgende Events waren früher public:
protected virtual void BeforeSave() { }
protected virtual void AfterCacheRefresh() { }
protected virtual void AfterSave() { }
Falls die Methoden in projekteigenen Konfigurationen überschrieben wurden, müssen sie auf protected geändert werden. Der Compiler weist im Zweifel auf den Fehler hin.
IDataConfiguration geändert in IEntityConfigurationSpecifier
Das Interface IDataConfiguration
wurde ersetzt durch IEntityConfigurationSpecifier
.
Compilerfehler beim Zugriff auf config.GetDataSource()
- Ersetzen durch config.OrmDataSource
Falls man es öfter hat, führ eine globale Ersetzung von .GetDataSource()
durch .OrmDataSource
zum Ziel.
Eigene Konfigurations-Klassen, die das Interface implementiert haben
- Interface durch das neue ersetzen.
- Die Methode GetDataSource() umbenennen in GetOrmEntityConfigurationGuid().
- Die Methdoen GetListOfFieldsUsed() und GetListOfRelationDefinitionsUsed() ersatzlos entfernen.
Die Eigenschaft ControlBase.HasErrors existiert nicht mehr.
Alle Zuweisungen des Feldes sind ersatzlos zu entfernen.
Ebenfalls entfernt wurden HasDesignErrors
und DesignErrorTooltipMessage
.
Änderungen an CDPOrmFieldsProperties
Bei der Auswahl von Datenfeldern wird typischerweise CDPOrmFieldsProperties
eingesetzt. Nun gibt es jetzt Datenspalten die nicht beschreibbar sind und Datenspalten die in Masken im Normalfall nicht beschrieben werden sollen. Technisch aber beschreibbar sind. In diesem Zusammenhang wurde der Datenprovider überarbeitet.
Read-Only-Spalten [immer prüfen]
Die Auswahl von Datenspalten muss jetzt sauber differenzieren, ob auch nur lesbare Spalten gewünscht sind oder nicht. Dies geschieht über den Parameter includeReadOnly
:
ReadOnly
(default) – Es werden alle Spalten zur Auswahl angeboten, berechnete und normal bearbeitbare.
Diese Auswahl sollte verwendet werden, wenn die gewählte Spalte gelesen werden soll. Dann funktionieren auch automatisch die neuen, berechneten Spalten.None
– Es werden nur Spalten angeboten, die auch in Masken pflegbar sind.
Diese Auswahl ist empfohlen, wenn eine Spalte zum Schreiben/Befüllen gewählt werden soll.NoUIWrite
– Es werden auch Spalten angeboten, die zwar technisch schreibbar sind, aber nicht für die Änderung durch Endbenutzer vorgesehen sind, weil sie z.B. automatisch zugewiesen werden wieAttachmentState
. Diese Auswahl wird z.B. für die Workflow-Akion ChangeFieldAction verwendet.
Datentypeinschränkung [nur bei Compilerfehler bearbeiten]
Die Optionen TypesToShow
und TypesNotToShow
haben jetzt den Datentyp IReadOnlyCollection<EnumDataTypes>
. Dem sollte i.a. ein Array von EnumDataTypes[]
zugewiesen werden.
Die Auswahl ist jetzt unabhängig von den verwendeten Controls in der Entity-Konfiguration und analog zu CDPCommonFieldsProperties.TypesToShow
.
Die Werte sind im allgemeinen wie folgt zu ersetzen. (Einige der Ersetzungen sind bereits Arrays, andere brauchen noch ein new[]
.)
OrmTextField
->EnumDataTypes.String
OrmTextFieldBase
->EnumDataTypes.TextTypes
OrmNumericFieldBase<>
->EnumDataTypes.NumberTypes
OrmTextFieldBase
, @OrmNumericFieldBase<>->
EnumDataTypes.TextNumberTypes@OrmDecimalField
->EnumDataTypes.Decimal
OrmDateTimeField
->EnumDataTypes.DateTime
OrmHTMLField
->EnumDataTypes.HTML
OrmAttachmentsField
->EnumDataTypes.Attachments
OrmEnumFieldBase
->EnumDataTypes.EnumTypes
OrmEnumField
->ReferenceEnumTypes
OrmSubRecordField
->EnumDataTypes.SubRecords
Wenn TypesToShow direkt in einem Attribut angegeben wird, müssen statt dessen die EnumDataSource.XXXGuid
Werte verwendet werden:
[CDPOrmFieldsProperties(typesToShow: new[] { EnumDataTypes.SubRecordsGuid })]
Eigene Steuerelemente für Masken
WIe im vorherigen Abschnitt erläutert wurde der Datenprovider CDPOrmFieldsProperties
überarbeitet. Typischerweise erweitern Steuerlemente für Masken DataControlBase
, welche eine virtuelle Methode GetTypesOfOrmFieldName
zur Beeinflussung der Feldauswahl zur Verfügung stellt. Deren Signatur hat sich nach den identischen Konzept wie im vorherigen Abschnitt erläutert umgestellt.
protected override IReadOnlyCollection<EnumDataTypes> GetTypesOfOrmFieldName()
Konfigurations-Datenprovider mit DataSources Filter [Compiler-Fehler oder Exception]
Wenn eigene Controls Eigenschaften haben, die fremde Konfigurationen (z.B. Masken) auswählen und einen DataSource-Filter nutzen, dann ist folgendes zu beachten:
- Die Enum-Werte lauten jetzt
MatchAnyTypeOrAscendant und MatchAnyTypeExcact -> MatchSubSet
MatchAllTypesOrAscendants -> MatchSuperSet - Zudem ist die Auswahl einer Match-Option jetzt obligatorisch, sobald ein DataSource-Filter verwendet wird. Andernfalls kommt eine ArgumentException zu Laufzeit. Das ist aber selten, weil die alte StandardOption MatchAnyTypeExcact nicht korrekt mit Basisdatentypen umgehen konnte und deshalb kaum verwendbar war.
- Wenn nur Konfigurationen mit exakt übereinstimmenden Datentypen ausgewählt werden sollen, steht zusätzlich die Option MatchExact zur Verfügung.
Projektcodemigration: AttributesCache R.I.P [nur bei Compilerfehler]
Die Klasse AttributesCache existiert nicht mehr. Statt dessen wird eine .NET Collection verwendet. Alle Methoden der Klasse stehen jetzt als kompatible Extensions zur Verfügung.
- Alle Vorkommen von AttributesCache durch IReadOnlyCollection ersetzen.
- Falls das Field AttributesCache.Attributes verwendet wurde, “.Attributes” entfernen. Die .NET Collection ist bereits die Liste der Attribute.
Änderungen in den Nugets, um eigene MVC-Views zu implementieren
Möchte man in einem Projekt mit MVC-Views (also .cshtml) arbeiten, braucht man RazorGenerator.MsBuild als Nuget.
Ansonsten bekommt man diese Fehlermeldung
"die Ansicht ... oder die entsprechende Gestaltungsvorlage wurde nicht gefunden, oder keines der Ansichtsmodule unterstützt die durchsuchten Speicherorte. die folgenden Speicherorte wurden durchsucht: ..."
Kann über den Nuget Package Manager deinstalliert bzw installiert werden.
OrmBase.ModelState existiert nicht mehr [bei Compilerfehler]
ModelState ist eine Eigenschaft einer Maske nicht eines Datensatzes. Eventuelle Validierungsfehler (z.B. in OnBeforeValidation
) müssen in OrmBase.ValidationResults
geschrieben werden. Von dort werden sie automatisch in den ModelState
der Maske übertragen.
Die Syntax ist:
orm.ValidationResults.Add(new BAValidationResult(new ValidationContext(...), ...));
Klasse BAValidationBase existiert nicht mehr [bei Compilerfehler]
Klassen, die davon geerbt haben, sollten jetzt direkt von ValidationAttribute
erben und dessen Methode IsValid(object value, ValidationContext validationContext)
überschreiben. Diese liefert statt einem boolean
ein ValidationResult
.
Für die Implementierung wird entweder die Hilfsmethode ValidationAttributeHelper.CreateValidationResult
empfohlen, die den passenden Ergebnistyp aus der Boolean-Bedingung erzeugt, oder new BAValidationResult(validationContext, ...)
im Fehlerfall.
HtmlToPlainText, PlainTextToHtml, CleanHtml, HtmlEquals umgezogen [optional]
Die Funktionen sind von Api.Text nach APi.Html umgezogen. Die alten Funktionen sind obsolet, funktionieren aber noch.
ORM-Event OnRelationsCreated
Dieses Event wurde aufgrund eines Fehlers vor Release 7.0 auch bei Aktualisierungsgruppen in Masken aufgerufen. Das ist jetzt nicht mehr der Fall.
Falls sich Implementierungen auf dieses Verhalten verlassen haben, um z.B. auf aktuelle Benutzereingaben in der Maske zu reagieren, müssen sie angepasst werden und zusätzlich OnUIRefreshing implementieren. Dieses wird bei Aktualisierungsgruppen aufgerufen.
LoadFromCache: createIfNotExists entfernt [bei Compilerfehler]
Falls der optionale Parameter createIfNotExists von ormbabase.LoadFromCache in Projektcode verwendet wurde, muss dieser beim Aufruf entfernt werden.
web.config
Die Nugets “BundleTransformer.Core” und “BundleTransformer.NUglify”, deren Installation automatisch folgende Einträge in der web.config-Datenbank vornimmt:
<sectionGroup name="bundleTransformer">
<section name="core" type="BundleTransformer.Core.Configuration.CoreSettings, BundleTransformer.Core" />
<section name="nuglify" type="BundleTransformer.NUglify.Configuration.NUglifySettings, BundleTransformer.NUglify" />
</sectionGroup>
Die Konfiguration dieser Pakete erfolgt ebenfalls in der web.config Datei, direkt im Bereich <configuration>
. Sollte durch die Installation der Nuget-Pakete eine Standardkonfiguration hinzugefügt worden sein, ist diese zu löschen.
Folgende Konfiguration muss in der web.config-Datei hinzugefügt werden, damit die Optimierung reibungsfrei durchgeführt werden kann:
<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
<core>
<css defaultMinifier="NUglifyCssMinifier">
<translators>
<add name="NullTranslator"
type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core"
enabled="false"/>
</translators>
<postProcessors>
<add name="UrlRewritingCssPostProcessor"
type="BundleTransformer.Core.PostProcessors.UrlRewritingCssPostProcessor, BundleTransformer.Core"
useInDebugMode="false"/>
</postProcessors>
<minifiers>
<add name="NullMinifier"
type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core"/>
<add name="NUglifyCssMinifier"
type="BundleTransformer.NUglify.Minifiers.NUglifyCssMinifier, BundleTransformer.NUglify"/>
</minifiers>
<fileExtensions>
<add fileExtension=".css"
assetTypeCode="Css"/>
<add fileExtension=".css?BA"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.Appointment"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.Dashboard"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.FollowUp"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.Report"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.Activity"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.CRM.Contact"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.CRM.Activity"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.CRM.Opportunity"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.CRM.FollowUp"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.CRM.Project"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.CRM.Appointment"
assetTypeCode="Css"/>
<add fileExtension=".css?BA.CRM.Marketing"
assetTypeCode="Css"/>
</fileExtensions>
</css>
<js defaultMinifier="NUglifyJsMinifier">
<translators>
<add name="NullTranslator"
type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core"
enabled="false"/>
</translators>
<minifiers>
<add name="NullMinifier"
type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core"/>
<add name="NUglifyJsMinifier"
type="BundleTransformer.NUglify.Minifiers.NUglifyJsMinifier, BundleTransformer.NUglify"/>
</minifiers>
<fileExtensions>
<add fileExtension=".js"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.Event"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.Appointment"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.Dashboard"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.FollowUp"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.Report"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.Contact"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.Activity"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.Correspondence"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.BusinessMail"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.CRM.Contact"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.CRM.Activity"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.CRM.Correspondence"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.CRM.Opportunity"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.CRM.FollowUp"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.CRM.Project"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.CRM.Appointment"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.CRM.Evalanche"
assetTypeCode="JavaScript"/>
<add fileExtension=".js?BA.CRM.Marketing"
assetTypeCode="JavaScript"/>
</fileExtensions>
</js>
</core>
<nuglify>
<css allowEmbeddedAspNetBlocks="false"
blocksStartOnSameLine="NewLine"
ignoreAllErrors="false"
ignoreErrorList=""
indentSize="4"
indentType="Space"
lineBreakThreshold="2147482647"
outputMode="SingleLine"
preprocessorDefineList=""
termSemicolons="false"
colorNames="Hex"
commentMode="Important"
decodeEscapes="true"
fixIE8Fonts="true"
minifyExpressions="true"
removeEmptyBlocks="true"
severity="0"/>
<js allowEmbeddedAspNetBlocks="false"
blocksStartOnSameLine="NewLine"
ignoreAllErrors="false"
ignoreErrorList=""
indentSize="4"
indentType="Space"
lineBreakThreshold="2147482647"
outputMode="SingleLine"
preprocessorDefineList=""
termSemicolons="false"
alwaysEscapeNonAscii="false"
amdSupport="false"
collapseToLiteral="true"
constStatementsMozilla="false"
debugLookupList="Debug,$Debug,WAssert,Msn.Debug,Web.Debug"
errorIfNotInlineSafe="false"
evalLiteralExpressions="true"
evalTreatment="MakeImmediateSafe"
ignoreConditionalCompilation="false"
ignorePreprocessorDefines="false"
inlineSafeStrings="true"
knownGlobalNamesList=""
localRenaming="CrunchAll"
macSafariQuirks="true"
manualRenamesProperties="true"
noAutoRenameList="$super"
preserveFunctionNames="false"
preserveImportantComments="true"
quoteObjectLiteralProperties="false"
removeFunctionExpressionNames="true"
removeUnneededCode="true"
renamePairs=""
reorderScopeDeclarations="false"
scriptVersion="EcmaScript6"
strictMode="false"
stripDebugStatements="true"
severity="0"/>
</nuglify>
</bundleTransformer>
Fügt ein Service-Projekt eigene JavaScript- und/oder CSS-Bundles hinzu, so müssen an dieser Stelle die “fileExtensions” entsprechend hinzugefügt werden (.css?<assembly-name>
oder .js?<assembly-name>
).