Skip to content

Releases: riganti/dotvvm

DotVVM 2.0.0

12 Aug 17:31
Compare
Choose a tag to compare

Main new features

  • REST API Bindings - DotVVM allows interacting with REST APIs directly from the DOTHTML views
  • Static Command Services - is a feature which allows injecting of a C# class in the page using @service directive and calling its methods using Static Command Binding.
  • PostBack Concurrency Modes
  • _collection Context Variable
  • New Binding System - mostly internal change but really huge.
  • Postback Handlers infrastructure rewritten

Upgrading from DotVVM 1.0 to DotVVM 2.0

See migration guidelines: https://www.dotvvm.com/docs/tutorials/how-to-start-upgrade-to-2-0/2.0

To review all changes, please see preview releases of DotVVM 2.0.

DotVVM 2.0.0-preview02-final

15 Mar 00:31
Compare
Choose a tag to compare
Pre-release

Breaking changes

DotVVM Registration

Signature of registration methods was changed. The reason is to be able safely execute registration of dotvvm services in compiler.
We introduced new interface called IDotvvmServiceConfigurator. This interface includes method void ConfigureServices(IDotvvmServiceCollection services). This method should includes all registrations of services needed for runtime of dotvvm. This part of code is called from compiler really often.

Warning: Avoid to init Entity Framework, calling API, sending emails and similar actions. Method void ConfigureServices(IDotvvmServiceCollection services) is meant only for registration of DotVVM

OWIN

The parameter IDotvvmOptions options was removed from signature of app.UseDotVVM() method. This functionality was moved to IDotvvmServiceConfigurator. You can simply implement IDotvvmServiceConfigurator interface on your DotvvmStartup.cs or you can create another class. If your DotvvmStartup implements this interface then a generic parameter TDotvvmStartup from app.UseDotVVM<TDotvvmStartup>() internally casts the DotvvmStartup as IDotvvmServiceConfigurator.

We introduced new overload app.UseDotVVM<TDotvvmStartup, TDotvvmServiceConfigurator>() in case you want to implement IDotvvmServiceConfigurator to separated class.

AspNet Core

The same change as for OWIN was made on function IServiceCollection AddDotVVM<TServiceConfigurator>.
The IDotvvmOptions options parameter was removed and replaced by generic type that expects implementation of IDotvvmServiceConfigurator.

DotvvmConfiguration

Debug property can be modified only in IDotvvmStartup and registration method app.UseDotVVM(). When you try to modify Debug property after initialization it throws exception.

Resources

Removed jQuery resource

In an effort to make DotVVM less depended we have removed jQuery resource. If you need it simply add jquery to you project and register in DotVVM configuration config.Resources.Register("jquery", new ScriptResource() { ... }.

Routes

Method config.RouteTable.Add() contained parameter type of Func<IDotvvmPresenter> . This signature of the parameter was change to Func<IServiceProvider, IDotvvmPresenter>. Now we provide an instance of IServiceProvider in factory method.

Some of Javascript API changes

  • dotvvm.postBackHandlers was renamed to dotvvm.postbackHandlers

DotVVM 2.0.0-beta01

23 Jan 11:52
Compare
Choose a tag to compare
DotVVM 2.0.0-beta01 Pre-release
Pre-release

Binding Properties

see Binding System Refactoring #341

  • Better Javascript translator
  • In the ViewModelSerializationMap it's possible to rename properties for client-side and JavascriptTranslator will translate it correctly, use Bind(Name = "MyName") attribute
  • Null checks in binding were previously done by try ... catch, which also caught exception inside called functions. Now it is done by real checks, so inner exceptions are propagated correctly
  • Binding can be transferred from one control to another in different data context and they will still evaluate and translate to JS correctly
    • This means that you can use inherited properties to transfer dependencies into your markup control even though they are deeply nested
    • You can even use MarkupControls recursively, just make sure they are server-rendered
  • Super cool extensibility
    • Extension parameters like _collection, _index and _api are just a tip of the icebergs ;)
  • Bindings have ResultType property accessible at runtime
  • Controls have DataContextType property accessible at runtime
  • Command Binding IDs are "more" unique and less readable

Function Arguments in Bindings

All bindings now have an implicit conversion to a delegate - essentialy, when the expected type is a delegate, the binding is wrapped in lambda. In Javascript it's represented as a function. And when the delegate contains any parameters, these get registered as additional symbols to the parser. For example to set (a) => a + 1 into a property of type Func<int, int> you can use {value: arg + 1}

