Code Monkey home page Code Monkey logo

dotvvm's Introduction

Component-based MVVM framework for ASP.NET

License Gitter GitHub Actions NuGet

DotVVM lets you build interactive web UIs with just C# and HTML using the MVVM approach.

It simplifies building of line of business web apps and ships with many built-in controls like GridView, FileUpload, Validator and more.

How does DotVVM work?

The Views in DotVVM use HTML syntax with controls and data-bindings.

The ViewModels are plain C# objects with properties and methods.

You can access the ViewModel properties using {value: Name} and call ViewModel methods using {command: Submit()}.

<div class="form-control">
    <dot:TextBox Text="{value: Name}" />
</div>
<div class="form-control">
    <dot:TextBox Text="{value: Email}" />
</div>
<div class="button-bar">
    <dot:Button Text="Submit" Click="{command: Submit()}" />
</div>
public class ContactFormViewModel
{
    [Required]
    public string Name { get; set; }

    [EmailAddress]
    public string Email { get; set; }

    public void Submit()
    {
        // ...
    }
}

DotVVM comes with many features including:

Getting started with DotVVM

Learn the basic principles of DotVVM in our DotVVM Academy tutorials.

The easiest way to start with DotVVM is to download DotVVM for Visual Studio and do File > New > Project.

You can also install DotVVM in existing ASP.NET projects and use it side-by-side with other ASP.NET frameworks (Web Forms, MVC, Razor Pages).

There is also dotnet new template for those who prefer command-line approach. You can get our free extension for Visual Studio Code.

Current status

DotVVM is used in production by hundreds of developers and companies. The first stable release was in June 2016.

ASP.NET Core OWIN
Current stable version DotVVM.AspNetCore 4.2.* DotVVM.Owin 4.2.*
Minimum runtime version .NET 6.0 .NET 4.7.2
Minimum ASP.NET version ASP.NET Core 6.0 OWIN 4.2.2

You can find the plans for next releases in the roadmap.

Commercial components & tools

DotVVM framework is open source and will always be free to use. It's developed under Apache license.

There are also free extensions for Visual Studio and VS Code available. They are not open source, but they will also be free to use.

You can get more productive with DotVVM and support development of the framework by purchasing commercial components and tools developed by the creators of the framework:

  • Bootstrap for DotVVM brings more than fifty Bootstrap 3 and 4 controls that are easy to use and integrate well with DotVVM validation and data-bindings.
  • DotVVM Business Pack contains more than 30 enterprise-ready controls for large line of business web apps.
  • DotVVM Pro for Visual Studio offers more features than the free extensions - IntelliSense for data-binding expressions, real-time error checking and much more.

Get involved

We'll be glad to accept any contribution. It doesn't need to be a pull-request - you can help us by spreading the word about the project in a blog or a user group, fix a typo in a documentation or send us your feedback and thoughts.

You can find more info in Contribution Guidelines. We kindly ask you to respect the Code of Conduct.

Feedback

Feedback is crucial to make DotVVM better. You can reach us at any time on our Gitter Chat.

.NET Foundation

This project is supported by the .NET Foundation.

Further reading

dotvvm's People

Contributors

acizmarik avatar adamjez avatar adamkopriva22 avatar cafour avatar darilek avatar dependabot[bot] avatar djanosik avatar duzij avatar exyi avatar jaroslavholcman avatar jechtom avatar josefpihrt avatar jozefpastucha avatar macakm avatar martindybal avatar michaltichy avatar mirecad avatar mrnustik avatar mylan719 avatar padresvk avatar parmap avatar pavelpolasek avatar quigamdev avatar rigantiteamcity avatar ropack avatar rumbeer avatar sejsel avatar strihtrs avatar tomasherceg avatar tomasjurasek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dotvvm's Issues

When the user presses Back button in browser, the viewmodel breaks

  1. The user fills some form controls (e.g. textbox).
  2. The user navigates to another page.
  3. The user presses Back button in the browser.
  4. The browser fills the form controls with the values automatically but in the viewmodel there is null on each property.

It happens in Google Chrome and maybe in other browsers.

Event Validation - CommandResolver security

I have found critical security bug in CommandResolver.
Open 'Sample 6 - ViewModel property encryption and protection' and run this in developer console

redwood.postBack('root', document, [], 'set_ReadOnlyData(SecretData)', '')

and see what is in protected data in viewmodel. This invocation has modified readonly data and read secret data.
I think we should read all binding before sending to client and then accept only these registered binding expressions. I hope this will help. We can also cache parsed binding expression to improve performance.

Implement built-in controls

GridView

  • basic features are already implemented
  • inline editing
  • more cell customizations
  • support for column resizing (and the customizations are persisted in the local storage)

ListView

  • basically Repeater with inline editing, empty data template and other features

CollectionEditor

  • a control where the user can enter one or more values
  • each row is an instance of template

CheckBoxList, RadioButtonList

