Base solution for your next web application
Ends in:
01 DAYS
01 HRS
01 MIN
01 SEC

Activities of "ebenzle"

@winstat Thank you! Saved me tons of time. It would be nice if this was made clear in the documentation, instead of having to sift through forum posts.

version 8.1.0 MVC .net Core

I noticed that when using excludedUserIds for _notificationPublisher.PublicAsync() we are having notifications sent to deleted users. I believe this is a bug within ABP code.

Looking at the Database, after a user is deleted their notification settings still remain in AbpNotificationSubscriptions DefaultNotificationDistributer then calls GetUsersAsync() which gets all the NotificationSubscriptions, including for any deleted users. The result is that SendNotifications() in CustomRealTimeNotifier.cs is passed a list of users that includes deleted accounts.

I think the issue is somewhere in NotificationStore.cs. This seems to be where Abp code is returning the deleted users.

Here is my code that ultimately results in notifications being sent to deleted user accounts:

Am I doing something wrong? Or is there an issue with the Abp notification that needs to be fixed?

version 8.1.0 MVC .net Core

This is just to help out others with the same issue. It took me while to find the answer and it wasn't available in the documentation.

I had a few HTML tables built statically and I wanted to apply DataTables to them. However the custom datatables code didn't seem to allow this and always resulted in 'loading...' even though I didn't want to use server side processing for the data. The answer was to use ajax: null

var dataTable = _$attendanceTable.DataTable({ serverSide: false, processing: false, ajax: null });

SettinserverSide: false doesn't seem to work with the asp.net zero version of Datatables.js

Also having the same issue. Any solutions?

zero version: 8.1.0.0 MVC .net core

For Mobile App (Xamarin) should DefaultHostUrl be set to Web.Host or Web.Mvc URL?

We are currently using the Web.Mvc URL, but continue to get the following error: "A problem occurred while trying to communicate with the server. Do you want to try again? Call failed. stream was reset: PROTOCOL_ERROR GET https://[our website address for MVC app].com/AbpUserConfiguration/GetAll"

We were going to try using the Web.Host project on a different URL for the mobile app API calls, but it seems like that might not work since 'CorsOrigins' only allows for certain domains.

Hi, I figured this out. Code as posted was correct. I had another route called "State" in a different area that was causing the conflict.

Hi. It's net core 3.x

Here is ActivityOnlineLessonAppService.cs

using System.Threading.Tasks;
using Abp.Domain.Repositories;
using NextGenLms.Courses.Dtos;
using Abp.Application.Services.Dto;
using Microsoft.EntityFrameworkCore;
using NextGenLms.Storage;
using Abp.UI;
using System;
using NextGenLms.ScormCloud;
using NextGenLms.Grading.Dtos;
using NextGenLms.Grading;
using System.IO;
using Abp.Authorization;
using NextGenLms.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Hosting;
using NextGenLms.Configuration;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Web;

namespace NextGenLms.Courses
{
    [AbpAuthorize]
    public class ActivityOnlineLessonAppService : NextGenLmsAppServiceBase, IActivityOnlineLessonAppService
    {
        private readonly ITempFileCacheManager _tempFileCacheManager;
        private readonly IRepository<ActivityOnlineLesson> _activityOnlineLessonRepository;
        private readonly IRepository<ActivityOnlineLessonUserResult> _activityOnlineLessonUserResultRepository;
        private readonly ICourseActivityAppService _courseActivityAppService;
        private readonly IGradesAppService _gradeAppService;
        private readonly IScormCloudManager _scormCloudManager;
        private readonly IConfigurationRoot _appConfiguration;
        private readonly IAppFolders _appFolders;

        public ActivityOnlineLessonAppService(
            ITempFileCacheManager tempFileCacheManager,
            IRepository<ActivityOnlineLesson> activityOnlineLessonRepository,
            IRepository<ActivityOnlineLessonUserResult> activityOnlineLessonUserResultRepository,
            ICourseActivityAppService courseActivityAppService,
            IGradesAppService gradeAppService,
            IScormCloudManager scormCloudManager,
            IWebHostEnvironment env,
            IAppFolders appFolders)
        {
            _tempFileCacheManager = tempFileCacheManager;
            _activityOnlineLessonRepository = activityOnlineLessonRepository;
            _activityOnlineLessonUserResultRepository = activityOnlineLessonUserResultRepository;
            _courseActivityAppService = courseActivityAppService;
            _gradeAppService = gradeAppService;
            _scormCloudManager = scormCloudManager;
            _appConfiguration = env.GetAppConfiguration();
            _appFolders = appFolders;
        }


