All Versions
Latest Version
Avg Release Cycle
80 days
Latest Release
129 days ago

Changelog History
Page 1

  • v2.5.0

    October 31, 2020

    πŸš€ This release includes all changes from DotVVM 2.5 Preview 2, as well as a few additional improvements:

    πŸ”‹ Features

    • πŸ‘ #880 - Inline editing is now supported in nested GridView controls
    • 0️⃣ #890 - DotVVM uses its own JsonSerializerSettings and doesn't rely on DefaultSettings
    • #877 - Control developers now may create attached property groups (e. g. <element MyExtensions.SomeGroup-SomeKey="something" />)
    • 0️⃣ #896 - The AddDotVVM and UseDotVVM methods now allow passing a custom instance of the DotvvmStartup class so it is possible to set its properties and so on. If you plan to use this feature, we recommend keeping a default constructor - otherwise, the DotVVM Compiler (used by the Visual Studio extension) will be unable to create the instance of this class.

    πŸ›  Fixes

    • πŸ›  Fixed references to netstandard in view compilation - these didn't work on older versions of .NET Framework.
    • πŸ›  Fixed deadlock occurring on the first HTTP request on OWIN.
    • πŸ›  Fixed incorrect invocation of the beforePostback event on static commands.

    ✨ Enhancements for framework developers

    • βœ… #874 - Infrastructure for end-to-end testing without the need of using Selenium.
    • 🏁 All paths are using forward slashes so everything in the repo should work on non-Windows machines.
  • v2.5.0-preview02

    August 23, 2020

    πŸ†• New Features

    Experimental: Explicit assembly loading

    Until now, DotVVM was searching all assemblies referenced by the application (including transitive references) to be able to find attached properties of controls (which may be declared in a different assembly than the controls), @import namespaces and other types. This was causing longer startup times as all assemblies were being searched.

    We've introduced the explicit assembly loading mode that loads and searches only the assemblies that you list explicitly in DotvvmStartup:


    This feature is experimental and must be turned on:


    🌐 We expect this feature to help a lot especially in the Web Forms modernization story - many legacy applications have unused references that are not even present in the bin directory. Without this feature, DotVVM was forcing the developers to fix all these issues first, which hurts the experience with getting DotVVM running.

    Redirection Helpers in the Route table


    We've added AddUrlRedirection and AddRouteRedirection in the DotVVM route table to simplify creating URLs that redirect to another place.

    It can be used e. g. for preserving old links when you need to change the URL for your pages.
    You can now register these old routes like this:

    // redirect from "article/15" to "content/article/15"
    config.RouteTable.AddUrlRedirection("ArticleRedirection", "article/{id}", c => "content/article/" + c.Parameters["id"]);
    // redirect from "calendar" to "calendar/{DateTime.Now.Year}/{DateTime.Now.Month}"
    config.RouteTable.Add("Calendar", "calendar/{year}/{month}", "Views/Calendar.dothtml");
    config.RouteTable.AddRouteRedirection("CalendarRedirection", "calendar", "Calendar", parametersProvider: (context) => {
        var now = DateTime.Now;
        return new Dictionary<string, object>() 
            { "year", now.Year },
            { "month", now.Month },

    View compilation on startup or on background

    (#841 and #846)

    Until now, all DotHTML files (views, master pages, and user controls) were compiled to their C# representation on the first HTTP request that needed them. Because of this, the first load of every DotVVM page took longer.

    We've added two new options:

    • DuringApplicationStart - this mode compiles all views and delays the startup of the application until the compilation is finished. The first HTTP request will be handled after all views have been compiled. This option is meant for production scenarios where you are using deployment slots (which will be switched once the application starts responding), or where downtime of a minute or two is not an issue.
    • 🐎 AfterApplicationStart - this mode doesn't delay the startup of the application but compiles all views on a background thread. It is possible to set a delay (configuration.Markup.ViewCompilation.BackgroundCompilationDelay) so it doesn't stress the CPU when other app initialization (populating caches etc.) tasks may be in progress. This option is great for applications that prioritize the page load time and have enough compute power so the background compilation won't affect the overall server performance.

    0️⃣ For development scenarios, we recommend sticking to the default Lazy mode as it doesn't slow down the application startup and compiles only the views that are actually needed (in the typical dev loop, the developer is not working with all pages of the app at the same time).

    ⬆️ REST API bindings upgraded to latest Swashbuckle.AspNetCore


    πŸ“‡ ASP.NET Core 3.0 introduced the new System.Text.Json serializer that replaced Newtonsoft.Json. This, and other changes, affected our Swashbuckle extensions for REST API bindings that helped DotVVM to generate better API clients based on Swagger / Open API metadata.

    πŸ“¦ The DotVVM.Api.Swashbuckle.AspNetCore package now references Swashbuckle.AspNetCore 5.4.1 which works with both ASP.NET Core 2.x and 3.x.

    πŸ“‡ If the API consumed by DotVVM app is hosted in ASP.NET Core 2.x, or if it explicitly uses the Newtonsoft.Json serializer in 3.x, you'll need to install Swashbuckle.AspNetCore.NewtonsoftJson package as well - otherwise the Open API metadata are not generated correctly.
    πŸš€ See the Swashbuckle 5.x release notes for more details.

    ValidationSummary improvement

    • πŸ’… #838 The ValidationSummary control has now a new property HideWhenValid that can hide the entire <ul> element when no errors are present. It helps when you need to apply styles like padding or border on the <ul> element.


    • πŸ’» #857 We've added the Context.GetCancellationToken() which returns the request cancellation token. You can pass this token to async methods if you expect they'll take long - it will allow them to cancel the operation if the user cancels the HTTP request (e. g. by refreshing the page or closing the browser).

    🐎 Startup performance tool

    • 🐎 #851 We've created a command-line tool that helps with measuring the startup performance of (not only DotVVM) ASP.NET web apps. It is not very sophisticated, but it is easy to use.

    It can be used like this:

    DotVVM.Tools.StartupPerfTester.exe Path/To/The/MyApp.csproj -t owin|aspnetcore --verbose --repeat 10

    πŸš€ The tool will publish the project in Release mode and try to run it 10 times while measuring the time until the app responds to the first HTTP request.

    Other small improvements

    • #819 Added AddRequiredResource method to ResourceManager to allow adding any kinds of resources to the current page.
    • 🐧 #789 and #826 We've done some improvements of build and testing scenarios for developers who work with the DotVVM repo on Linux.

    πŸ›  Fixes

    ViewModel Serialization

    • πŸ‘ #871 Until now, DotVVM didn't support nesting [Protect] attributes in the viewmodels. If you used the [Protect] attribute on a complex object or array in the viewmodel, and the attribute was used inside too, DotVVM didn't serialize the viewmodel correctly. We've redesigned parts of the serializer so the nesting is now supported. There are some restrictions - basically, the protection is additive: if you protect the parent object e.g. by SignData, the child cannot use None on any of its members. Also, if you use EncryptData, the child object cannot use just SignData.
    • πŸ›  #853 We've fixed serialization of KeyValuePair in viewmodels.

    Race conditions and problems in the postback pipeline

    • 🚦 #816 We've fixed several bugs in the postback pipeline that caused freezing of the page or skipping some postbacks, especially when using PostBack.Concurrency="Queue". The issue was happening when multiple postbacks were invoked quickly (e. g. triggered by the incoming SignalR messages).
    • πŸ›  #816 When the client received the Redirect response from the server, the next postbacks from the queue were still being sent which could lead to unexpected behavior. We've fixed the issue so now when the client gets redirect response, subsequent postbacks in the queue are discarded. It was causing issues, especially in SPAs when the postback responses could arrive even after another page was loaded.
    • #860 Another PR related to cleaning up the postback queues in SPA apps.
    • πŸ›  #876 When the user navigated to another page in SPA and then triggered a postback, it canceled the SPA navigation and the page may stop working. We've fixed this so all postbacks during SPA navigation are ignored. In case the SPA navigation fails, the postbacks start working again so the user is able to repeat the action and continue using the old page.

    DotVVM for Visual Studio compatibility issues

    • #818 Cleaned the DotvvmConfiguration JSON representation (getting rid of freezable collection wrappers) to fix the behavior of the VS extension.
    • πŸ“œ #822 We've fixed several issues in the binding expression parser so IntelliSense now works better in the VS extension.
    • #824 Added the [PropertyGroup] attribute (for properties like class-* or Param-*) that easies the discovery of the property groups for the VS extension IntelliSense.

    Binding expression cache on OWIN

    • πŸš€ #805 We've implemented a custom LRU (least recently used) cache for binding expressions that replaces the System.Web.Caching.Cache on OWIN. This fixes a memory leak that occurred in applications that generated a lot of binding expressions dynamically (e. g. by using DotVVM Dynamic Data). A temporary solution was to use ConcurrentDictionary-based cache, but this approach couldn't release unused bindings that weren't needed anymore.

    Other issues

    • πŸ›  #856 Fixed NullReferenceException when calling task-based methods without async/await statement.
    • πŸ›  #804 We've fixed passing non-primitive command arguments to methods (it was affecting mostly the staticCommand calls).
    • πŸ›  #859 Fixed the dependency cycle detection in the registration of resources in DotvvmStartup.
  • v2.4.0

    December 28, 2019

    Server side caching of view models (experimental)

    This feature can dramatically reduce data transferred between the server and the client.

    To enable this feature, add the following code snippet in DotvvmStartup.cs:


    When the feature is enabled, the viewmodels are cached on the server. When the client needs to do a postback, DotVVM can send only the diff of the viewmodel instead of serializing and transmitting the entire object. Thanks to this, we can save a lot of network traffic – almost 100% in extreme cases. Imagine a page with a GridView and a Delete button in every row – when you click on the button, the viewmodel on the client hasn’t changed at all. Thus the diff will be empty and the postback will transfer only a tiny JSON object with an identification of the button that was clicked – no viewmodel data at all. There were other ways to save this traffic, but this one is very convenient to use.

    🚦 The viewmodels are stored in memory by default, but the mechanism is extensible so you can use any storage you need – just implement the IViewModelServerStore interface. They are also deduplicated – we are using a hash of the viewmodel as a cache key, so when you use this feature on a public facing site which has the same β€œstatic” viewmodel for many users, the viewmodel will be kept in memory only once. And if the item is not in the cache any more, DotVVM will signal it to the client which will immediately issue a new postback with a full viewmodel.

    The feature can be enabled for all routes, or only for specific routes in the application. We recommend to enable it on less frequently used pages at first, and watch the memory consumption on the server – the cache should be cleaned up when the server gets low on memory, but still – we encourage to start using this feature carefully.

    We are still working on providing diagnostic tools that will help you identify how much this feature actually helped - how much traffic it saved and how much memory on the server it consumed.

    πŸ‘€ see #704 for more info

    Public API is using C# 8 nullable reference

    ⬆️ Most of the DotVVM API is now annotated by C#8 nullable reference types. If you are already using this C# feature, this may create bunch of new warnings when you upgrade DotVVM, but we recommend you do that as it may reveal new issues. If you are not using it, we suggest you give it a try, we have already discovered few glitches in DotVVM caused by nulls :)

    Frozen config

    To prevent strange behavior the entire DotvvmConfiguration is now frozen at runtime - it can not be modified after DotVVM is initialized.

    Unfortunately, this may break some of your code if you have attempted to modify some option at runtime. On the bright side, it will fail early rather than running into race conditions (or what could happen).

    πŸ”§ If you been modifying configuration just after the UseDotvvm function, you'll have to move the config modification into a lambda argument modifyConfiguration. For example, this works fine - the configuration is modified just before it gets frozen.

    app.UseDotVVM\<DotvvmStartup\>(..., modifyConfiguration: c =\> { c.RouteTable.Add(...); });


    Combining css classes

    πŸš€ When binding is assigned to both class attribute and Class-my-class property it used to behave in quite a strange way. With this release, the classes are combined.

    This will render a div with class="a b"

    \<div Class-a="{value: true}" class="{value: true ? 'a' : 'x'}" /\>

    πŸ‘€ see #783 for more info

    Validation of grid view cells

    We have added properties to add validators to grid view cells (for the inline-edit mode). The validator can be added by setting the property ValidatorPlacement="AttachToControl" or ValidatorPlacement="Standalone" (or both when separated by comma). Validator placement AttachToControl will add the Validator.Value to the rendered input control, placement Standalone will place separate element after the input. To control what the validator does, you can place Validator.InvalidCssClass and similar properties to the GridView.

    βž• Added InlineStylesheetResource

    πŸ’… Like the InlineScriptResource, you can now add inline CSS (in the <style> tag) using the InlineStylesheetResource. Unlike the script, style is placed in the head, so be careful not to add styles when rendering the page.

    ItemValueBinding (and friends) must return primitive types

    We have decided to fix one design debt. Controls based on SelectorBase control (which is ComboBox, ListBox, and MultiSelect) have ItemValueBinding. You could put any value in ItemValueBinding - there was no validation and it caused unpredictable behavior. When the result of ItemValueBinding was primitive type everything was fine. When the result type was a complex type the behavior got strange and there is unfortunately no way how to guarantee consistent behavior. So we have added a validation that the result type is primitive to make sure everything works fine.

    "Primitive" in this case means anything that is not translated to object on client-side - which are numbers, string and enums.

    Redirects from static commands

    You can now safely use IDotvvmRequestContext.RedirectToUrl and IDotvvmRequestContext.RedirectToRoute from static commands. Note that you can get the IDotvvmRequestContext from the standard dependency injection.


    ⚠ API for runtime warnings

    πŸ‘€ We have added infrastructure that will allow DotVVM to warn you at runtime when something suspicious happens. It will be reported to Asp.Net Core (that you'll probably see in the output of the server) and it will be propagated to JavaScript console.

    πŸš€ For example, it will warn you if you put something inside elements that must be self-closing in HTML. We will add more of these diagnostics in future releases. It is only enabled in debug mode.

    πŸ‘€ see #750 for more details (the API is described there)

    πŸ’… StyleBuilder.SetControlProperty polishing

    πŸ’… The SetControlProperty method used to add new controls to properties using Server Side Styles got polished. It should now work correctly in all three mode (Overwrite, Append, Ignore) regardless if the target is a control collection, a template or a single control.

    You can for example add a postback handler to all buttons that satisfy some conditions:

    config.Styles .Register\<LinkButton\>(m =\> m.HasHtmlAttribute("data-hashandler")) .SetControlProperty\<ConfirmPostBackHandler\>(PostBack.HandlersProperty, s =\> s.SetProperty(c =\> c.Message, "you sure?"), StyleOverrideOptions.Append)

    You can also use SetHtmlControlProperty and SetLiteralControlProperty to easily create a html element or a simple literal.


    Deserialization on client

    πŸ›  @Mylan719 has rewritten one of the most feared piece of code in our code base - the dotvvm.serialization.deserialize that copies a JavaScript object into the view model and wraps everything with knockout observables. Number of bugs got fixed in it, if you have encountered a strange behavior especially with static commands, it should be gone.

    πŸ“‡ Specifically, you can now copy object from one property to another using static commands {staticCommand: DataSet = FetchData(SelectedCategory); Metadata = DataSet.Metadata }.


    Binding may be specified without quotes

    Bindings in DotHTML files may be specified without the quotes around them (as you may be used to from React). This is now valid syntax:

    \<Button Click={command: MyMethod()} Text={value: MyLabel} /\>

    Just note that if you are also using Razor/MVC, don't get too much used to this, it behaves very strangely there.

    πŸ›  Bugfixes

    • RouteLink with binding in Query-something property now works as expected (#779)
    • πŸ›  Redirect now works as expected when Dictionary<string, object> is used as query. This fixes some issues with LocalizablePresenter. (#777)
    • Error are propagated correctly (i.e. is called) when network is unreachable (#770 #768)
  • v2.4.0-preview02

    December 28, 2019

    DotVVM 2.4 Preview 2

    πŸ‘Œ Support presenter factories on route groups #753

    If you have several routes that use different presenter that DotvvmPresenter, you can now easily specify the presenter for all routes in a route group.

    config.RouteTable.AddGroup("LocalizedRoutes", null, "Views", content =\> { content.Add("default", "", "default.dothtml"); content.Add("About", "about", "about.dothml"); }, LocalizablePresenter.BasedOnQuery("lang"));
  • v2.4.0-preview01

    September 18, 2019

    πŸ‘Œ Support for ASP.NET Core 3.0

    βœ… We have handled the breaking change in Microsoft.AspNetCore.Authorization between 2.2 and 3.0, and tested the framework extensively on ASP.NET Core 3.0.

    βœ… DotVVM is now fully suported (and tested) on:

    • OWIN and .NET Framework 4.5.1
    • πŸš€ ASP.NET Core 2.1 (LTS - Long-term Supported release)
    • πŸš€ ASP.NET Core 3.0 (latest release)

    πŸš€ Our plan is to always support the LTS releases and the last stable release of ASP.NET Core.

    ⬆️ If you are still on ASP.NET Core 2.0, upgrade soon as the minimum supported version of ASP.NET Core will be changed to 2.1 in the future.

    πŸ†• New MultiSelect control

    πŸ‘ DotVVM now support basic MultiSelect control. The API is basically the same as you know from ComboBox, except you have a SelectedValues property. Usage is like this:

    \<dot:MultiSelect SelectedValues="{value: SelectedValues}"DataSource="{value: Values}"SelectionChanged="{command: OnSelectionChanged()}"ItemValueBinding="{value: \_this}"ItemTitleBinding="{value: \_this}"ItemTextBinding="{value: \_this}" /\>

    0️⃣ Default presenter can be specified on route groups

    0️⃣ When creating a route group, you can now use overload DotvvmRouteTable.AddGroup(string groupName, string urlPrefix, string virtualPathPrefix, Action<DotvvmRouteTable> content, Func<IServiceProvider, IDotvvmPresenter> presenterFactory), which allows you to specify a default IDotvvmPresenter.

    With this change, you can for example specify that the routes should respect locale in the route parameter "Lang" by LocalizablePresenter.BasedOnParameter("Lang"):

    routes.AddGroup("MyGroup", "", "", table =\> { table.Add("{Lang}/Route1", "something", "something.dothtml"); }, LocalizablePresenter.BasedOnParameter("Lang"))

    Note that the presenter don't compose, it's not a middleware. So this route will only accept the Lang2 query parameter and always ignore the Lang1.

    routes.AddGroup("MyGroup", "", "", table =\> { table.Add("Route1", "something", "something.dothtml", LocalizablePresenter.BasedOnQuery("Lang2")); }, LocalizablePresenter.BasedOnQuery("Lang1"))

    πŸ‘€ (see #753)

    4096 commits

    πŸ”€ We have passed the virtual line of having 4096 merged in master branch. It does not mean anything in practise, fortunately git will still work and nothing else can be affected. So we used the very important "anniversary" to at least fix some typos 61ee3fd

    Methods invoked in sequence can be async

    When you make a (static) command like this: DoAsync(); Do2Async(), DotVVM automatically waits for both of these methods to finish. If you'd need to extract the resulting value of the Task<T>s, you can use the Result property - {staticCommand: Property = MyMethod().Result}.

    ⚑️ UpdateProgress can attach to particular concurrency queues (#720)

    ⚑️ <dot:UpdateProgress control has got properties IncludedQueues and ExcludedQueues which control where the update is triggered. For example, if you have a separate queue for background requests, you don't want to display any info about it:

    <dot:UpdateHandler ExcludedQueues="refreshOneGrid, refreshSecondGrid:" />

    πŸ‘ ValidationErrorFactory supports local variables (#734)

    When you create validation error paths using ValidationErrorFactory.CreateModelError or ValidationErrorFactory.CreateValidationResult from a Linq.Expression, you can also reference local variables and it will just propagate the resulting value from them. It's mostly useful for handling array indices:

    var index = SomeIndex;this.AddModelError(a =\> a.List[index].MyProperty, "It's wrong.");

    ⚑️ TextBox UpdateTextAfterKeydown changed to UpdateTextOnInput

    ⚑️ The UpdateTextAfterKeydown property was marked as obsolete. It was using the keypress event which didn't work on mobile devices and in other scenarios. The framework now uses oninput event for the same purpose.

    There is also a new event called TextInput which triggers in this case. Be careful not to trigger postbacks which transmit huge viewmodels - we encourage you to use static command with this event.

    Design-Time Error Checking in CheckBox, RadioButton and ComboBox

    We have added error checking for various controls that contain combination of properties whose data-binding types must match. The controls didn't work properly and sometimes their behavior was unpredictable when the types were different.

    \<dot:CheckBox CheckedItems="{value: \_parent.SelectedIds}" CheckedValue="{value: Id}" /\>

    The framework now checks that CheckedValue binding type is T and SelectedIds type is IEnumerable<T> (or IEnumerable<Nullable<T>>). Similar rules apply to RadioButton and ComboBox.

    We recommend to use Diagnostics Status Page and check that all pages in your application use these controls correctly.

    CSRF token is lazy loaded (experimental)

    The CSRF token can be loaded after the page is displayed.

    • πŸ‘ When the config option CsrfTokenLazyLoading is enabled, CSRF token is not rendered by default and will be requested before the first postback. This removes one source of non-determinism and may allow easier caching of entire DotVVM pages.
    • In any case, when the CSRF token or Session ID is invalid (for any reason), the server returns that as a JSON error message, the client automatically asks for a new token and retries the postback.

    To enable this feature, you must enable it in DotvvmConfiguration.ExperimentalFeatures.LazyCsrfToken:

    config.ExperimentalFeatures.LazyCsrfToken.EnableForRoutes("AdminPage", "AnotherPage")
    // or 

    πŸ‘ Allowed strange chars in attribute names (#727)

    It should be now OK to use square [] and round () brackets in attribute names, for example <span [text]="..." />. It may help when working with some client-side templating.

    πŸ‘Œ Improved performance of ValidationSummary (#734)

    We have redesigned a bit how the client-side validation works. The errors are not stored in a knockout observable anymore, changes in validation errors can be observed using the validationErrorsChanged event. If you have been using validationErrors directly, you'll have to adjust it's usage as it's not ko.observable anymore.

    Debugging and diagnostics improvements

    • Error page now has Binding tab which displays information about the binding that caused the exception (if the exception is related to some binding).
    • Error page crashed when some object could not be serialized.
    • #700 - In Debug mode, resources in the HTML are preceded by a comment that says the name, type and location type of the resource.
    • #728 - Resource with primary location being local cannot have have fallbacks.
    • πŸ‘Œ Improved error handling in some edge cases (6ec553e, 6d9543b).

    πŸ›  Other fixes

    • πŸ›  #701 - Fixed missing condition on file age in DeleteOldFiles (community contribution - thanks to @ppech).
    • #714 - Circular dependencies in resources are now detected
    • #740 - The promise returned by a static command is now rejected, when error occurs.
    • #721 - We now culture specific globalize.js resource in case you use ToString in a binding.
    • πŸ›  #732 - Fixed SetValue in nested markup control.
    • #725 - LinkButton does not use href="#".
    • πŸ›  #698 - Fixed server-rendered Repeater (and friend controls) when the DataContext is swapped entirely.
    • #731 - Resolved FormatException that occurred under strange circumstances.
    • πŸ’… #738 - Removed suppression of errors in style attribute unless value binding is rendered.
    • #742 - GetValue does not end up in an infinite cycle when custom binding is used.
    • πŸ’… #743 - HandleAsImmutableObjectInDotvvmProperty attribute added to indicate shared objects for server-side styles.
    • Validation.Enabled property was restricted to not allow value bindings.
  • v2.3.3

    November 04, 2019
  • v2.3.2

    November 02, 2019
  • v2.3.0

    June 21, 2019

    πŸ†• New Features

    • The context.ReturnFile method can now specify the Content-Disposition header. Until now, the header was always attachment.
    • Added context.LocalRedirect method which checks whether the specified URL is local. We strongly recommend using this method on all places where the user can inject his own URL to redirect - e.g. Account/Login?returnUrl=something
    • πŸ‘€ GridViewDataSet methods that apply sorting and paging operations on IQueryable were made public to allow writing the LoadFromQueryableAsync extension method. See #688.
    • βž• Added infrastructure for rendering script[type=html] templates. This will be useful for control developers using the Knockout template binding, especially DotVVM Business Pack.

    πŸ›  Fixes

    • πŸ›  Fixed error in IncludedInPage property when the resource binding was used.
    • ⚑️ Validation errors collection was not cleared when some parts of the viewmodel were set to null or reinitialized with new objectS. The validator binding handler update method was not used at all.
    • 🚚 Validator.InvalidCssClass functionality didn't work properly for multiple CSS classes and didn't remove all classes in some situations.
    • πŸ›  Fixed XSS vulnerability in registration of DotVVM polyfill resources.

    πŸ’₯ Breaking changes

    • CheckBox was rendering different HTML structure for the case when the text was empty. This structure did not include the label element, that is in most cases used as a base element for restyling of the checkbox design. Now, the label element is rendered in both cases.
  • v2.2.0

    April 06, 2019
  • v2.2.0.2

    April 13, 2019

    TL;DR; There are some new minor features. The most important point is Validation - EnforceClientFormat , which may break some existing code if it is using DateTime or nullable numberic type in view model.

    πŸ†• New features

    Binding Cache

    We have added caching interface IDotvvmCacheAdapter that provides access to built-in caching mechanism on Asp.Net Core or OWIN that reflect memory usage on your server.

    ValueBindingExpression.CreateThisBinding is now cached, so it's invocation should be quite cheap.

    When you want to create binding at runtime you can now use a helper method DotvvmBindingCacheHelper.CreateCachedBinding that makes sure that the binding is not recreated every time. Creation of bindings is usually time-consuming, so it should not be done on every request. (more info in PRs #672 and #664)

    By the way, we have also (hopefully) improved the error messages when something fails with binding. When an error page is displayed for a binding-related exception, there is a new tab Binding that shows some information about the binding (data context, type, ...). Let us know what you think about that and what could be improved.


    • ValidationErrorFactory.CreateValidationResult<T>(ValidationContext validationContext, ...)
      Overload that does not require explicit DotvvmConfiguration

    Session cookies are SameSite

    This was sometimes the case before. It means that postbacks won't work in third-party iframes (so your application should be safe from clickjacking).

    πŸ›  Fixes

    Validation - EnforceClientFormat

    πŸ’₯ This part is a fix and unfortunately a breaking change at the same time. In older versions, DotVVM did not validate that DateTime and numeric fields were valid on the client-side and sent null to the server in that case. It could be enabled by EnforceClientFormatAttribute, but nobody really did. It is now by default enabled on nullable numeric types, DateTime, and DateTime?, so it enables validation in cases where it was disabled previously. While this has a potential to "fix" existing code as not validating the input is likely a bug, it may also break some code that relied on that behavior. Please make sure that all your views using nullable DateTime and numerics work as expected. (more info in PR #666)
    🚚 For example, suppose you had a dot:TextBox bound to a property of type int?. The problem is that when you paste value like "asd", it will write a null value into the property because "asd" is not a valid numeric value. The solution for this problem was applying EnforceClientFormatAttribute to the property in your view model. Now, you don't have to do that anymore. If you use that attribute somewhere, you can safely remove it.

    Repeater control initialization

    We have change a bit how the Repeater initialization works. Controls with templates have to initialize the control tree before it is used by command invocation and HTML rendering and when this initialization is dependent on data from view model, it has to be done twice on postbacks - once before command invocation and then before rendering since the command may have changed the data. In older version Repeater have not done that in all cases, because it's quite time-consuming. Unfortunately, in some cases, it broke some code, so we are now re-initializing it two times, but only in case the data is actually changed. (more info in #653)

    Unique id generation for nested trees

    ⚑️ If you were creating controls at runtime, you may know that before adding more child controls into the newly create control has to be added to the control tree. The reason was, that the mechanism that generates unique ID (for control command and Postback.Update) did not work correctly when entire subtree was added at once. From this version, this should work correctly, so you can initialize entire subtrees at once. (more info in #668)

    It should now get precedence over the Events.Click handler. (more info in #630)


    _ Fixed in DotVVM _

    πŸ‘» When you installed Microsoft.Extensions.DependencyInjection 2.1.0 or higher in your application and used DotvvmAuthenticationHelper.ApplyRedirectResponse, this method was throwing an exception with a message that ServiceProvider had been disposed.

    netstandard assembly loading on .NET Framework 4.7.1+

    _ Fixed in DotVVM _
    DotVVM View compilation on .NET471+ was not able to load netstandard assembly.