DotVVM v2.4.0-preview01 Release Notes

Release Date: 2019-09-18 // over 2 years ago
  • ๐Ÿ‘Œ 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 
    config.ExperimentalFeatures.LazyCsrfToken.EnableForAllRoutes()
    

    ๐Ÿ‘ 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.