Base solution for your next web application

Activities of "OutdoorEd"

What was the previous code issue?

Hello all,

I've activated email verification when creating a new user today, but I've faced the below exception when the user clicks on the link sent in the activation email. It fails when on the line

await _userManager.UpdateAsync(user);

and the exception detail is "Abp.Domain.Entities.EntityNotFoundException: There is no such an entity. Entity type: XYZ.Authorization.Users.User, id: 5"

I've double checked that there is user id: 5 in the DB so I'm not sure why this is failing now?

Any insights will be appreciated.

Exception detail as the below:

There is no such an entity. Entity type: XYZ.Authorization.Users.User, id: 5

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: Abp.Domain.Entities.EntityNotFoundException: There is no such an entity. Entity type: XYZ.Authorization.Users.User, id: 5

Source Error: 


Line 672:            user.EmailConfirmationCode = null;
Line 673:
Line 674:            await _userManager.UpdateAsync(user);
Line 675:
Line 676:            var tenancyName = user.TenantId.HasValue


Stack Trace: 


[EntityNotFoundException: There is no such an entity. Entity type: XYZ.Authorization.Users.User, id: 5]
   Abp.Domain.Repositories.<GetAsync>d__17.MoveNext() in D:\Halil\Github\aspnetboilerplate\src\Abp\Domain\Repositories\AbpRepositoryBase.cs:86
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   Abp.Threading.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__5`1.MoveNext() in D:\Halil\Github\aspnetboilerplate\src\Abp\Threading\InternalAsyncHelper.cs:120
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   Abp.Authorization.Users.&lt;GetUserNameFromDatabaseAsync&gt;d__64.MoveNext() in D:\Halil\Github\module-zero\src\Abp.Zero\Authorization\Users\AbpUserStore.cs:0
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   Abp.Authorization.Users.&lt;UpdateAsync&gt;d__41.MoveNext() in D:\Halil\Github\module-zero\src\Abp.Zero\Authorization\Users\AbpUserManager.cs:343
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +28
   XYZ.Web.Controllers.<EmailConfirmation>d__39.MoveNext() in C:\Repos\Personal\XYZ_MVC\XYZ.Web\Controllers\AccountController.cs:674
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   Abp.Threading.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__5`1.MoveNext() in D:\Halil\Github\aspnetboilerplate\src\Abp\Threading\InternalAsyncHelper.cs:120
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +97
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass37.&lt;BeginInvokeAsynchronousActionMethod&gt;b__36(IAsyncResult asyncResult) +17
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
   System.Web.Mvc.Async.AsyncInvocationWithFilters.&lt;InvokeActionMethodFilterAsynchronouslyRecursive&gt;b__3d() +50
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass46.&lt;InvokeActionMethodFilterAsynchronouslyRecursive&gt;b__3f() +225
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass46.&lt;InvokeActionMethodFilterAsynchronouslyRecursive&gt;b__3f() +225
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass46.&lt;InvokeActionMethodFilterAsynchronouslyRecursive&gt;b__3f() +225
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass46.&lt;InvokeActionMethodFilterAsynchronouslyRecursive&gt;b__3f() +225
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass33.&lt;BeginInvokeActionMethodWithFilters&gt;b__32(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass2b.&lt;BeginInvokeAction&gt;b__1c() +26
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass21.&lt;BeginInvokeAction&gt;b__1e(IAsyncResult asyncResult) +100
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
   System.Web.Mvc.Controller.&lt;BeginExecuteCore&gt;b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
   Castle.Proxies.AccountControllerProxy.EndExecuteCore_callback(IAsyncResult asyncResult) +4
   Castle.Proxies.Invocations.Controller_EndExecuteCore.InvokeMethodOnTarget() +55
   Castle.DynamicProxy.AbstractInvocation.Proceed() +80
   Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation) in D:\Halil\Github\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:29
   Castle.DynamicProxy.AbstractInvocation.Proceed() +108
   Castle.Proxies.AccountControllerProxy.EndExecuteCore(IAsyncResult asyncResult) +142
   System.Web.Mvc.Controller.&lt;BeginExecute&gt;b__15(IAsyncResult asyncResult, Controller controller) +12
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   Castle.Proxies.AccountControllerProxy.EndExecute_callback(IAsyncResult asyncResult) +26
   Castle.Proxies.Invocations.Controller_EndExecute.InvokeMethodOnTarget() +55
   Castle.DynamicProxy.AbstractInvocation.Proceed() +80
   Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation) in D:\Halil\Github\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:29
   Castle.DynamicProxy.AbstractInvocation.Proceed() +108
   Castle.Proxies.AccountControllerProxy.EndExecute(IAsyncResult asyncResult) +142
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.MvcHandler.&lt;BeginProcessRequest&gt;b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +129