Localization and resource binding

Implement a new type of a binding {resource: ResourceType.ResourceKey } that will load the value from the resource file and create function for changing the culture from viewmodel code.

More intelligent item templates

  1. Content Page template should allow user to select the viewmodel and master page in some window
  2. ViewModel should allow to create a new view or attach to an existing one
  3. Template for user control should be added

Visual Studio extension

Update the tokenizer to handle unfinished elements and bindings.
Implement the IntelliSense for directives, attributes and binding types.

Replace knockout.mapper with custom serialization

The custom serialization must reflect the Bind() attribute in the C# viewmodel.

The following binding options should be implemented:

  1. TwoWay
  2. OneWay (server to client only)
  3. OneWayToSource (client to server only)
  4. OneTime (server to client but only on initial page load)

Get rid of the ResourceLinks control in markup

Scripts and styles should be embedded in the page by the framework, there is no need to explicitly use them from the markup.
Also the RedwoodView and ResourceLinks controls should be placed in different namespace so they cannot be used from the markup.

Security bug in deserialization of protected values

When deserializing there is no control if object in array I really belongs to this property.
In the 'Sample 6 - ViewModel property encryption and protection' first remove explicit proteced data validation (method ValidateSecretDataDecryptedSuccessfully). Then you can run this command in developer console to display SecretData property.

redwood.viewModels.root.ReadOnlyData$encrypted(redwood.viewModels.root.SecretData$encrypted())

ViewModel protection in child viewmodels

Now property of viewmodel property can be protected, but it is pretty insecure, because class is included optionally (can be replaced by null or removed from array) and its encrypted value can overflow to some read-only property.
I have made little example in protection-vunerability-demo branch. Just run following in developer console

redwood.viewModels.root.ProtectedTasks.remove(redwood.viewModels.root.ProtectedTasks()[0])

and do a postback.
We can enable protection only in main viewmodel, but I think it's not needed.
Maybe it can be solved by appending to EncryptedValues number of new elements added while serializing the property. On deserialization check if it fits.
In my sample it will look like

[
  "secret task data",
  "secret task data",
  "secret task data",
  3, // number of encrypted values in ProtectedTasks property
  "This property can be read on the client but when you modify it, the server won't accept the request.",
  "This is encrypted and cannot be displayed on the client."
]

Do you think it will be safe?

Support user controls with view defined in .rwhtml file

UserControl can have the view defined in .rwhtml.
The controls must support Init, Load, PreRender, InitComplete, LoadComplete and PreRenderComplete methods that must be called during the page lifecycle.
A new binding of type {controlProperty: expression} should be supported in the future.
A new binding of type {controlCommand: function} should be supported in the future.

Rwhtml syntax: Binding should use only one curly brace

Currently rwhtml is using single curly brace in attribute binding and double in HTML element content, like: <p class="{value: Result}">{{value: Result}}<p>.
We should use single brace everywhere. For example:
<p class="{value: Result}">{value: Result}<p>.

You should be able to escape opening binding with two opening curly braces.

Update wiki

Add a link to the VSIX extension
Update first pages where the files are created manually - the extension now does this
Add a page about action filters
Add a page about IoC/DI and testability of viewmodel

Authorization and action filters

Implement the action filtering mechanism similar to ASP.NET Web API and MVC. The filters can be applied:

  • on the method level
  • on the viewmodel level
  • globally

Then implement the Authorize attribute (which is an action filter) and a RedirectToLoginPageAttribute that redirects to a specified URL when an UnauthorizedAccessException occurs.

ArgumentException when opening redwood.json