To use the parameters with staticCommand you can set the commandArgs symbolic parameter (the same way you'd do with command binding)

REST API

DotVVM allows interacting with REST APIs directly from the DOTHTML views. You can fill GridView, Repeater and other controls with data from the REST API, and use Button or other controls to call REST API methods as a response to user action. It is also possible to refresh data that have already been loaded (in the GridView for example) based on a change of a particular viewmodel property, or explicitly.
See: https://www.dotvvm.com/docs/tutorials/basics-rest-api-bindings/2.0

Model state helpers

You can just viewModel.AddModelError(v => v.MyObject.PartOfTheForm.Property3, "It's invalid") instead of creating JS evaluatable string path

Controls improvements

  • ComboBox.ItemValueBinding and ItemTextBinding - use them instead of ValueMember and DisplayMember
  • TextBox.ValueType is obsolete, it's infered from result type of Text property

string.Format in value bindings

string.Format method is correctly translated to Javascript. You can also use [primitive type].ToString("Format") method - this one is also two-way, so it's possible to use it instead of FormatString property on TextBox.

Route Groups

see #363

you can register routes in groups with specified path and id prefixed to prevent repetitive literals and help with visual code orientation:

routes.AddGroup(name: "Admin", prefix: "admin", virtualPath: "Views/Administration", content: adminRoutes =>
{
    // adminRoutes is of type RouteTable
    adminRoutes.Add("Users", "users", "Users.dothtml"); // name = Admin_Users, path = "admin/users", virtualPath = "Views/Administration/Users.dothtml"
    adminRoutes.Add("Articles", "articles", "Articles.dothtml");
});

Dependency Injection into controls

It works in two modes:

  • Simple/intuitive/automatic/hipster mode - when the control does not have a parameterless constructor, it is initialized from the default IServiceProvider. It is used mainly for infrastructure controls that need to get some dotvvm service, for non-control DotvvmBindableObjects that need or on Asp.NET Core projects that use the default DependencyInjection properly.
  • Explicit/enterprise mode - when the control is marked by [RequireDependencyInjection] it is created using resolver registered in the default IServiceProvider. You can use it if you want services from your separate container or need some weird injection features, like property injection

Dependency Injection into dothtml views

You can require a service using @service directive. It is mainly useful for Asp.Net Core ILocalizer interface and for calling static commands. The service usage can't be translated to Javascript, so usage in value binding will throw an exception.

@service myService = IMyService<string>

{{resource: myService.SomeProperty}}

{{command: myService.DoSomething()}}

Markup controls packed into dlls

Markup file loaded supports embedded://...assembly name/...name of the resource syntax for referencing embedded resources from view or markup control registration. It should allow you to pack dotcontrol files into the dll and distrube them in a library. The files are referenced as the original source code and have to be compiled in the target project, so you can apply compile-time styles to them.

IncludeInPage property

Just a wrapper for knockout if binding handler.

FormControls.Enabled property

proposed in #296, PR #433

Added a FormControls.Enabled attached property which disables controls inside that are not explicitly enabled.
Controls affected

  • in DotVVM - Button (ButtonBase), CheckBox (CheckableControlBase), ComboBox (SelectorBase), DataPager, LinkButton (ButtonBase), ListBox (SelectorBase), RadioButton (CheckableControlBase), TextBox
  • in Bootstrap - Button, CheckBox, DataPager, RadioButton, TextBoxGroup
  • in Business pack - Button, Calendar, CheckBox, CheckBoxList, ColorPicker, ComboBox, DataPager, DateTimePicker, DateTimeRangerPicker, DropDownList, MultiSelect, NumericUpDown, RadioButton, RadioButtonList, RangeCalendar, RangeSlider, Rating, Slider, TextBox

Example

<div FormControls.Enabled="{value: false}">
    <dot:Button Text="I am disabled" />
    <dot:Button Text="I am enabled" Enabled="{value: true}" />
</div>

dot:BodyResourceLinks and dot:HeadResourceLinks

When you use one of these controls in page, the resources will be render in location that is defined by the control. Only the first control on the page is activated to prevent accidential multiple times included scripts.

LocalizablePresenter

It's a utility for easy localization based on query string or route parameters. It just sets the Threads
current culture.

// based on query string parameter lang, `myPage?lang=cs-CZ` will be in czech culture
config.RouteTable.Add("myRoute", "myPage", "myPage.dothtml", presenterFactory: LocalizablePresenter.BasedOnQuery("lang"));

// based on parameter lang, `cs-CZ/myPage` will be in czech culture
config.RouteTable.Add("myRoute", "{lang}/myPage", "myPage.dothtml", presenterFactory: LocalizablePresenter.BasedOnParameter("lang"));

By default, it redirects to a default culture when a invalid code is specified, you can disable that using redirectWhenNotFound parameter.

see #513

Custom constuctor for serializer

On a IViewModelSerializationMapper, you can set your own method to create a new instance of the viewmodel.

mapper.Map(m => {
	// create from Asp.Net DI
	m.AllowDependencyInjection();
	// custom constructor
	m.SetConstructor(serviceProvider => SomehowCreateViewModel(serviceProvider))l
});

Ben.Demystify for the error page

By default, the error page uses Ben.Demystify library to show nicer stack traces.

Implemented CSS style bindable

Added Style-* property group that generates the style knockout binding. I'm not sure what type should I use for the property group, currently there is object.

Usage example:

<div Style-color="{value: Color}" Style-display="{value: Condition ? 'none' : 'inline-block'}"/>
<div style="background-color: green;" Style-width="{value: Width + 'px'}"/>

see #572

DotVVM 1.1.8

25 Dec 16:58
Compare
Choose a tag to compare

Fixes

  • Validation errors are cleared before SPA navigation starts
  • ViewModel and dependencies are disposed in finally block.
  • Fixed route url parser with optional parameter at start of url

DotVVM 1.1.7

02 Nov 22:08
Compare
Choose a tag to compare
  • Fixes static command deserialization
  • Fixes GridViewDataSet deadlocks at OnLoadingDataAsync event. #481
  • Fixes DotvvmRoute: optional parameter is ignored when null is assigned #483

DotVVM 1.1.6

13 Sep 10:54
Compare
Choose a tag to compare

Asp.Net Core 2.0

Added support for AspNetCore 2.0 but dropped support for 1.0, because it's not compatible. OWIN hosting is basically untouched. For more info, have a look at dotvvm blog

DotVVM 1.1.5

13 Sep 10:21
Compare
Choose a tag to compare

Parameter binding

With parameter binding, you can simply get data from query string or route parameter. You just need to declare a property and mark it with the FromRoute or FromQuery attribute:

[FromRoute("id")]
public int? CustomerId { get; private set; }

DotVVM will look in the route parameter collection and if the parameter is there, it loads the property with the value and does all the conversions. It also automatically binds the property with Direction.ServerToClientFirstRequest.

Request tracing

Added IRequestTracer interface, that is called multiple times per request when a notable event happens (like on Init, Load, ...). We have prepared implementation for Azure Application Insights and for StackExchange's MiniProfiler - more info at dotvvm blog

Few more minor features

  • GridViewDataSet supports async
  • Support for scoped services on OWIN
  • CheckBox.Checked supports null
  • Commands render a

And bugfixes

DotVVM 1.1 RC

29 Dec 08:32
Compare
Choose a tag to compare
DotVVM 1.1 RC Pre-release
Pre-release

.NET Core support

DotVVM.Framework was splitted into several projects.

  • DotVVM.Framework now contains almost everything except Hosting layer, so it is portable between Owin on old .NET, AspNetCore on old .NET and AspNetCore on .NET Core
  • DotVVM.Framework.Hosting.OWIN contains hosting layer for OWIN, works only on old .NET Framework
  • DotVVM.Framework.Hosting.AspNetCore contains hosting layer for AspNetCore.

Since the common core of Dotvvm framework is not dependent on hosting technology, we had to implement unifying interfaces above IOwinContext/HttpContext, IOwinRequest/HttpRequest and so on. These interfaces are implemented in each hosting layer package and should allow you to write components without referencing concrete hosting technology. We have tested it on our bootstrap wrappers and it worked without any source code change.
If you'd like to access raw IHttpContext/HttpRequest you can use GetOwinContext() or GetAspNetCoreContext() on IDotvvmRequestContext to get to them.

ServiceLocator is now considered deprecated, you should use the new AspNet Dependency Injection. However the GetService<T>() still works as a wrapper over IServiceProvider and in OWIN hosting you can also register services. On AspNetCore hosting you should call AddDotVVM() in Startup.ConfigureSorvices method, see the samples how to do that. On OWIN the UseDotVVM() method takes Action<IDotvvmBuilder> where you can register them.

Route constraints

#161
implemented all route constraints that are available in WebAPI as specified at http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#constraints. You can add your own in DotvvmConfiguration.

Bool properties without value

#191
You don't have to type <dot:Button IsSubmitButton="true" />, <dot:Button IsSubmitButton /> is enough, the value true is assigned implicitly.

@import directive

It works like using in C#, you can import namespace, namespace as alias and type as alias.

@import MyApp.Resources <-- namespace is imported
@import RS=MyApp.Resources <-- namespace is aliased as RS
@import Resources=MyApp.Resources.DetailPageResources <-- type is aliased as Resources

You can also import these globally in DotvvmConfiguration.Markup.ImportedNamespaces.

All directives also support generic types with C# syntax:

@viewModel System.Collection.Generic.List<MyApp.ViewModels.SomeViewModel>

@resourceNamespace and @resourceType directives are now deprecated and will not work any more.

Set which wrapper tag can be rendered by control in markup

@wrapperTag span directive sets the tag name (to span in this case) and @noWrapperTag directive suppresses rendering of the wrapper tag.

Property groups

You can map all attribute stating with specified prefix to an dictionary using property group. The Class-... and Param-... attributes works this way. you can have a look how we use the in the HtmlGenericControl and RouteLink controls.

Action Filters splited into interface

You can still use the ActionFilterAttribute, the way how it works inside was changed, so you create filter only for ViewModel/Command/Request.
See #261

Mapping serialization options from code

So you don't have to mark the classes with attributes. Useful when you don't want to mess up your model or you don't have access to that code.
See #262

[Flags] enums in dothtml

You can set these properties in markup. The enum member names in the property value are separated by , or |.

Breaking Changes

  • methods on ActionFilterAttribute / ExceptionFilterAttribute are async
  • property RoleView.HideNonAuthenticatedUsers renamed to HideForAnonymousUsers

New Controls

  • ClaimView - Like RoleView but for claims, renders content only if claims match the specified conditions.
  • EnvironmentView - The one for Environment

Bugfixes, bugfixes, bugfixes

And lot of new bugs ;)

Kind of internal stuff