Verhaltensänderung bei Relationsdefinitionen (Targets) und Api.Relation
Wurden diese Methoden genutzt enthielt die Ergebnismenge (im Defaultverhalten) nur aktive Datensätze. Nun werden auch die inaktiven in die Liste eingeschlossen. Ist dies nicht gewünscht, muss die Methode entsprechend ergänzt werden.
RelatedChildren.Where(ff => ff.IsActive).Count()
Falls die Api.Relation
direkt genutzt wurde, muss der Parameter entryActiveState
entsprechend belegt werden.
Reduktion der Nuget-Pakete in Projekten
Die BA-Nugets bringen ihre Laufzeitabhängigkeiten nun selbst mit. Es ist daher nicht mehr erforderlich oder empfohlen, alle zur Laufzeit benötigten Nuget-Pakete in allen Projekten zu installieren. Davon profitiert die Geschwindigkeit von Kompilieren und IntelliSense.
Typischerweise können alle Nugets bis auf diese entfernt werden:
- BA.* – die BusinessApp-Module
- Standard-Nugets für Asp.NET MVC-Anwendungen
- Microsoft.AspNet.Mvc
- Microsoft.AspNet.Mvc.de
- Microsoft.AspNet.Razor
- Microsoft.AspNet.Razor.de
- Microsoft.AspNet.WebPages
- Microsoft.AspNet.WebPages.de
- Microsoft.Web.Infrastructure
- Unterstützung für TypeScript im Projekt
- Microsoft.TypeScript.MSBuild
- JSON Serialisierung
- Newtonsoft.Json
- DIInit
- Ninject
- Server-Log Funktionen
- NLog
- Eigene MVC Views im Projekt
- RazorGenerator.MsBuild
Folgende Nuget Pakete können zusätzlich wegen Abhängigkeiten zu weiteren BA oder BA.CRM Modulen nicht deinstalierbar sein
- BuildWebCompiler
- CsvHelper
- Microsoft.AspNet.WebApi.Client
- Microsoft.AspNet.WebApi.Core
- Microsoft.Exchange.WebServices
- RestSharp
- System.ValueTuple
Weitere Nuget-Pakete werden nur dann benötigt, wenn die Programmierung im Projekt explizit darauf zugreift, bespielsweise wenn eigene Logik für Microsoft-Exchange Synchronisation implementiert wurde.
Nacharbeiten
Projektdatei: System.Web.Optimization
Bei der Entfernung des Nugets System.Web.Optimization wird die Referenz auf diese DLL aus dem Projekt entfernt. Diese DLL wird zukünftig von Business App zur Verfügung gestellt. Dazu muss die Referenz in die Projektdatei eingefügt werden. (Pfad ggf. an BA-Version anpassen)
<Reference Include="System.Web.Optimization, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\BA.Core.8.0.0\lib\System.Web.Optimization.dll</HintPath>
</Reference>
Projektdatei: Independentsoft.Msg
Falls vorhanden, Referenz auf Independentsoft.Msg entfernen.
web.config: Hinzufügen BundleTransformer
In web.config den Abschnitt für bundleTransformer vor </configSections>
wieder eintragen oder die Änderung per git revert zurücknehmen:
<sectionGroup name="bundleTransformer">
<section name="core" type="BundleTransformer.Core.Configuration.CoreSettings, BundleTransformer.Core" />
<section name="nuglify" type="BundleTransformer.NUglify.Configuration.NUglifySettings, BundleTransformer.NUglify" />
</sectionGroup>
web.config: Ändern System.Diagnostics
Beim Eintrag die Version auf 6.0.0.1 ändern.
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.1" newVersion="6.0.0.1" />
</dependentAssembly>
web.config: Ändern Microsoft.Identity.Client
Beim Eintrag die Version auf 4.54.1.0 ändern.
<dependentAssembly>
<assemblyIdentity name="Microsoft.Identity.Client" publicKeyToken="0a613f4dd989e8ae" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.54.1.0" newVersion="4.54.1.0" />
</dependentAssembly>
web.config: Hinzufügen Azure.Core
Eintrag hinzufügen
<dependentAssembly>
<assemblyIdentity name="Azure.Core" publicKeyToken="92742159e12e44c8" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.35.0.0" newVersion="1.35.0.0" />
</dependentAssembly>
web.config: Aktualisierung WebGrease
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
</dependentAssembly>
Compilierfehler
Falls Compilierfehler wegen fehlender Namespaces auftreten:
Zuerst prüfen ob es nicht vielleicht nur verwaiste using-Direktiven sind => entfernen (geht mit Ctrl-R-G).
Ggf. ein zu viel entferntes Nuget wieder installieren, wenn der Projekt-Code dieses explizit benötigt.
Umorganisation Bundle Transformer
In der web.config den Bereich bundleTransformer
austauschen
<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" />
</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" />
</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>
RenderingUtils.SetHelpText, .SetRequired, .GetRealHelpTextPosition [bei Compilerfehler]
Die Methoden benötigen zusätzliche Informationen, um bei Teilmasken für Basistabellen dennoch die Eigenschaften des aktuellen konkreten Datensatzes (z.B. abweichende Hilfetexte oder Validatoren) zu berücksichtigen.
SetHelpText, SetRequired
Für die Methoden gibt es jetzt zusätzlich eine Implementierung in den Basisklassen der Renderer, die alle Kontextinformationen automatisch beschafft.
Vorher:
RenderingUtils.SetRequired(control, mvcxItem);
RenderingUtils.SetHelpText(control, mvcxItem);
Neu:
SetRequired(mvcxItem);
SetHelpText(mvcxItem);
Nur bei Renderern, die mehrere Controls selbst Rendern muss man die Methoden aus RenderingUtils mglw. weiterhin benutzen, falls die Eigenschaften für ein anderes Control als das aktuell im Fokus des Renderers befindliche gesetzt werden soll.
In dem Fall muss der zusätzliche Parameter attributes
mit den CustomAttributes
des Properties, auf das sich das gerade gerenderte Control bezieht, versorgt werden. Das bekommt man in Renderern über PreparedProperty.CustomAttributes
.
GetRealHelpTextPosition
Hier muss der zusätzliche Parameter immer wie o.g. versorgt werden.
Ausbau von ClientActionGridMassOperationBase.SomethingMustBeSelected
Da der Mechnismus für die Massenoperation alle Datensätze zu verarbeiten, auch wenn nichts Selektiert ist eine Weile nicht mehr funktioniert, wurde die Option entfernt.
GetFormAttributesForControl entfernt [bei Compilerfehler]
Die Methode RenderingUtils.GetFormAttributesForControl
existiert nicht mehr. Statt dessen ist DevExFormModel.AdditionalAttributes
jetzt eine Datenstruktur, aus der die gewünschten Informationen direkt entnommen werden können.
Das engste Äquivalent zu RenderingUtils.GetFormAttributesForControl(formModel.AdditionalAttributes, control)
ist formModel.AdditionalAttributes.Get(control.Id)
. Das liefert allerdings statt Dictionary<AttributeEnum, bool>
bei dem alle Werte true
sind ein IDictionary<AttributeEnum, AdditionalFormAttributes>
, also mit dem konkreten Attribut als Wert. ContainsKey
funktioniert darauf genauso. Allerdings kann Get
null
liefern, wenn es für das Control keine Attribute gibt.
Die üblichen Abfragen, ob für ein Control ein bestimmtest Attribut existiert, gehen aber wesentlich einfacher:
Alt:
Dictionary<AttributeEnum, bool> attributes = RenderingUtils.GetFormAttributesForControl(formModel.AdditionalAttributes, control);
if (attributes.ContainsKey(AttributeEnum.SkipIfNotEmpty))
...
Neu:
if (formModel.AdditionalAttributes.Contains(control.Id, AttributeEnum.SkipIfNotEmpty)
...
Statt der Abfrage auf AttributeEnum.ReadOnly
sollte unbedingt die Funktion IsControlEditable
verwendet werden, weil andernfalls nicht alle Read-Only-Ursachen berücksichtigt werden.
Alt:
Dictionary<AttributeEnum, bool> attributes = RenderingUtils.GetFormAttributesForControl(formModel.AdditionalAttributes, control);
if (attributes.ContainsKey(AttributeEnum.ReadOnly))
...
Neu:
if (!IsControlEditable(control))
...
Datenstruktur von AdditionalAttributes [bei Compilerfehler]
Falls in Renderen o.ä. direkt auf formModel.AdditionalAttributes
zugegriffen wird, sollte die neue Datenstruktur mit ihren Funktionen sinnvoll genutzt werden. Im Besonderen sollten Schleifen über die Attribute vermieden werden, auch LINQ-Schleifen wie .Where
oder .@Any@. Beispiel:
Alt:
if (!formModel.AdditionalAttributes.Any(ff => ff.ControlGuid == control.Id && ff.Attribute == AttributeEnum.ReadOnly))
formModel.AdditionalAttributes.Add(new AdditionalFormAttributes(control.ControlInternalName, control.Id, AttributeEnum.ReadOnly, control.GetType()));
Neu:
formModel.AdditionalAttributes.TryAdd(new AdditionalFormAttributes(control, AttributeEnum.ReadOnly));
Verändertes Interface IControlDataProvider [bei Compilerfehler]
Die Methode IControlDataProvider.GetByKey
wurde ersetzt durch GetByKeys
, um mehrere Schlüssel auf einmal abzufragen. Das ist vor allem für
Mehrfachselektionscontrols aus Performancegründen erforderlich.
Der eigene Datenprovider kann statt IControlDataProvider
zu implementieren, von der Basisklasse SimpleCDPBase
erben. Zusätzlich
- Das Property
Properties
entfernen. Das ist bereits in der Basisklasse enthalten. - Die Implementierungen der Methoden
GetRows
undGertByKey
mitoverride
deklarieren.
Falls es für den eigenen Datenprovider aus Gründen der Performance Sinn macht, kann man auch die Implementierung auf dem Interface IControlDataProvider
belassen und die eigene GetByKey
Implementierung auf GetByKeys
umstellen.
Umbau EnumControlBase.DataProviderProperties [bei Compilerfehler]
Bei Maskensteuerelementen für Auswahllisten wurde der Getter von DataProviderProperties
auf private
gesetzt. Für das Auslesen steht nun eine virtuelle Methode GetDataProviderProperties()
zur Verfügung, die jeweils einen Klon erstellt. Wurden eigene Steuerelemente auf Basis von EnumControlBase
implementiert oder bestehende erweitert kann eine Änderung notwendig sein (siehe).
Falls ein eigener Renderer implementiert wurde, der lediglich den Datenprovider geändert hat, ist dies nicht mehr notwendig. Man kann nun die GetDataProviderProperties()
dazu überschreiben.
Obsolete Klasse OperationFromActionOverSelectedRecordsIgniter entfernt [bei Compilerfehler]
Die seid längerem obsolete Klasse OperationFromActionOverSelectedRecordsIgniter
wurde entfernt. Siehe
Eigene DataProviderProperties Klassen
Die Properties-Klassen der DataProvider dürfen keine Referenzen auf veränderliche Datentypen enthalten..
List<String> PropertyName; // FALSCH!
GuidSet DataSources; // FALSCH!
IReadOnlyCollection<string> PropertyName; // richtig!
IReadOnlyCollection<Guid> DataSources; // richtig!
EnumLanguagesAll Language; // OK, Enum-Instanzen dürfen ohnehin nicht geändert werden.
Andernfalls kommt es bei der Implementierung von DataProvider-Modifier-Methoden zu schwer zu findenden Fehlern mit undefiniertem Verhalten, weil Änderungen an den Listen sich dauerhaft auf Masken aller Benutzer auswirken. Die Modifier-Implementierungen dürfen nur die Listen als Ganzes durch neue Listen mit anderem Inhalt ersetzen.
DataProviderProperties Attribute (bei Compilerfehler)
Die Properties-Klassen wurden bzgl. obiger Bedingung systematisch umgestellt. Vereinzelt kann es bei Attributen direkt an Properties dadurch zu Compilerfehlern kommen, wenn anstelle der Konstruktorargumente die Properties direkt zugewiesen wurden. Das muss ggf. angepasst werden.
Beispiel:
// Fehler
[CDPOrmEntitiesProperties(TypesToShow = new[] { typeof(OrmActivityBase) })]
// neu
[CDPOrmEntitiesProperties(typesToShow: new[] { typeof(OrmActivityBase) })]
Validierung bei eigenen Dialogen
Die Validator-Attribute werden nicht mehr automatisch validiert. Siehe dazu das entsprechende Kapitel
Änderungen am Widget Framework
- Methode
GetProvidedParameterJsonString
umbennant:GetAllProvidedParameterJsonString
. Die liefert nun eine Liste von Parametern (nicht mehr einzelne Parameter) in einem JSON formatierten String, - WidgetStates “ContentBlocked” und “ContentError” existieren nicht mehr,
- Die Methode
SetWidgetState
bekommt nicht mehr den ParameterblockWidgetIfNotLoaded
, - Widget Parameter
GridViewConfigWidgetParameter
umbenannt:GridViewOrCalendarConfigWidgetParameter
, - ParameterJsonString in
DataWidgetControllerBase
ist jetzt eine Liste von Parametern, - Methode in Widget.ts
SetWidgetState
bekommt nicht mehr den ParameterblockWidgetIfNotLoaded
, - WidgetStates “ContentError” und “ContentBlocked” existieren nicht mehr,