1527 2015/03/04 14:13:42.800 Error Editor or Editor Extension System.ArgumentException: The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG)) at EnvDTE.ProjectItems.Item(Object index) at Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions.RwHtml.Base.CompletionHelper.<GetSelfAndChildProjectItems>d__3.MoveNext() in D:\Riganti\External\Redwood\src\Redwood.VS2015Extension\RwHtmlEditorExtensions\Completions\RwHtml\Base\CompletionHelper.cs:line 45 at System.Linq.Enumerable.<SelectManyIterator>d__8`2.MoveNext() at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions.RwHtml.MasterPageDirectiveCompletionProvider.GetItemsCore(RwHtmlCompletionContext context, String directiveName) in D:\Riganti\External\Redwood\src\Redwood.VS2015Extension\RwHtmlEditorExtensions\Completions\RwHtml\MasterPageDirectiveCompletionProvider.cs:line 20 at Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions.RwHtml.Base.DirectiveValueHtmlCompletionProviderBase.GetItems(RwHtmlCompletionContext context) in D:\Riganti\External\Redwood\src\Redwood.VS2015Extension\RwHtmlEditorExtensions\Completions\RwHtml\Base\DirectiveValueHtmlCompletionProviderBase.cs:line 21 at Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions.RwHtmlCompletionSource.<>c__DisplayClass8_1.<AugmentCompletionSession>b__4(IRwHtmlCompletionProvider p) in D:\Riganti\External\Redwood\src\Redwood.VS2015Extension\RwHtmlEditorExtensions\Completions\RwHtmlCompletionSource.cs:line 72 at System.Linq.Enumerable.<SelectManyIterator>d__8`2.MoveNext() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions.RwHtmlCompletionSource.AugmentCompletionSession(ICompletionSession session, IList`1 completionSets) in D:\Riganti\External\Redwood\src\Redwood.VS2015Extension\RwHtmlEditorExtensions\Completions\RwHtmlCompletionSource.cs:line 101 at Microsoft.VisualStudio.Language.Intellisense.Implementation.CompletionSession.Start() at Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions.RwHtmlCompletionCommandHandler.TriggerCompletion() in D:\Riganti\External\Redwood\src\Redwood.VS2015Extension\RwHtmlEditorExtensions\Completions\RwHtmlCompletionCommandHandler.cs:line 121 at Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions.RwHtmlCompletionCommandHandler.Exec(Guid& pguidCmdGroup, UInt32 nCmdID, UInt32 nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) in D:\Riganti\External\Redwood\src\Redwood.VS2015Extension\RwHtmlEditorExtensions\Completions\RwHtmlCompletionCommandHandler.cs:line 84 at Microsoft.VisualStudio.Editor.Implementation.CommandChainNode.InnerExec(Guid& pguidCmdGroup, UInt32 nCmdID, UInt32 nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) at Microsoft.VisualStudio.Editor.Implementation.SimpleTextViewWindow.Exec(Guid& pguidCmdGroup, UInt32 nCmdID, UInt32 nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) at Microsoft.VisualStudio.Editor.Implementation.VsKeyboardFilter.SendCommand(Guid cmdGroup, UInt32 cmdID, Object inParam) at Microsoft.VisualStudio.Editor.Implementation.VsKeyboardFilter.TextInput(TextCompositionEventArgs args) at Microsoft.VisualStudio.Text.Editor.Implementation.KeyProcessorDispatcher.<>c__DisplayClass0.<DispatchTextInputEvents>b__1(KeyProcessor p, TextCompositionEventArgs args) at Microsoft.VisualStudio.Text.Editor.Implementation.KeyProcessorDispatcher.<>c__DisplayClass26`1.<Dispatch>b__27() at Microsoft.VisualStudio.Text.Utilities.GuardedOperations.CallExtensionPoint(Object errorSource, Action call)

PostBack.Update and Render.Mode properties (Server-side rendering)

Create attached property PostBack.Update="true" which will re-render the control on postback and send the HTML to the client. The client replaces the control content with new HTML that came from the server.
Also implement a Render.Mode="Server/Client" that will turn the client rendering on or off. In Server mode, the bindings are evaluated on the server and pure HTML without knockout stuff is generated.

Error in compiled view cache

When the DefaultViewCompilers compile a complex page with master page and templates for the first time, it works. When the compiled output is cached, the next time the page injects incorrect template.

Enhance property matching in markup

Currently the property in markup is mapped on RedwoodProperties. When a redwood property is not found, we should try to map it to the actual property on the class.

Lock page during postback

Currently the framework allows to create several concurrent postbacks. E.g. when the user clicks the button twice, two postbacks are sent to the server and if the responses come in different order, the viewmodel can break.

Implement SpaContentPlaceHolder and RouteLink controls

SpaContentPlaceHolder can be used only once in a page and the content is loaded using AJAX.

RouteLink will allow to create a hyperlink to a route.
Attributes beginning with Param- will be passed in the route:

<rw:RouteLink RouteName="NameOfRoute" Param-Id="{value: MenuItemId}" />

The prefix is necessary because we might want to specify HTML attributes that will be applied to the link. Also we need a function that builds the route URL.

Support for decorator controls

Many controls and HTML elements do not have Click handler and it is not wise to add it to all of them. Instead a concept of Decorator should be implemented. Each BindableControl will have an option to declare whether it can be decorated or not, and when it can, one or more decorators can be applied to it. They will be allowed to wrap the control in a HTML element or add an attribute to it.
It should be easy to apply a decorator, e.g. via attached property.

Example (we consider a decorator named EventsDecorator):

<tr Event.Click="{command: Test()}">...</tr>

Rwhtml syntax: remove colon from directives

@viewmodel: Redwood.Samples.BasicSamples.ViewModels.Sample2ViewModel, Redwood.Samples.BasicSamples

Should be:

@viewmodel Redwood.Samples.BasicSamples.ViewModels.Sample2ViewModel, Redwood.Samples.BasicSamples

Please update parser and samples.

Validation

We need to design some extensible validation.
There are many decisions to be made:

  • will we use validation groups, or we are always going to validate whole viewmodel or its subtree
  • what JS library will we use
  • how that will be connected to the model validation, we'll also need the ModelState in the viewmodel

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.