        /* Saves the state for xAPI activities */
        [HttpPut]
        [Route("/App/ActivityOnlineLesson/activities/state")]
        public async Task<ActivityOnlineLessonXapiResumeOutput> State(ActivityOnlineLessonXapiResumeInput input)
        {
            // processes the xAPI state request
            var ActivityOnlineLessonXapiResumeOutput = new ActivityOnlineLessonXapiResumeOutput();

            if (input.Value == "123") {
                ActivityOnlineLessonXapiResumeOutput.Success = true;
            } else
            {
                ActivityOnlineLessonXapiResumeOutput.Success = false;
            }

            return ActivityOnlineLessonXapiResumeOutput;
        }

        /* Gets the initial state for xAPI activities */
        [HttpGet]
        [Route("/App/ActivityOnlineLesson/activities/state")]
        public async Task<string> State()
        {

            return "24146070ji1001112a0101201112C10v_player_6BypgqIVLDo_6MymGJoBbaC1^1^0000";
        }

    }
}

And the interface:

using Abp.Application.Services;
using Abp.Application.Services.Dto;
using NextGenLms.Courses.Dtos;
using NextGenLms.Courses.Dtos.Activities;
using NextGenLms.Courses.Dtos.Quiz;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace NextGenLms.Courses
{
    public interface IActivityOnlineLessonAppService : IActivityBaseAppService<ActivityOnlineLessonDto>, IApplicationService
    {

        Task<string> State();
    }
}

This is the error when trying to call the service at the URL:

Request URL: https://localhost:44312/App/ActivityOnlineLesson/activities/state?stateId=resume&activityId=68&agent=%7B%22objectType%22%3A%22Agent%22%2C%22mbox%22%3A%22mailto%3A%20admin%40defaulttenant.com%22%2C%22name%22%3A%22admin%20admin%22%7D&course_id=7&base_url=https%3A%2F%2Flocalhost%3A44312%2F

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches: 