I am on v3.0.0.0

I tried to use {DisableValidation] both in individual Actions in the Controller and on the entire Controller but I still get Abp.Runtime.Validation.AbpValidationException: Method arguments are not valid

If I add
Configuration.Modules.AbpMvc().IsValidationEnabledForControllers = false; the MVC validation works however, it means that I have disabled validation for all of the Abp Controllers as well which I don't want to do (things like creating Users/Roles/Tenants etc.)

Question

I have added lots of Permission-based pages in my app and having the Permissions section come up as a model requires a lot of scrolling. How can I "turn off" modals for a particular view and just have it render on a regular page. In my case I am looking at the _PermissionsModal.cshtml

Thanks. I tried setting this up with both the Default DbContent and separate DBContent but have not been able to get it to work.

My Entity class inherits IMustHaveTenant

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
using Abp.Domain.Entities;

[Table("idb_IncidentDamage")]
public partial class IncidentDamage : IMustHaveTenant
{
    public Guid Id { get; set; }

My Second DbContext inherits AbpDbContext

using System.Data.Entity; using OE_Tenant.Incidents.Entity; using Abp.EntityFramework;

namespace OE_Tenant.EntityFramework { public class IDBDbContext: AbpDbContext { public IDBDbContext() : base("SecondDefault")

I used the EF6 Scaffolding Wizard to generate the Controllers and Views for CRUD operations straight from the Entities and added the necessary references to Abp and inherited from the ControllerBase

When looking at breakpoints in the Controller for the AbpSession.TenantId the correct TenantId <ins>is</ins> in the session variable however, there is no database filtering taking place. All records are shown from all Tenants. There must be something that is missing/needs to be added to the Scaffolded Controller to include the TenantId in filtering and CRUD operations.

Controller using System; using System.Data.Entity; using System.Linq; using System.Net; using System.Web.Mvc; using Abp.Authorization; using OE_Tenant.EntityFramework; using OE_Tenant.Incidents.Entity; using OE_Tenant.Web.Controllers;

namespace OE_Tenant.Web.Areas.Incidents.Controllers { [AbpAuthorize] public class IncidentDamageController : OE_TenantControllerBase //: Controller { private IDBDbContext db = new IDBDbContext();

    // GET: Incidents/IncidentDamage
    public ActionResult Index()
    {
        var tenantId = AbpSession.TenantId;
        var IncidentDamage = db.IncidentDamage.Include(i => i.Incident).Include(i => i.LkpDamageSeverity).Include(i => i.LkpDamageType);
        return View(IncidentDamage.ToList());
    }

This is the full controller generated by EF

using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Linq; using System.Threading.Tasks; using System.Net; using System.Web; using System.Web.Mvc; using Abp.Authorization; using OE_Tenant.EntityFramework; using OE_Tenant.Incidents.Entity; using OE_Tenant.Web.Controllers;

namespace OE_Tenant.Web.Areas.Incidents.Controllers { [AbpAuthorize] public class IncidentDamageController : OE_TenantControllerBase //: Controller { private IDBDbContext db = new IDBDbContext();

    // GET: Incidents/IncidentDamage
    public ActionResult Index()
    {
        var tenantId = AbpSession.TenantId;
        var IncidentDamage = db.IncidentDamage.Include(i => i.Incident).Include(i => i.LkpDamageSeverity).Include(i => i.LkpDamageType);
        return View(IncidentDamage.ToList());
    }

    // GET: Incidents/IncidentDamage/Details/5
    public ActionResult Details(Guid? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        IncidentDamage IncidentDamage = db.IncidentDamage.Find(id);
        if (IncidentDamage == null)
        {
            return HttpNotFound();
        }
        return View(IncidentDamage);
    }

