by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Anatoli & My Rabbits
    @AnatoliDol_twitter
    Question: can you update DotVVM to the FrameWork 4.6? - 4.8. My project don't work in framework 4.52
    Daniel Sagazio
    @SagazioDan
    Hi, i must download a file in dotvvm, but i can't insert a spinner into the page. I tryed to set a postback event handler, but Contex.ReturnFile don't generate a postback. Any tips about it?
    Tomáš Herceg
    @tomasherceg
    @AnatoliDol_twitter Hello,
    1) In DotVVM, the Repeater is much more light-weight - it cannot do grouping, but it is quite easy to make using nested Repeaters (the outer Repeater will list all the groups and the inner one will list items in the group). In the viewmodel, you need to represent as a "collection of collections" - it is not possible to "group-by" in data-binding syntax.
    2) In comparison to Web Forms, DotVVM doesn't render any built-in CSS classes and renders very simple and straight-forward HTML, so it shouldn't be difficult to use plain CSS to style it. The Repeater has the WrapperTagName property that make it render ul instead of the default div.
    3) DotVVM works with .NET 4.5.1 and higher - there should be no problem using it with .NET 4.8. Are you getting some specific errors?
    Tomáš Herceg
    @tomasherceg
    @SagazioDan This won't be so easy. Context.ReturnFile is basically a redirect, so we need to display the animation in afterPostback and hide it when the file download starts. The problem is that I haven't found any browser event that you could hook on to recognize when the download starts. I found only some crazy solutions that need a cookie to be appended with the downloaded file, and then you can have some timer in the page that will detect when the cookie changes.
    There is some API browser.downloads that could be used for that, but it doesn't like it is supported in some browsers.
    Michal Tichý
    @MichalTichy

    @SagazioDan Hello, I think that I have exactly what you need allready implemented. It's kinda hacky but it should work in all browsers.
    Control

        public class FileDownloadButton : RouteLink
        {
            [MarkupOptions(AllowBinding = false)]
            public BootstrapTextColor SpinnerColor
            {
                get { return (BootstrapTextColor)GetValue(SpinnerColorProperty); }
                set { SetValue(SpinnerColorProperty, value); }
            }
    
            public static readonly DotvvmProperty SpinnerColorProperty
                = DotvvmProperty.Register<BootstrapTextColor, FileDownloadButton>(c => c.SpinnerColor, BootstrapTextColor.Light);
    
            protected override void OnInit(IDotvvmRequestContext context)
            {
                context.ResourceManager.AddRequiredResource(nameof(FileDownloadButton));
    
                var spinner = new Spinner() { Size = SpinnerSize.Small, Type = SpinnerColor };
                spinner.Attributes["class"] = "loadingIcon";
                Children.Add(spinner);
    
                base.OnInit(context);
            }
    
            protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
            {
                writer.AddAttribute("class", "button-loading");
                base.AddAttributesToRender(writer, context);
            }
        }

    Javascript (typescript) resource required by this control

    var setCookie = function (name, value, expiracy) {
        var exdate = new Date();
        exdate.setTime(exdate.getTime() + expiracy * 1000);
        var c_value = escape(value) + ((expiracy == null) ? "" : "; expires=" + exdate.toUTCString());
        document.cookie = name + "=" + c_value + '; path=/';
    };
    
    var getCookie = function (name) {
        var i, x, y, ARRcookies = document.cookie.split(";");
        for (i = 0; i < ARRcookies.length; i++) {
            x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
            y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
            x = x.replace(/^\s+|\s+$/g, "");
            if (x == name) {
                return y ? decodeURI(unescape(y.replace(/\+/g, ' '))) : y;
            }
        }
    };
    var downloadTimeout;
    var checkDownloadCookie = function (element) {
        let cookie = getCookie("Download");
        if (cookie == "true" || cookie == undefined) {
            element.removeClass("loading");
            $(".button-loading").removeAttr("disabled");
            setCookie("Download", "false", 1);
        } else if (cookie == "false") {
            downloadTimeout = setTimeout(() => {
                checkDownloadCookie(element);
            },
                1000);
        }
    };
    
    (window as any).dotvvm.events.init.subscribe(() => {
        $(".button-loading").click(event => {
    
            let element = $(event.target);
            if (element.attr("disabled")) {
                return;
            }
            element.addClass("loading");
            $(".button-loading").attr("disabled", "true");
            setCookie("Download", "false", 10);
            setTimeout(() => {
                    checkDownloadCookie(element);
                },
                1000);
        })
    });

    Resource and control registration in DotvvmStartup

                config.Markup.AddCodeControls("cc", typeof(FileDownloadButton));
    
                config.Resources.Register(nameof(FileDownloadButton), new ScriptResource(
                    new UrlResourceLocation(PATH TO JS)));
    It uses bootstrap spinner, but you can easily edit it to use something else
    Daniel Sagazio
    @SagazioDan
    Thank you very much!!
    Tomáš Herceg
    @tomasherceg
    The virtual meetup is today - it starts at 3 PM UTC (5 PM CEST).
    We'll be happy to talk to you and show you some cool demos: https://www.dotvvm.com/blog/70/Join-the-DotVVM-Team-on-a-Virtual-Meetup
    Jan Berger
    @kamm85
    Hello!
    Please is any way to use interface property as datacontext? :-)
    <dot:Panel DataContext="{value: _root.UniObjImpelemtedAsInterface}">
                                <dot:TextBox Text="{{value: NumberFromImplementationClassNotFoundInInterface}}" />
    </dot:Panel>
    Tomáš Herceg
    @tomasherceg
    I am afraid it is not possible - we have no way to cast in the data-binding expressions.
    Jan Berger
    @kamm85
    @tomasherceg I think this.. Thank you
    Tomáš Herceg
    @tomasherceg
    @kamm85 There is actually one hack that you could use - define your own static C# method that does the cast (accepts the interface and returns the casted value) and register a custom JS translator.
    https://github.com/riganti/dotvvm-samples-weeklyplanner/blob/master/src/WeeklyPlanner/DotvvmStartup.cs#L32
    The custom translator can just return the same value - something like return arguments[0].JsExpression();, or maybe it can verify if the type is correct (if it contains all properties you'll need to use).
    Stanislav Lukeš
    @exyi
    In general, this is not so easy, since DotVVM basically does not support polymorphism in view models. It will somehow work until you also try to deserialize the viewmodel on server (during a postback).
    mirecad
    @mirecad
    Hi, easter discount code is not working:)
    dima-chernin
    @dima-chernin
    Hi, is there a possibility to get the gridview control in view model using Context.View?
    Michal Tichý
    @MichalTichy
    @mirecad Hi, thank you for report, we willl fix it ASAP.
    @dima-chernin
    If I remember correctly there should be method that gets element by Id
    dima-chernin
    @dima-chernin
    @MichalTichy , well, i set an Id="grdTest" to a grid in view, and Context.View.FindControlByUniqueId("grdTest") gives me null
    dima-chernin
    @dima-chernin
    @MichalTichy , Context.View.GetAllDescendants().FirstOrDefault( => .ID == "grdTest") worked.
    Jenny Beard
    @christianmother27

    I have an issue I've been struggling with that hopefully someone can point me in the right direction with. My webforms app is v 4.6, and I have about 5 Dotvvm pages I've converted. We have to have RSA authentication on our servers. Without RSA, the Dotvvm pages work without error. With RSA I get errors, but my webforms page that I replaced don't get errors (which makes me think it's some kind of issue between the RSA single sign on communicating with RSA). I get 3 Dotvvm Server 500 javascript errors, and then what I suspect are errors just resulting from the fact that knockoutjs and dotvvm aren't loading properly. The javascript errors are:

    GET http://server/virdir/dotvvmResource/knockout/knockout net::ERR_ABORTED 500 (Internal Server Error) (index):244 GET http://server/virdirdotvvmResource/dotvvm--internal/dotvvm--internal net::ERR_ABORTED 500 (Internal Server Error) (index):246 GET http://server/virdir/dotvvmResource/dotvvm--debug/dotvvm--debug net::ERR_ABORTED 500 (Internal Server Error) (index):1745 GET http://server/virdir/dotvvmResource/globalize/globalize net::ERR_ABORTED 500 (Internal Server Error) (index):1747 GET http://server/virdir/dotvvmResource/globalize---en-US/globalize---en-US net::ERR_ABORTED 500 (Internal Server Error) (index):1551 GET http://server/virdir/dotvvmResource/knockout/knockout net::ERR_ABORTED 500 (Internal Server Error) (index):1555 GET http://server/virdir/dotvvmResource/dotvvm--internal/dotvvm--internal net::ERR_ABORTED 500 (Internal Server Error) (index):1557 Uncaught ReferenceError: DotVVM is not defined at (index):1557 (anonymous) @ (index):1557 (index):1559 GET http://server/virdir/dotvvmResource/dotvvm--debug/dotvvm--debug net::ERR_ABORTED 500 (Internal Server Error) (index):1562 Uncaught ReferenceError: ko is not defined at (index):1562 (anonymous) @ (index):1562 (index):1588 Uncaught ReferenceError: ko is not defined at (index):1588 (anonymous) @ (index):1588 (index):1614 Uncaught ReferenceError: ko is not defined at (index):1614 (anonymous) @ (index):1614 (index):1627 Uncaught ReferenceError: ko is not defined at (index):1627 (anonymous) @ (index):1627 (index):1638 Uncaught ReferenceError: ko is not defined at (index):1638 (anonymous) @ (index):1638 (index):1651 Uncaught ReferenceError: ko is not defined at (index):1651 (anonymous) @ (index):1651 (index):1664 Uncaught ReferenceError: ko is not defined at (index):1664 (anonymous) @ (index):1664 (index):1672 Uncaught ReferenceError: dotvvm is not defined at (index):1672 (anonymous) @ (index):1672 (index):1699 Uncaught ReferenceError: ko is not defined at (index):1699 (anonymous) @ (index):1699 (index):1745 GET http://server/virdir/dotvvmResource/globalize/globalize net::ERR_ABORTED 500 (Internal Server Error) (index):1747 GET http://server/virdir/dotvvmResource/globalize---en-US/globalize---en-US net::ERR_ABORTED 500 (Internal Server Error) (index):12430 Uncaught TypeError: Cannot read property 'domUtils' of undefined at (index):12430 (anonymous) @ (index):12430

    And then when I login with RSA I get an Elmah exception that I have set up
    `System.Web.HttpException: Cannot redirect after HTTP headers have been sent.
    Generated: Fri, 01 May 2020 22:13:34 GMT

    System.Web.HttpException (0x80004005): Cannot redirect after HTTP headers have been sent.
    at System.Web.HttpResponse.Redirect(String url, Boolean endResponse, Boolean permanent)
    at System.Web.Security.FormsAuthenticationModule.OnLeave(Object source, EventArgs eventArgs)
    at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
    at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
    `
    I assuming this is all caused by some kind of redirection issue but I don't know enough about how Dotvvm receives requests I guess to even begin to guess how to debug this. Any ideas?

    Tomáš Herceg
    @tomasherceg
    @christianmother27 It looks like the authentication is applied also to DotVVM scripts - is it possible to turn it off for /dotvvmResource/ path in the app? I am not sure how it is configured - I believe it is commonly done in web.config using the <location path="dotvvmResource"> and then system.web/authorization.
    Lubos
    @tatran_twitter
    image.png
    Anyone else suffer from this?
    Tomáš Herceg
    @tomasherceg
    @tatran_twitter It happens occasionally - DotVVM extension needs to be loaded quite early when VS starts, and when it starts, it needs to load a lot of assemblies which is included in this "consumed" time.
    Lubos
    @tatran_twitter
    @tomasherceg Thanks for explanation, not a biggy. ;-)
    dima-chernin
    @dima-chernin
    Hi, I've noticed, that if I place a control directly into view, it can be found by Id at Load step, but if it is inside a repeater, it is initialized only at Render, I suppose... Is there an option to have it inside the repeater at Load step? Thank you
    Lubos
    @tatran_twitter
    image.png
    I have set this to 2MB and managed to upload 6MB file, what is the trick?
    Tomáš Herceg
    @tomasherceg
    @dima-chernin It depends when you bind data in the Repeater, but it builds its content immediately after the Load phase. What's your scenario?
    @tatran_twitter I am not sure if the check works in all browsers on the client-side. But you should be able to evaluate whether the file is OK on the server - the UploadedFilesCollection entries have a property indicating whether the file size was exceeded. https://github.com/riganti/dotvvm/blob/master/src/DotVVM.Framework/Storage/UploadedFile.cs
    dima-chernin
    @dima-chernin
    @tomasherceg , I've tried both at Load and PreRender. I have a custom upload control , which has some logics inside. It is placed into the repeter teplate, cuz i need a list of attachements being rendered sequentially. I wanted to have a func<> property in control, that would have been assigned after load, before the control events are fired on postback, so the control owner will be notified that file upload and processing was successful and the owner can do some postprocessing with the result entity.
    The controls contructor is entered when repeater starts rendering. But when I put the control into the page, it behaves as expected
    dima-chernin
    @dima-chernin
    Or as option override the default upload functionality, but still have basic validation inside the control like server side attachment analisys, etc.
    thatdbme
    @thatdbme
    Hello, I am new to DotVVM. I like what I've seen and read so far. I am doing a POC for my company to see if we can justify making the switch from WebForms to DotVVM. Currently I am trying to prove that we can use the Telerik controls we have purchased. I understand to combine DotVVM and Telerik we must use the KendoUI version. I have installed that into a new DotVVM templated project. I am able to get the Kendo controls to work in a plain HTML page. But when I attempt the same thing in a dothtml page it seems as though the DotVVM scripts are somehow preventing the KenoUI scripts from running. It appears that the jquery scripts are not actually being loaded until after the KendoUI scripts have attempted to run.
    I'm not sure how to get the scripts to load and run in the correct order. Any help is greatly appreciated.
    Ok, I made some progress. I have been trying to use the DotVVM RequiredResource tags at the top of the master page. I found that by making them regular HTML script references the scripts will execute in the correct order. Is there a way to do this correctly using the RequiredResource tags?
    Stanislav Lukeš
    @exyi
    @thatdbme Sorry for a late reply. Yes, you can specify a list of Dependencies in the resource registration, which ensures that resources will be inserted in the correct order (no matter the RequiredResource order) and also the dependencies will be added automatically.
    @dima-chernin Repeater really should initialize it's body in Load and in PreRender (if the view model change). Would you please try to be more specific what is your issue? Could you provide a easy to replicate example of it misbehaving? I mean, there can be bugs, or we can just explain what and why is happening in your situation.
    dima-chernin
    @dima-chernin
    @exyi , I'll try to make some sample project in couple of days
    Stanislav Lukeš
    @exyi
    I'm pretty sure that when you just place a custom component in a Repeater bound to a non-empty collection, then it will create the contents in Load.
    If your collection is empty after Load, and non-empty after PreRender then the components will be created just after the PreRender method is executed on view model
    dima-chernin
    @dima-chernin
    @exyi , thank you, I'll check it out )
    Stanislav Lukeš
    @exyi
    Btw, from what I see, you are assigning properties manually (find the control in the control tree and then set a property, right?). It should IMHO work to assign the Func<> property as a command binding or a resource binding to a expression that returns the matching Func<...>
    thatdbme
    @thatdbme
    Thank you @exyi.

    I am in the process of adding DotVVM into a legacy Webforms app. I have it installed and configured as far as I can tell. I added a dummy DotHTML page and validated the pathing is correct. All the legacy code that I have tested is working.

    When I try to access a DotHTML page, however, I am getting a 500 error back from the DotVVM code. I have received a series of them that changes after I resolve each one. They are all the same System.IO.FileNotFoundException and are all for libraries the project does not even reference. I was able to resolve about 6 of them by adding references to the library it specifies. But now it’s asking for one I can’t even find in order add the reference. The error is always occurring because of this line in DotVVM code: void DotVVM.Framework.Compilation.ControlTree.DefaultControlResolver.InvokeStaticConstructorsOnAllControls.

    I don’t know how to proceed. This is a complete show stopper for my POC at the moment.

    How do I proceed? Why is DotVVM looking for libraries we’re not even referencing? If it is a dependency of something we are referencing, how can I track it down? Thank you for your help.

    Chui Tey
    @teyc
    May be you can show a stacktrace with the full errormessage?
    Does dotVVM have any mechanism where asynchronous changes on the server-side ViewModel is pushed down to the client?
    thatdbme
    @thatdbme
    I was able to get past my issue by referencing every library that DotVVM said was missing (though our code does not need it). Is there a better way?