NextGenLms.Web.Areas.App.Controllers.ActivityOnlineLessonController.state (NextGenLms.Web.Mvc)
NextGenLms.Courses.ActivityOnlineLessonAppService.State (NextGenLms.Application)
   at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ReportAmbiguity(CandidateState[] candidateState)
   at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ProcessFinalCandidates(HttpContext httpContext, CandidateState[] candidateState)
   at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.Select(HttpContext httpContext, CandidateState[] candidateState)
   at Microsoft.AspNetCore.Routing.Matching.DfaMatcher.MatchAsync(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.Matching.DataSourceDependentMatcher.MatchAsync(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS
=======
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization: null
Connection: keep-alive
Cookie: .AspNetCore.Antiforgery.LvCbYuYZ0jQ=CfDJ8MZ5iXL2Cq9JmHEp0VtZuygW3VNV9s4pgXA7uVXZcJmrDDW_Ki_4MJAbWrcHA_8izlDoWJtLV6EjAGbv7qowvvdTwtoo7Gtxpb3GZVKJaSX6mrQ9JbuTD7hA7rA8BjzWqh9BpYZ3uPj3rsxVhVjE7XU; idsrv.session=HI_7vLf0gvPNxgCYcQM6mw; googtrans=/en/en; XSRF-TOKEN=CfDJ8MZ5iXL2Cq9JmHEp0VtZuyg0LT35YHGojvJWUMTda0XGMmm-WY7GwoiabCuR0MK-4_85-5yta9-xA62uFrgLDVphnH3tRAtGqxUid-KzH4YDlPZ-Fc9eQgFaFnMfaWgKELUkF-tjMHd_qRQTMgb8OvNKcjjSmvmxRvEB2iisN029C-_fl_dS9pCPgZZgqYAuUQ; .AspNetCore.Identity.Application=CfDJ8MZ5iXL2Cq9JmHEp0VtZuyjiKQwKR2Y7qQ1RgaiNDQmoVvpimfIBPPpJcd_6PCijFwK5qbeOVLOkKP0dyhZcGuOq9Doa_Wz2U87mqnMB23zZQi88JyyOrIBTE6q2C-QewbT57SzX2Tn_8UZkzupWNZ8Lh9aTtw_AQY9sU39-uyEWFOjWwOd3qsobIlbzapItCUJAb6DdVFzAvuuWZlucKXIeNtBJ7p6lJc6f8Z60QGLWPmvTzH2NVhybsTGeqWny4K7jA_IHxFUSX9X1DE7JMWJOY0AB1hqWPtcCe6bAAx9VMRAra_xyNCfJxoGjYkwC1zC4EjAuZHmlSdxcKajNeRay-hyMD96PvJYIcHiipocEmJdNJR8FjC7w2ha6TvXxD0OeTOCG6N0o8TX7yL6-qNt-__s9c4wkhjIlHYIHDFhI-LGaY6yD6qLg1SqUrSEjxlHAg1iPtgXiJmgLgzHl3w0HuI7PNuFra_KQDzr4lYgQWANtVUpofmbVa6YmnhGlOHc-1ACIHD1mg28TND4YDAjxpBmZ860Kgwob_7tpf1yvVqnzoMbluiEhb9ci3MDcV0988b_NyXdp5RxGD-7ZdmvHbgbcODit0Xrnn0hbG41FekWbFFq0ONJTABu_khvM_ALnaUd1zx20dFt12124BkGppl60eJOYq_aGL9YJgWsbch_UWL8O6d7SpHKaLhLtZOkB1ZeW_kSo1v5TGF6x7srtInRJYgO4Vb0U_RIJlU8m1BijBBq6Z2niiBFkT30CqB_meLgQnIXM_afSy9bUg-fclsUnm12rFNlRBZkjAvXZAXNBWXlHvY14cJ9TsKTQ2j7tgppTQEj_RH4zr3BNORfQoSwoxeEkGelIQ3xEaYEdkp8p6bQ9tb3p-LwTZzchN04JdAhn9P_MvNEun8yaN4Ld2fh6zv5GeAoCm8ij9WpDYXe2BuvtO_zU8YRyQJe9y94HHVo-JZvdWzC8UM4u3tg
Host: localhost:44312
Referer: https://localhost:44312/ActivityFiles/OnlineLessons/99df21dd-4238-432d-8eb0-6dd2722dc621/story.html?endpoint=https://localhost:44312/App/ActivityOnlineLesson/&course_id=7&actor=%7B%22name%22%3A%20%5B%22admin%20admin%22%5D%2C%20%22mbox%22%3A%20%5B%22mailto%3A%20admin%40defaulttenant.com%22%5D%7D&activity_id=68&base_url=https://localhost:44312/
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
X-Experience-API-Version: 1.0.1
DNT: 1
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty

I believe those are all the related code files.

Thanks.

ASP.Net Core MVC/jQuery

In our application service we need to be able to handle an API call to the same route, but process it differently based on the HTTP method. This call is coming from an external application and we are unable to change how the call is made, only how we handle it within our application.

the route: App/ActivityOnlineLesson/activities/state

[HttpPut] - should save the passed value
[HttpGet] - will return a saved value

Our current code returns an error: Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches:

How do we have the same route process the Get and Put methods separately?


Our AppService:

        /* Saves the state for xAPI activities */        [HttpPut]
        [Route("/App/ActivityOnlineLesson/activities/state")]
        public async Task<ActivityOnlineLessonXapiResumeOutput> State(ActivityOnlineLessonXapiResumeInput input)
        {
            // processes the xAPI state request
            var ActivityOnlineLessonXapiResumeOutput = new ActivityOnlineLessonXapiResumeOutput();
            ActivityOnlineLessonXapiResumeOutput.Success = true;

            return ActivityOnlineLessonXapiResumeOutput;
        }

        /* Gets the initial state for xAPI activities */
        [HttpGet]
        [Route("/App/ActivityOnlineLesson/activities/state")]
        public async Task<string> State()
        {
            return "24146070ji1001112a0101201112C10v_player_6BypgqIVLDo_6MymGJoBbaC1^1^0000";
        }

I thought that the [HttpGet] and [HttpPut] would determine which to use depending on the HTTP Method.


Our Interface looks like this:

    public interface IActivityOnlineLessonAppService : IActivityBaseAppService<ActivityOnlineLessonDto>, IApplicationService
    {
        Task<ActivityOnlineLessonXapiResumeOutput> State(ActivityOnlineLessonXapiResumeInput input);

        Task<string> State();
    }

Is there a built in way for users to provide their own translation strings when adding content to the site? For example, in a text area our admin would type:

<span data-lang="es_mx">Bienvenido a la pagina web.Welcome to the website.</span>

When displayed on a page that would show the correct string based on the current user's language.

Thanks

asp.net zero v8.1.0 ASP.NET MVC 5.x & jQuery

We'd like to add a navigation link that will allow users direct access to the create/edit modal for entities.

For example, an entity names 'Courses' might have a menu item like this:

AddItem(new MenuItemDefinition( AppPageNames.Common.AddCourses, L("AddCourses"), url: [open /Courses/\_CreateOrEditModal.cshtml], icon: "flaticon-presentation-1", permissionDependency: new SimplePermissionDependency(AppPermissions.Pages\_Administration\_Courses) ) )

If it's not possible to open the modal because of dependancies on the main entity page, then is it possible to open that page, then auto trigger _addCourseModal.open() once the page loads?

Showing 1 to 10 of 16 entries