Base solution for your next web application
Open Closed

AspNet Core Telerik #6711


User avatar
0
martin created

So we are looking at using Telerik with ASP.NET Zero and their guide details how to setup a ASP.NET Core project and get it all working. https://docs.telerik.com/aspnet-core/getting-started/getting-started#configuration Which is fine and works great, they also supply a demo project which shows everything working.

I used the manual process for adding the Client Side resources. https://docs.telerik.com/aspnet-core/getting-started/getting-started-copy-client-resources#manual-installation

Step 4. Register the Kendo UI styles and scripts in ~/Views/Shared/_Layout.cshtml

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - TelerikSetup</title>

    <environment include="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />

        <link rel="stylesheet" href="~/lib/kendo-ui/styles/kendo.common-nova.min.css" />
        <link rel="stylesheet" href="~/lib/kendo-ui/styles/kendo.nova.min.css" />

        <script src="~/lib/jquery/dist/jquery.js"></script>

        @* Place Kendo UI scripts after jQuery *@
        <script src="~/lib/kendo-ui/js/kendo.all.min.js"></script>
        <script src="~/lib/kendo-ui/js/kendo.aspnetmvc.min.js"></script>
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
              crossorigin="anonymous"
              integrity="sha256-eSi1q2PG6J7g7ib17yAaWMcrr5GrtohYChqibrV7PBE=" />

        <link rel="stylesheet"
              href="https://kendo.cdn.telerik.com/2019.1.115/styles/kendo.common-nova.min.css"
              asp-fallback-href="~/lib/kendo-ui/styles/kendo.common-nova.min.css"
              asp-fallback-test-class="k-common-test-class"
              asp-fallback-test-property="opacity" asp-fallback-test-value="0" />

        <link rel="stylesheet"
              href="https://kendo.cdn.telerik.com/2019.1.115/styles/kendo.nova.min.css"
              asp-fallback-href="~/lib/kendo-ui/styles/kendo.nova.min.css"
              asp-fallback-test-class="k-theme-test-class"
              asp-fallback-test-property="opacity" asp-fallback-test-value="0" />

        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous"
                integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
        </script>

        @* Place Kendo UI scripts after jQuery *@
        <script src="https://kendo.cdn.telerik.com/2019.1.115/js/kendo.all.min.js"
                asp-fallback-src="~/lib/kendo-ui/js/kendo.all.min.js"
                asp-fallback-test="window.kendo">
        </script>
        <script src="https://kendo.cdn.telerik.com/2019.1.115/js/kendo.aspnetmvc.min.js"
                asp-fallback-src="~/lib/kendo-ui/js/kendo.aspnetmvc.min.js"
                asp-fallback-test="kendo.data.transports['aspnetmvc-ajax']">
        </script>
    </environment>
    <link rel="stylesheet" href="~/css/site.css" />
</head>

So how do I acheive that using the ASPNET.Core framework ?

/.Web.Mvc does have anything that is similar to a _Layout.cshtml page.


