DotVVM 4.3
DotVVM 4.3 includes two new built-in controls — ModalDialog and AddTemplateDecorator; a major upgrade of the routing system — route localization; better system for warnings; a dozen of new JS translations; and a number of bug fixes and performance improvements, such as the postback request compression.
Potential breaking changes
First, we present to you the bad news. Although we try to limit the number of breakages in minor versions, it if often impossible to fix serious glitches without changing the behavior of some components:
- Client-side
dotvvm.state
object is now frozen. Its modification will throw an exception when in JS strict mode (#1782). Previously, the modification was silently ignored. - Newtonsoft.Json was updated to 13.0.3
- Removed a redundant Microsoft.CodeAnalysis.CSharp dependency from DotVVM.AspNetCore. You might need to explicitly add it back if your application needs the package.
- If two
@property
directives define a property with the same name, an error is issued. - Controls registered using
AutoDiscoverControls
now use relative file paths instead of absolute paths in theSrc
property (#1817)
If you encounter any other regressions, please let us know, as they would most likely be accidental.
dot:ModalDialog
- wrapper for the HTML <dialog>
element (#1776)
DotVVM now includes a dot:ModalDialog
control which wraps the new native HTML <dialog>
element. It does not replace the dialogs in Bootstrap or BusinessPack, as it isn't styled.
<dot:ModalDialog Open={value: ShowDialog} CloseOnBackdropClick>
content
</dot:ModalDialog>
dot:ModalDialog
only supports the modal version of <dialog>
, as the non-modal version is accessible through basic HTML with a bidning in the open
attribute - <dialog open={value: ShowInlineDialog}>
New dot:AddTemplateDecorator
control (#1760)
dot:AddTemplateDecorator
is a new decorator which can prepend or append content to the decorated element. For example, you might use it to add an additional row to each entry in a grid view. In the following snippet, we use this to add a separate row for a description field, which is otherwise too long to fit into a table column.
<dot:GridView DataSource={value: MyTable}>
<RowDecorators>
<dot:AddTemplateDecorator>
<AfterTemplate>
<tr> <td colspan="8">{{value: Description}}</td> </tr>
</AfterTemplate>
</dot:AddTemplateDecorator>
</RowDecorators>
<Columns>
...
</Columns>
</dot:GridView>
Localizable routes (#1824, #1840)
DotVVM now has a mechanism for localizing the route URLs. First, you need to apply a middleware which sets the correct CurrentCulture based on url prefix or the Accept-Language header.
Based on CurrentCulture, DotVVM will decide to which language should the route URL match. By default, DotVVM does not consider alternative languages. You can reconfigure it to accept alternative URL languages or to redirect to the "correct" language variant.
In the following example, we register a localized route and configure DotVVM to redirect if the route language does not match the selected language. If we take requested culture from Accept-Language or a cookie, we probably want to redirect users to the URL language of their preference:
config.RouteTable.Add("MyLocalizableRoute", "localizable-route", "Views/LocalizableRoute.dothtml",
localizedUrls: [
new("cs", "lokalizovana-routa"),
new("de", "lokalisierte-route"),
]);
// redirect to a matching language based on CultureInfo.CurrentCulture
config.RouteTable.AddPartialMatchHandler(new CanonicalRedirectPartialMatchRouteHandler());
Related to route localization, we have added the dot:AlternateCultureLinks
control which automatically generates <link rel=alternate>
elements pointing to the alternative language variants.
Warnings
The Compilation Status Page normally available at _dotvvm/diagnostics/compilation
now lists the warnings and errors of all compiled views. We strongly recommend you to examine the compilation page after upgrading, as it might uncover many mistakes in the application. Thanks to these warnings, we have fixed tens of small UI glitches on one of our systems, which were caused by wrong usage of some DotVVM properties. (related forum post, #1762)
The Control usage validation API now allows controls to emit custom warnings (#1751). For instance, you might want the user about a potential issue, such as specifying a redundant property:
[ControlUsageValidator]
public static IEnumerable<ControlUsageError> ValidateUsage(ResolvedControl control)
{
if (control.Properties.ContainsKey(LabelProperty) && control.Properties.ContainsKey(SomeTemplateProperty))
{
var propertyNode = control.GetValue(LabelProperty).DothtmlNode;
yield return new ControlUsageError("Label is ignored when SomeTemplate is also specified.", DiagnosticSeverity.Warning, propertyNode);
}
}
POST compression (#1766)
DotVVM 4.3 will use gzip to compress the command
and staticCommand
request bodies. As the requests are in JSON, the performance gain is quite significant if you aren't on gigabit Ethernet.
However, accepting compressed requests carries a risk of exposing the web server to "compression bomb" DOS attacks. To limit the potential impact, DotVVM now limits the maximum (uncompressed) postback size to 128 MiB, and the limit may be configured in config.Runtime.MaxPostbackSizeBytes
(it doesn't affect file upload). Postback compression may also be disabled using the config.Runtime.CompressPostbacks
option.
Note that request compression is only enabled in Production environment, because browsers are currently unable to display the uncompressed JSON in devtools.
Other improvements
- Markup file recompilation can be enabled in Production mode using the
DotvvmConfiguration.Runtime.ReloadMarkupFiles
option. - Changed operation name in DotVVM.Tracing.ApplicationInsights to the current route URL template (#1807, thanks to @mirecad)
- JS translations now avoid throwing exception even when the .NET equivalent does throw.
- New JS translations
IEnumerable.Last
,IEnumerable.First
Dictionary.GetValueOrDefault
TimeOnly.Hour
,Minute
,Second
,Millisecond
,FromDateTime
DateOnly.Year
,Month
,Date
,FromDateTime
DateTime.Now
,UtcNow
,Today
GridViewColumn.Visible
now accepts aresource
binding (#1826)- Added methods for compiling
command
andresource
bindings from string toBindingCompilationService.Cache
(#1839) - Client-side DotVVM logging may be configured using the
dotvvm.logging.setLogger
function. Note that the exact wording of log messages is not stable and may even differ in Development and Production environments. - Performance improvements, mainly HTML encoding in
HtmlWriter
thanks for the vectorizedIndexOfAny
implementation (#1851) InlineScriptResource
can now produce<script type=module
whenmodule
parameter is specified.- Prevent double postbacks after redirect in Deny or Queue
PostBack.Concurrency
mode by pretending that the redirect takes 5 seconds. Before those 5s pass, the page most likely unloads and the user does not get the chance to submit the duplicate postback (#1853) - Improved error messages (#1731, #1748, #1763, #1772, #1804, #1806)
Bugs/glitches fixed
- The client-side ViewModel is now restored on back/forward navigation (fixed in Chrome) and not restored on page reload (fixed in Firefox) (#1848)
- DotVVM.AspNetCore does not depend on Microsoft.CodeAnalysis.CSharp (#1743)
- Lambda argument type inference works for custom delegates (#1752)
- The "Force recompile all" button in the Compilation Status Page now actually forces rebuild of all pages (#1759)
- Fixed overload resolution of generic methods with default arguments (#1761)
- Fixed support for client-side property names which are not valid JS identifiers (#1790)
- Client-side validation is now correctly performed on typed objects inside a untyped object (#1803)
- (#1816)
- Controls registered using
AutoDiscoverControls
now use relative file paths (#1817) - Remove
defer
attribute from<script type=module
element as it is redundant and invalid HTML - Limit the number of queued
Task
s when doing pre-compilation to avoid stalling the ThreadPool (#1843) - Fixed the
CopyProperty
method to work with inherited properties containing bindings (#1850)
Thanks to @tomasherceg, @Mylan719, @mirecad, @exyi for contributing to this release