    // GET: Incidents/IncidentDamage/Create
    public ActionResult Create()
    {
        ViewBag.IncidentId = new SelectList(db.Incident, "Id", "IncidentEvent");
        ViewBag.DamageSeverityId = new SelectList(db.LkpDamageSeverity, "Id", "DamageSeverity");
        ViewBag.DamageTypeId = new SelectList(db.LkpDamageType, "Id", "DamageType");
        return View();
    }

    // POST: Incidents/IncidentDamage/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see &lt;a class=&quot;postlink&quot; href=&quot;http://go.microsoft.com/fwlink/?LinkId=317598&quot;&gt;http://go.microsoft.com/fwlink/?LinkId=317598&lt;/a&gt;.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Id,IncidentId,DamageTypeId,DamageDescription,DamageSeverityId,DamageAmount,IndexIdentity,TenantId,IsDeleted,DeletedUserId,DeletionTime,LastModificationTime,LastModifiedUserId,CreationTime,CreatorUserId")] IncidentDamage IncidentDamage)
    {
        if (ModelState.IsValid)
        {
            IncidentDamage.Id = Guid.NewGuid();
            db.IncidentDamage.Add(IncidentDamage);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.IncidentId = new SelectList(db.Incident, "Id", "Activity", IncidentDamage.IncidentId);
        ViewBag.DamageSeverityId = new SelectList(db.LkpDamageSeverity, "Id", "DamageSeverity", IncidentDamage.DamageSeverityId);
        ViewBag.DamageTypeId = new SelectList(db.LkpDamageType, "Id", "DamageType", IncidentDamage.DamageTypeId);
        return View(IncidentDamage);
    }

    // GET: Incidents/IncidentDamage/Edit/5
    public ActionResult Edit(Guid? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        IncidentDamage IncidentDamage = db.IncidentDamage.Find(id);
        if (IncidentDamage == null)
        {
            return HttpNotFound();
        }
        ViewBag.IncidentId = new SelectList(db.Incident, "Id", "Activity", IncidentDamage.IncidentId);
        ViewBag.DamageSeverityId = new SelectList(db.LkpDamageSeverity, "Id", "DamageSeverity", IncidentDamage.DamageSeverityId);
        ViewBag.DamageTypeId = new SelectList(db.LkpDamageType, "Id", "DamageType", IncidentDamage.DamageTypeId);
        return View(IncidentDamage);
    }

    // POST: Incidents/IncidentDamage/Edit/5
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see &lt;a class=&quot;postlink&quot; href=&quot;http://go.microsoft.com/fwlink/?LinkId=317598&quot;&gt;http://go.microsoft.com/fwlink/?LinkId=317598&lt;/a&gt;.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "Id,IncidentId,DamageTypeId,DamageDescription,DamageSeverityId,DamageAmount,IndexIdentity,TenantId,IsDeleted,DeletedUserId,DeletionTime,LastModificationTime,LastModifiedUserId,CreationTime,CreatorUserId")] IncidentDamage IncidentDamage)
    {
        if (ModelState.IsValid)
        {
            db.Entry(IncidentDamage).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        ViewBag.IncidentId = new SelectList(db.Incident, "Id", "Activity", IncidentDamage.IncidentId);
        ViewBag.DamageSeverityId = new SelectList(db.LkpDamageSeverity, "Id", "DamageSeverity", IncidentDamage.DamageSeverityId);
        ViewBag.DamageTypeId = new SelectList(db.LkpDamageType, "Id", "DamageType", IncidentDamage.DamageTypeId);
        return View(IncidentDamage);
    }

    // GET: Incidents/IncidentDamage/Delete/5
    public ActionResult Delete(Guid? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        IncidentDamage IncidentDamage = db.IncidentDamage.Find(id);
        if (IncidentDamage == null)
        {
            return HttpNotFound();
        }
        return View(IncidentDamage);
    }

    // POST: Incidents/IncidentDamage/Delete/5
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(Guid id)
    {
        IncidentDamage IncidentDamage = db.IncidentDamage.Find(id);
        db.IncidentDamage.Remove(IncidentDamage);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }
}

}

Is there any way to use EF Scaffolding to generate CRUD operations in controllers that include TenantId for CRUD and filtering <ins>directly</ins>from the Entity without using Dtos, etc.

I have an existing MVC 5 application that has been using standard ASP.NET Identity for Authentication/Role Authorization. I am porting it over to Abp.

I already have a populated database in my current app. I used EF Database First to generate the Models from the database and then EF MVC Scaffolding to build all of the Controllers and Views for basic CRUD operations. Since that code all works I want to see if I can reuse it. My thought is to take my current Models, Controllers, Views and place then in a new /Area in .Web. My database tables already have all the necessary Abp fields: TenantId, IsDeleted, DeletedUserId, LastModificationTime, LastModifiedUserId, CreationTime, CreatorUserId so no migrations are necessary.

From looking at the sample implementation implementing CRUD on one database table requires about 30 different code files in the various layers spread across .Application, .Core, .EntityFramework and .Web. With over 90 tables in the existing database I am trying to explore alternatives to throwing out all my existing code and rebuilding the entire application from scratch.

My questions: I need to authenticate via Abp Login and pass the TenantId over to my existing Controllers to filter all the records by TenantId and to be able to use the TenantId and UserId in Create and Update methods. Is it possible to inherit the necessary elements from Abp to use my existing Models and scaffolded Controllers without needing to recreate all of the layers in .Application, .Core, .EntityFramework?

If it is possible, what would I need to do to get my existing code to work with TenantId? Things like a second DbContext that inherits from AbpZeroDbContext, and Models that inherit IMustHaveTenant? Or are there any shortcuts to accessing the TenantId that would allow me to use my current code?

Thanks for any advice you can give me.

Thanks. Here are the features I am looking for with Subscription Management for Tenants