23 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    Have you tried it according to the telerik document?

    The background layout page is here: https://github.com/aspnetzero/aspnet-zero-core/tree/dev/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Web.Mvc/Areas/AppAreaName/Views/Layout

  • User Avatar
    0
    martin created

    Thanks again for the awesome support. I saw the Layout.cshtml page but wasn't sure it was the one to edit since there were heaps of them. Still struggling with getting the Telerik controls to actually work. Still waiting for an answer from their support people.

  • User Avatar
    0
    martin created

    Not sure if this is any use to anyone else but I might as well post it here, if it helps one person then it was worth my time.

    Important the links below are the reference documents supplied by Telerik. You MUST read and understand these before continuing. Some of the steps required are NOT covered in this guide. This guide is mainly to explain what is needed to get the Telerik datepicker control working with a _CreateOrEditModal.cshtml modal form

    https://docs.telerik.com/kendo-ui/intro/installation/getting-started#download https://docs.telerik.com/devtools/aspnet-ajax/installation/installing-the-telerik-controls-from-nuget-package https://docs.telerik.com/aspnet-mvc/getting-started/nuget-install#set-up-nuget-package-source https://docs.telerik.com/aspnet-core/getting-started/getting-started https://docs.telerik.com/aspnet-core/getting-started/getting-started-copy-client-resources#manual-installation

    Please refer to https://docs.telerik.com/aspnet-core/getting-started/getting-started

    1. Add the Telerik.UI.for.AspNet.Core dependency via NuGet to the ..Web.Mvc project
    2. Update ..Web.Mvc\Startup\Startup.cs adding using Newtonsoft.Json.Serialization;
    3. Update ..Web.Mvc\Startup\Startup.cs
    public IServiceProvider ConfigureServices(IServiceCollection services)
           {
               //MVC
               services.AddMvc(options =>
               {
                   options.EnableEndpointRouting = false;
                   options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
               }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
               services.AddMvc().AddJsonOptions(options =>
                   options.SerializerSettings.ContractResolver = new DefaultContractResolver());
               services.AddKendo();
    
    1. Update ..Web.Mvc\Areas\App\Views_ViewImports.cshtml
    @addTagHelper *, Kendo.Mvc
    @using Kendo.Mvc.UI
    
    1. Copy the Client-Side files manually from the telerik.ui.for.aspnet.core.20XX.X.XXX.zip file from Telerik to :- I found using npm and webpack as per the instructions results in some major problems. _Refer to _https://docs.telerik.com/aspnet-core/getting-started/getting-started-copy-client-resources#manual-installation
    ..Web.Mvc\wwwroot\lib\kendo-ui\js
    ..Web.Mvc\wwwroot\lib\kendo-ui\styles
    
    1. Add the stylesheet and scripts as per the instructions to the Theme _Layout.cshtml pages. I am only covering ..Web.Mvc\Areas\App\Views\Layout\Default\Layout.cshtml
    @section Styles{
    
    …
    
       <link rel="stylesheet" href="~/lib/kendo-ui/styles/kendo.common-nova.min.css" />
       <link rel="stylesheet" href="~/lib/kendo-ui/styles/kendo.nova.min.css" />
       @RenderSection("Styles", false)
    }
    

    Note jquery MUST be before the other scripts

    @section Scripts{
       <script abp-src="/metronic/src/js/demo/default/base/layout.js" asp-append-version="true"></script>
       <script src="~/lib/jquery/dist/jquery.min.js"></script>
       <script src="~/lib/kendo-ui/js/kendo.all.min.js"></script>
       <script src="~/lib/kendo-ui/js/kendo.aspnetmvc.min.js"></script>
       @RenderSection("Scripts", false)
    }
    

    7. Finally add the actual Kendo datepicker to your page

    @(Html.Kendo().DatePicker()
    .Name("dob")
    .Value(Model.Person.DOB)
    )
    

    If the control doesn't render at all check the client-side assets as well as the stylesheet and scripts in _Layout.cshtml page

    If you get something like **IHtmlHelper&lt;CreateOrEditCatModalViewModel>' does not contain a definition for 'Kendo' ** check to make sure you have updated the correct _ViewImports.cshtml page. You don't need to register another dll or anything like that contrary to what you find elsewhere.

  • User Avatar
    1
    murphymj5209 created

    I wanted to thank you for the detail on the telerik controls. it was a big help.

  • User Avatar
    0
    BobIngham created

    Thanks @martin. I use Telerik in the angular, dotnetcore Zero version. It is also a bit fiddly, should anyone require details please let me know.

  • User Avatar
    0
    dev_frontrush created

    Which version of the Zero framework are you using? I am trying to get setup with 6.9.1 but can't get a single control to render. The inputs render but I get a kendo.dateTimePicker is not a function error (or grid, or ...)

    Are we going to have to change how we include external control libraries with every new release? Seems like we are doing a lot of refactoring with every new release. Is there an recommended upgrade path? We have our own repositories setup and it seems like when there is an upgrade a merge is always painful, especially if we skip a release or two.

  • User Avatar
    0
    BobIngham created

    angular, dotnetcore, 6.8.0, .net 4.6.1 I use Telerik controls for all my UI. It's not difficult but a little fiddly. Don't use ng add as suggested by kendo, use npm install and then delete your package.json.lock and run yarn. This is from memory: Install with npm:

    npm install --save @progress/kendo-angular-buttons @progress/kendo-angular-l10n
    

    Add rxjs-compat (5 or 6, depending on your version)

    npm install --save rxjs-compat@6
    

    Add Kendo style:

    npm install @progress/kendo-theme-default
    

    Delete package.json.lock and run yarn. Add styles to angular.json:

    "node_modules/@progress/kendo-theme-default/dist/all.css"
    

    Import and add ButtonsModule to the imports array in whichever module you're working in. Import ButtonsModule into your component and use it as follows on your html page.

    <button kendoButton (click)="onButtonClick()">Default</button>
    

    Hope that helps. It's worth perservering with, here's my date picker for a ChartJS object:

  • User Avatar
    0
    dev_frontrush created

    What about for jQuery? It looks like you are referencing the Web.Mvc project which is for jQuery?

  • User Avatar
    0
    dev_frontrush created

    Sorry, that was from martin on the Core + jQuery setup; I can get them up with the Angular solution but no dice with the Core + jQuery 6.9.1, seems like it should be easier in the Core + jQuery but it is far from, it just doesn't work.

  • User Avatar
    0
    BobIngham created

    Sorry, I can't help with MVC and jquery.

  • User Avatar
    0
    martin created

    I understand your pain @dev_frontrush it was a pain in the arse to get it all working. I suspect the issue isn't the framework version but something you missed.

    Go back through my list and re-check everything, if you missed some parts you will either get the error like you described or the control won't render. Sorry that I can't give you more feedback but I came to a working solution via trial and error. Also it was for the Demo project.

    Sadly I think we are dropping Telerik since some of the advice we have been given was that Telerik can be a major hassle to implement.

  • User Avatar
    0
    martin created

    I had a few minutes to spare so I though why not give some more info ? I double checked the differences between the code changes. Here is a synposis.

    Web.Mvc\Startup\Startup.cs

    using Newtonsoft.Json.Serialization .......

     //MVC
                services.AddMvc(options =>
                {
                    options.EnableEndpointRouting = false;
                    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
                }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
                services.AddMvc().AddJsonOptions(options =>
                    options.SerializerSettings.ContractResolver = new DefaultContractResolver());
                services.AddKendo();
    

    Web.Mvc\Areas\App\Views_ViewImports.cshtml

    .......
    @addTagHelper *, Kendo.Mvc
    @using Kendo.Mvc.UI
    

    Web.Mvc\Areas\App\Views\Layout\Default\Layout.cshtml (Other layout files were updated as well)

    @section Styles{
       ......
        <link rel="stylesheet" href="~/lib/kendo-ui/styles/kendo.common-nova.min.css" />
        <link rel="stylesheet" href="~/lib/kendo-ui/styles/kendo.nova.min.css" />
       .......
    }
    
    @section Scripts{
    .......
        <script src="~/lib/jquery/dist/jquery.min.js"></script>
        <script src="~/lib/kendo-ui/js/kendo.all.min.js"></script>
        <script src="~/lib/kendo-ui/js/kendo.aspnetmvc.min.js"></script>
    .......
    }
    
  • User Avatar
    0
    dev_frontrush created

    Hey bobingham,

    Have you setup the Kendo Angular grid using a service that uses the DataSourceRequest and DataSourceResult? An example would be awesome!

    Thanks

  • User Avatar
    0
    BobIngham created

    @dev_frontrush, yep I use the grid in two or three different flavours but it's something I didn't document. It might take a couple of days but I'll try get some basic instructions together for you, I'm up to my ears right now.

  • User Avatar
    0
    dev_frontrush created

    Do you get weird visual results with filters? Got it to work but the state is never applied and doesn't look like the material styles are either.

  • User Avatar
    0
    BobIngham created

    @dev_frontrush, There doesn't seem to be a method of adding files to this forum. If you want to post your email I can help by sending you my code files but I haven't the time to document exactly how to implement at the moment, I'm in the middle of an implementation. The code below shows how I implement filters, hopefully it may help, I suspect you may be having a problem with the long descriptor.

            [DontWrapResult(WrapOnError = true)]
            public async Task<JsonResult> GetEntities([DataSourceRequest]DataSourceRequest request, int isDeleted)
            {
                //for testing...
                isDeleted = 0;
    
                //cast string to Guid
                if (request.Filters != null)
                {
                    ModifyFilters(request.Filters);
                }
                var query = await _ncEntityService.GetSPEntityIQueryableForKendoGrid(isDeleted);
                var model = await query.ToDataSourceResultAsync(request);
                return Json(model);
            }
    

    And the modified filter code:

            private void ModifyFilters(IList<IFilterDescriptor> filters)
            {
                if (filters.Any())
                {
                    foreach (var filter in filters)
                    {
                        var descriptor = filter as FilterDescriptor;
                        if (descriptor != null && descriptor.Member == "id")
                        {
                            descriptor.Value = ToGuid(descriptor.Value.ToString());
                            descriptor.MemberType = typeof(Guid);
                        }
                        else if (descriptor != null && descriptor.Member == "userName")
                        {
                            var user = _userRepository.FirstOrDefault(m => m.UserName == descriptor.Value.ToString());
                            descriptor.Value = 0;
                            if (user != null)
                            {
                                descriptor.Value = user.Id;
                            }
                            descriptor.Member = "userId";
                            descriptor.MemberType = typeof(long);
                        }
                        else if (filter is CompositeFilterDescriptor)
                        {
                            ModifyFilters(((CompositeFilterDescriptor)filter).FilterDescriptors);
                        }
                    }
                }
            }
    
  • User Avatar
    0
    OutdoorEd created

    Very helpful post. One thing I would add for Telerik ASP.NET Core Jquery with Netzero Core 2.2

    I found that the Telerik js files need to be in the header rather than at the bottom of the page to work so on the NetZero /Area/Views/Layouts/__Layout.cshtml

    I moved the script code up into the header AND there is a Netzero RenderScript flag in the footer which is set to false by default, change this to true when moving the Script Code to the Header

    @RenderSection("Scripts", true)

    Here is the Code I moved to the header

    `

    <!-- Dynamic scripts of ABP system (They are created on runtime and can not be bundled) -->
    <script src="@(ApplicationPath)AbpServiceProxies/GetAll?v=@(AppTimes.StartupTime.Ticks)" type="text/javascript"></script>
    <script src="@(ApplicationPath)AbpScripts/GetScripts?v=@(AppTimes.StartupTime.Ticks)" type="text/javascript"></script>
    
    <script type="text/javascript">
        abp.localization.currentCulture = $.extend({}, abp.localization.currentCulture, { displayNameEnglish: '@CultureInfo.CurrentUICulture.EnglishName' });
        moment.locale('@(CultureHelper.UsingLunarCalendar ? "en": CultureInfo.CurrentUICulture.Name )'); //Localizing moment.js
    </script>
    
    <script src="@(ApplicationPath)view-resources/Areas/Admin/Views/_Bundles/signalr.bundle.min.js" asp-append-version="true"></script>
    
    <script abp-src="/view-resources/Areas/Admin/Views/_Bundles/common-scripts.js" asp-append-version="true"></script>
    <script abp-src="/view-resources/Areas/Admin/Views/_Bundles/app-common-scripts.js" asp-append-version="true"></script>
    <script abp-src="/view-resources/Areas/Admin/Views/Layout/_Header.js" asp-append-version="true"></script>
    <script src="@(ApplicationPath)view-resources/Areas/Admin/Views/Layout/_ThemeSelectionPanel.js" asp-append-version="true"></script>
    
    @if (isChatEnabled)
    {
        <script src="@(ApplicationPath)view-resources/Areas/Admin/Views/Layout/_ChatBar.js" asp-append-version="true"></script>
        <script src="@(ApplicationPath)Common/Scripts/Chat/chat.signalr.js" asp-append-version="true"></script>
    }
    
    <script src="[email protected]_Validation_Localization" asp-append-version="true"></script>
    <script src="[email protected]_Select_Localization" asp-append-version="true"></script>
    <script src="[email protected]_Timeago_Localization" asp-append-version="true"></script>
    <script src="[email protected]_Localization" asp-append-version="true"></script>
    
    <!--end::Base Scripts -->
    <!--begin::Telerik Scripts -->
    <!-- NOTE Jquery already loaded as part of NetZero Bundles above-->
    

    ** ** `

  • User Avatar
    0
    dev_frontrush created

    [email protected]

    Would definitely like to see the front and back end in totality. Thanks!

  • User Avatar
    0
    Mitch created

    I hope you don't mind me jumping in on this discussion (about a year late!). I'll do another post just in case this gets missed.

    I'm using Telerik MVC and Core components with ANZ, but I have found that when dealing with forms, ANZ expects the values with fields in Camel Case whereas Telerik returns the field names in Pascal Case. The end result is the when clicking on the Save button, an error occurs due to all fields having null values.

    I have tried several times to fix this and in the end I gave up and decided to completely bypass the Volosoft validation and CRUD routines and use my Telerik friendly versions.

    However, I would be more productive if I could use the standard ANZ approach, which I believe could be achieved by either getting ANZ to accept Pascal Case or to get Telerik to post in Camel Case.

    So my question is, how is everyone getting Telerik form components to save data with ANZ?

  • User Avatar
    1
    OutdoorEd created

    In Startup.cs ConfigureServices you need

    .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

    That handles the Pascal Case/Camel Case issue

    I have it right above IdentityRegistrar.Register(services);

  • User Avatar
    0
    Mitch created

    Thanks for the quick reply.

    I had previously been trying this approach with the MVC version, but gave up due to issues with the Multi Select control.

    I've just tried your suggestion with some simple Telerik TextBox TagHelpers and with a bit of experimenting with the Name and ID I've managed to get it working.

    I do remember from my previous attempts to get it working with the MVC version that I managed to get it working somewhat, but the MultiSelect control proved to be too difficult. Whatever I tried I couldn't return more than one selected value.

    Have you managed to get the MultiSelect working, and if so did you find it required a bit of tweaking?

    Thanks again for your help with this.

  • User Avatar
    0
    OutdoorEd created

    I haven't used the MultiSelect tool so I don't have an answer for you on that. I've found that the HtmlHelpers can be very finicky to configure to get them to work correctly especailly with handling Nulls and Telerik's documentation is poor.

    For example:

    Create for a DateTimePicker

            @(Html.Kendo().DatePicker()
            .Name("ContactDate")
            .Value("")
            .HtmlAttributes(new { placeholder = "month/day/year" })
        )
    

    Edit for a DateTimePicker

                @(Html.Kendo().DatePicker()
                .Name("ContactDate")
                .Value(Model.ContactDate)
                .HtmlAttributes(new { placeholder = "month/day/year" })
            )
    
  • User Avatar
    0
    BobIngham created

    @Mitch, They key to the multi-select component is to have two arrays, one for available items and one for selected items, the latter of which forms part of your form group. I know you're JQuery but hopefully the following Angular code should help:

                <kendo-multiselect 
                    [data]="availableOrganizationUnits"
                    textField="displayName"
                    valueField="id"
                    [(ngModel)]="selectedOrganisationUnits"
                    (valueChange)="onOrganizationUnitChange($event)"
                    style="margin-left:2rem;vertical-align:middle;display:inline-block;">
                </kendo-multiselect>
    
    
    
    public availableOrganizationUnits = new Array<OrganizationUnitDto>();
    public selectedOrganisationUnits: Array<OrganizationUnitDto>;
    public selectedOrganisationUnitIdsAsString: string;
    
    
    get data....
          .subscribe((result) => {
            if (result.organizationUnits.length > 0) {
              this.availableOrganizationUnits = result.organizationUnits;
    
      ...
      
    onOrganizationUnitChange(organisationUnits: Array<OrganizationUnitDto>): void {
        this.selectedOrganisationUnitIdsAsString = _.map(organisationUnits, 'id').toString();
        this.getDataAndSetChartData(moment(this.range.start), moment(this.range.end), false);
    }