  1. Integrate with Editions Feature so the Subscription is tied to an Edition.
  2. Create a SubscriptionStartDate and SubscriptionEndDate for the Subscription.
  3. All Tenant Logins are filtered by the SubscriptionStartDate and SubscriptionEndDate. If the login attempt is outside of those dates, the user is redirected to a SubscriptionExpired page.
  4. Each Subscription includes an ActiveUserCount. The Tenant Admin can create as many users as they want. When they create a user that user is set as either Active or Inactive. Only Active Users are permitted to Login. The number of Active Users permitted is managed by the ActiveUserCount. When the Admin has reached that limit, they can no longer make a user active. If they change an Active User to Inactive, they free up a space to make a different user active.

For example, the Tenant purchased a 5 User License so the ActiveUserCount = 5. The Admin can add 10 users and set 5 as active. Only those 5 can login. In order to allow the 6th user to login, the Admin must make one of the 5 currently active users inactive and then the 6th user can be set as active. This allows for flexibility in the license. Also it allows for more streamlined user provisioning since the users can all be added at the same time and then easily turned on or off through an editable grid interface.

  1. A Notification System would be connected to the SubscriptionEndDate to send an email reminder to the Tenant Admin when the Subscription was going to expire (ex. 30 days out from the SubscriptionEndDate)

  2. The SuperAdmin Management Interface would include an editable grid showing all Tenants with SubscriptionStartDate, SubscriptionEndDate, ActiveUserCount and CountofUsersCurrentlyActive

For 2, 3 and 4 if Subscription was set as implemented, the Create Tenant Form would include SubscriptionStartDate, SubscriptionEndDate and ActiveUserCount. These would typically <ins>only</ins> be used by the SuperAdmin in the initial provisioning of a new Tenant and would not be accessible to the individual Tenant Admins.

Let me know if this adequately explains how I would need Subscription Management implemented.

Do you have a timeline for adding the Subscription Management feature you listed in the roadmap? I need to manage the number of Active Users in a Subscription and am developing an application to be released in May. I have built my own Active User/Subscription and Length of Subscription implementation but might pull that out depending on when this feature will be added and if it will cover these two scenarios:

StartDate & EndDate of Subscription Limit Number of Active Users: a 5 User Subscription allows you to create 5 Active Users and any number of Inactive Users. You can turn off an active user and the turn on an inactive user

Showing 61 to 70 of 73 entries