How can to map to a wrapper class using Mapster? - c#

Based on my project I need to create a wrapper for “IFormFile”, Actually I created a “AppFileProxy” class and “IAppFile” interface for this purpose :
IAppFile.cs :
public interface IAppFile
{
string Name { get; }
string FileName { get; }
string ContentType { get; }
long Length { get; }
void CopyTo(Stream target);
Task CopyToAsync(Stream target, CancellationToken cancellationToken = default);
Stream OpenReadStream();
}
AppFileProxy.cs :
public class AppFileProxy : IAppFile
{
private readonly IFormFile _formFile;
public AppFileProxy(IFormFile formFile)
{
_formFile = formFile ?? throw new ArgumentNullException(nameof(formFile));
}
public string Name => _formFile.Name;
public string FileName => _formFile.FileName;
public string ContentType => _formFile.ContentType;
public long Length => _formFile.Length;
public void CopyTo(Stream target)
{
_formFile.CopyTo(target);
}
public Task CopyToAsync(Stream target, CancellationToken cancellationToken = default)
{
return _formFile.CopyToAsync(target, cancellationToken);
}
public Stream OpenReadStream()
{
return _formFile.OpenReadStream();
}
}
Now, I want to Map “IFormFile” to “IAppFile” by using Mapster in the action controller as shown below :
CompanyDto.cs :
public class CompanyDto
{
public string Name { get; set; }
public IFormFile Logo { get; set; }
}
CompanyMapDto.cs :
public class CompanyMapDto : IRegister
{
public int Id { get; set; }
public string Name { get; set; }
public IAppFile Logo { get; set; }
public void Register(TypeAdapterConfig config)
{
config.ForType<CompanyDto, CompanyMapDto>()
.Map(dest => dest.Logo, src => new AppFileProxy(src.Logo));
}
}
action controller :
[HttpPost]
[Route("[controller]/[action]")]
public async Task<IActionResult> AddCompanyWithLogo([FromForm]CompanyDto dto)
{
CompanyMapDto company = dto.Adapt<CompanyMapDto>();
var stream = company.Logo.OpenReadStream();
return Ok();
}
But When I call action I get exception error for OpenReadStream() method :
System.NotImplementedException: The method or operation is not implemented.
at GeneratedType_1.OpenReadStream()
at MapsterInDotNet.Controllers.CompaniesController.AddCompanyWithLogo(CompanyDto dto) in C:\Users\Mohsen\source\repos\UseMapsterInDotNet\MapsterInDotNet\MapsterInDotNet\Controllers\CompaniesController.cs:line 52
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
How do I resolve this?

Well. I managed to make it work. You have to explicitly configurate mapping from IAppFile to IFormFile.
So instead of your configuration:
config.ForType<CompanyDto, CompanyMapDto>()
.Map(dest => dest.Logo, src => new AppFileProxy(src.Logo));
Use this:
TypeAdapterConfig<IFormFile, IAppFile>.ForType() // Or NewConfig()
.MapWith(src => new AppFileProxy(src));

Related

Why does adding services.AddDataProtection() to Startup.cs fix XmlException and CryptographicException?

I am following along with the Asp.net Core MVC tutorial here.
My project works when navigating to Students/Index but when I navigate to Students/Edit/1 I have the below error.
XmlException: '.', hexadecimal value 0x00, is an invalid character. Line 1, position 1.
System.Xml.XmlTextReaderImpl.Throw(Exception e)
CryptographicException: An error occurred while trying to encrypt the provided data. Refer to the inner exception for more information.
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Protect(byte[] plaintext)
I found a solution to this issue on another post on this website here.
While this solution does work for me I am wondering why this step is necessary? I know my question may be broad but how would I know by looking at the errors below to add the services.AddDataProtection to the configure services in Startup.cs? I would comment on the question where I found the solution but I do not have enough reputation.
Below is the full text of the errors.
XmlException: '.', hexadecimal value 0x00, is an invalid character. Line 1, position 1.
System.Xml.XmlTextReaderImpl.Throw(Exception e)
System.Xml.XmlTextReaderImpl.Throw(string res, string[] args)
System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
System.Xml.XmlTextReaderImpl.ParseDocumentContent()
System.Xml.XmlTextReaderImpl.Read()
System.Xml.XmlReader.MoveToContent()
System.Xml.Linq.XElement.Load(XmlReader reader, LoadOptions options)
System.Xml.Linq.XElement.Load(Stream stream, LoadOptions options)
System.Xml.Linq.XElement.Load(Stream stream)
Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository.ReadElementFromFile(string fullPath)
Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository.GetAllElementsCore()+MoveNext()
System.Collections.Generic.List<T>..ctor(IEnumerable<T> collection)
System.Linq.Enumerable.ToList<TSource>(IEnumerable<TSource> source)
Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository.GetAllElements()
Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.GetAllKeys()
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.CreateCacheableKeyRingCore(DateTimeOffset now, IKey keyJustAdded)
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.ICacheableKeyRingProvider.GetCacheableKeyRing(DateTimeOffset now)
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.GetCurrentKeyRingCore(DateTime utcNow, bool forceRefresh)
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.GetCurrentKeyRing()
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Protect(byte[] plaintext)
CryptographicException: An error occurred while trying to encrypt the provided data. Refer to the inner exception for more information.
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Protect(byte[] plaintext)
Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Serialize(AntiforgeryToken token)
Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery.Serialize(IAntiforgeryFeature antiforgeryFeature)
Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery.GetAndStoreTokens(HttpContext httpContext)
Microsoft.AspNetCore.Mvc.ViewFeatures.AntiforgeryExtensions.GetHtml(IAntiforgery antiforgery, HttpContext httpContext)
Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateAntiforgery(ViewContext viewContext)
Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper.Process(TagHelperContext context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.TagHelpers.TagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.RunAsync(TagHelperExecutionContext executionContext)
AspNetCore.Views_Students_Edit.ExecuteAsync()
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, bool invokeViewStarts)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ActionContext actionContext, IView view, ViewDataDictionary viewData, ITempDataDictionary tempData, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext context, ViewResult result)
Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|21_0(ResourceInvoker invoker, IActionResult result)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0<TFilter, TFilterAsync>(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Additional code:
controller for edit
// GET: Students/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var student = await _context.Students.FindAsync(id);
if (student == null)
{
return NotFound();
}
return View(student);
}
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ContosoConnectionString")));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(#"c:\temp-keys\"));
services.AddControllersWithViews();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Student model
public class Student
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
SchoolContext
public class SchoolContext : DbContext
{
public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
{
}
public DbSet<Course> Courses { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Student> Students { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
modelBuilder.Entity<Student>().ToTable("Student");
}
}
Thanks

Creating a new comment only works once

I created a method for posting comments on a post. Everything works fine when I first post a comment. It appears under the post, it's saved in the database etc. However, if I want to create a second comment right away (without refreshing the page- because this way it does work) I get this error:
Microsoft.EntityFrameworkCore.Update: Error: An exception occurred in the database while saving changes for context type 'JoyAndFaithLicenta.Data.DataContext'.
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot insert explicit value for identity column in table 'AspNetUsers' when IDENTITY_INSERT is set to OFF.
at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__169_0(Task`1 result)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync
(IRelationalConnection connection, CancellationToken cancellationToken) at
Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at
Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at
Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at
Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(DbContext _, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at
Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at
Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at JoyAndFaithLicenta.Data.UserRepository.SaveAllAsync() in C:\Users\Georgia\source\repos\JoyAndFaithLicenta\JoyAndFaithLicenta\Data\UserRepository.cs:line 84 at JoyAndFaithLicenta.Helpers.LogUserActivity.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) in C:\Users\Georgia\source\repos\JoyAndFaithLicenta\JoyAndFaithLicenta\Helpers\LogUserActivity.cs:line 30 at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker) at
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at JoyAndFaithLicenta.Middleware.ExceptionMiddleware.InvokeAsync(HttpContext context) in C:\Users\Georgia\source\repos\JoyAndFaithLicenta\JoyAndFaithLicenta\Middleware\ExceptionMiddleware.cs:line 33
Why is that? It's the only functionality where I have this problem. However, every other functionality has a SaveAsync() method created in the repository, and I have not created a repository for the comments, so I'm using DataContext: _context.SaveChangesAsync().
This is the method for posting a comment:
[HttpPost("create/{postId}")]
public async Task<ActionResult<CommentDto>> PostComment(CommentDto commentDto, int postId)
{
if (!ModelState.IsValid) return BadRequest("Not a valid model");
var user = await _userRepository.GetUserByUsernameAsync(User.GetUsername());
var comment = new Comment
{
PostId = postId,
UserId = user.Id,
Text = commentDto.Text,
Created = commentDto.Created,
User = commentDto.User
};
_context.Comments.Add(comment);
await _context.SaveChangesAsync();
return new CommentDto
{
PostId = comment.PostId,
UserId = comment.UserId,
Text = comment.Text,
Created = comment.Created,
User = comment.User
};
}
And this is the comment entity:
public class Comment
{
public int Id { get; set; }
public DateTime Created { get; set; } = DateTime.Now;
public string Text { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
public int UserId { get; set; }
[ForeignKey("PostId")]
public Post Post { get; set; }
public int? PostId { get; set; }
}
I can't see your onModelCreating function, but i think it is caused because you have not [Key] in your comment id.
public class Comment
{
[Key]
public int Id { get; set; }
public DateTime Created { get; set; } = DateTime.Now;
public string Text { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
public int UserId { get; set; }
[ForeignKey("PostId")]
public Post Post { get; set; }
public int? PostId { get; set; }
}
Then database will use Id as Key, and you are sure that keys aren't repeated.
Also, i think that you are injected DataContext service wrong.
Try to make the same job like this:
using(var cnx = new DataContext()
{
var comment = new Comment
{
PostId = postId,
UserId = user.Id,
Text = commentDto.Text,
Created = commentDto.Created,
User = commentDto.User
};
cnx.Comments.Add(comment);
await cnx.SaveChangesAsync();
}
If it works, its probplem with your DI in Startup.cs.
Remember, the best way to inject DataContext of EntityFramework is:
services.AddDbContext<DataContext>();
According to below code
var comment = new Comment
{
PostId = postId,
UserId = user.Id,
Text = commentDto.Text,
Created = commentDto.Created,
User = commentDto.User
};
You are trying to insert a new User as well. Since you are trying to create a new user with assigned ID you are getting this error. Because Aspnetuser table does not allow to pass ID explicitly since IDENTITY_INSERT is set to false by default.
I am not sure why you want to insert a user as well along with comment. Probably it can be a requirement. If you really want to create a user, then your User object should not have a assigned ID value.
If this is by mistake change User to UserId.

Many To Many Database with EF Core5 Error

Plaase help!!!: I created 2 entities and added DbSets to ApplicationDbContext.
public class ApplicationUser : IdentityUser
{
public string Adi { get; set; }
public ICollection<Firma> Firmalar {get; set;}
}
public class Firma
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<ApplicationUser> ApplicationUser { get; set; }
}
onPost Method I want to add List to ApplicationUser Table with relation. I can see ApplicationUserFirma table has automatically created
public async Task<IActionResult> OnPostAddFirmaToUser(UserFirmaVM vm, ServisHaritasi.DataService.Models.Firma firma)
{
var dbuser = await _userManager.FindByIdAsync(vm.ApplicationUser.Id);
var dbfirma = await _db.Firmalar.FirstOrDefaultAsync(m => m.Id == firma.Id);
if (dbuser != null && dbfirma != null)
{
dbuser.Firmalar.Add(dbfirma); **///I GET EXCEPTION HERE!!!!!!!!!!!!!!**
await _db.SaveChangesAsync();
return RedirectToPage("./Duzenle", new {id = dbuser.Id});
}
return Page();
}
enter image description here
I assure you there is no null for dbuser and dbfirma. they are coming normally on debug.
Plase help!!!
Stack trace is here:
NullReferenceException: Object reference not set to an instance of an object.
webUI.Pages.Users.DuzenleModel.OnPostAddFirmaToUser(UserFirmaVM vm, Firma firma) in Duzenle.cshtml.cs
+
dbuser.Firmalar.Add(dbfirma);
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+GenericTaskHandlerMethod.Convert<T>(object taskAsObject)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+GenericTaskHandlerMethod.Execute(object receiver, object[] arguments)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Try to use include Firma for ApplicationUser:
public async Task<IActionResult> OnPostAddFirmaToUser(UserFirmaVM vm, ServisHaritasi.DataService.Models.Firma firma)
{
var dbuser = await _db.Set<ApplicationUser>()
.Include(i=>i.Firmalar)
.Where(m => m.Id == vm.ApplicationUser.Id)
.FirstOrDefaultAsync();
var dbfirma = await _db.Firmalar.FirstOrDefaultAsync(m => m.Id == firma.Id);
if (dbuser != null && dbfirma != null)
{
if(dbuser.Firmalar==null) dbuser.Firmalar= new List<Firmalar>();
dbuser.Firmalar.Add(dbfirma);
await _db.SaveChangesAsync();
return RedirectToPage("./Duzenle", new {id = dbuser.Id});
}
return Page();
}
When you are fetching the user as -
var dbuser = await _userManager.FindByIdAsync(vm.ApplicationUser.Id);
the related Firmalar list is not included. So it remains null. Then You are trying to add to this null list -
dbuser.Firmalar.Add(dbfirma);
That's where the issue is.
Try to fetch the user including the Firmalar list, like -
var dbuser = await _db.ApplicationUser
.Include(p=> p.Firmalar)
.FirstOrDefaultAsync(p=> p.Id == vm.ApplicationUser.Id);
That should solve the issue.

How to map JsonPatchDocument using Mapster?

I have my model:
public class Membership
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[MinLength(3)]
[MaxLength(30)]
public string Name { get; set; }
[Required] public int PeriodType { get; set; }
[Required] public int Duration { get; set; }
[Required] public int TerminationPeriod { get; set; }
[Required] public float InstallmentPrice { get; set; }
}
And my Dto:
public class MembershipDto
{
public int Id { get; private set; }
public string Name { get; set; }
public int PeriodType { get; set; }
public int Duration { get; set; }
public int TerminationPeriod { get; set; }
public float InstallmentPrice { get; set; }
}
I'm using Entity Framework and JsonPatchDocument to make PATCH operation in my API, the code is following:
public async Task<MembershipDto> Handle(EditMembershipCommand request, CancellationToken cancellationToken)
{
var membershipEntity = await _dbContext
.Memberships
.SingleOrDefaultAsync(m => m.Id == request.Id);
if (membershipEntity is null)
throw new NullReferenceException($"Membership [Id: {request.Id}] not found");
var editedMembership = request.NewMembershipDto.Adapt<JsonPatchDocument<Membership>>(); //request.NewMembershipDto is type of JsonPatchDocument<MembershipDto>
editedMembership.ApplyTo(membershipEntity, ModelState);
_ = await _dbContext.SaveChangesAsync();
var membershipDto = editedMembership.Adapt<MembershipDto>();
return membershipDto;
}
As an output I get the following information:
ProblemDetails.ProblemDetailsMiddleware[1]
An unhandled exception has occurred while executing the request.
Mapster.CompileException: Error while compiling
source=Microsoft.AspNetCore.JsonPatch.JsonPatchDocument`1[AgreementApi.Dtos.MembershipDto]
destination=Microsoft.AspNetCore.JsonPatch.JsonPatchDocument`1[AgreementApi.Models.Membership]
type=Map
---> Mapster.CompileException: Error while compiling
source=Newtonsoft.Json.Serialization.IContractResolver
destination=Newtonsoft.Json.Serialization.IContractResolver
type=Map
---> System.InvalidOperationException: No default constructor for type 'IContractResolver', please use 'ConstructUsing' or 'MapWith'
at Mapster.Utils.DynamicTypeGenerator.CreateTypeForInterface(Type interfaceType)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Mapster.Utils.DynamicTypeGenerator.GetTypeForInterface(Type interfaceType)
at Mapster.Adapters.RecordTypeAdapter.CreateInstantiationExpression(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateInstantiationExpression(Expression source, CompileArgument arg)
at Mapster.Adapters.RecordTypeAdapter.CreateInlineExpression(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateInlineExpressionBody(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateExpressionBody(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateAdaptFunc(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
--- End of inner exception stack trace ---
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateInlineMapExpression(Type sourceType, Type destinationType, MapType mapType, CompileContext context, MemberMapping mapping)
at Mapster.Adapters.BaseAdapter.CreateAdaptExpressionCore(Expression source, Type destinationType, CompileArgument arg, MemberMapping mapping, Expression destination)
at Mapster.Adapters.BaseAdapter.CreateAdaptExpression(Expression source, Type destinationType, CompileArgument arg, MemberMapping mapping, Expression destination)
at Mapster.Adapters.ClassAdapter.CreateInlineExpression(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateInlineExpressionBody(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateExpressionBody(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateAdaptFunc(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
--- End of inner exception stack trace ---
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateMapExpression(TypeTuple tuple, MapType mapType)
at Mapster.TypeAdapterConfig.CreateDynamicMapExpression(TypeTuple tuple)
at Mapster.TypeAdapterConfig.<GetDynamicMapFunction>b__66_0[TDestination](TypeTuple tuple)
at Mapster.TypeAdapterConfig.<>c__DisplayClass55_0`1.<AddToHash>b__0(TypeTuple types)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Mapster.TypeAdapterConfig.AddToHash[T](ConcurrentDictionary`2 hash, TypeTuple key, Func`2 func)
at Mapster.TypeAdapterConfig.GetDynamicMapFunction[TDestination](Type sourceType)
at Mapster.TypeAdapter.Adapt[TDestination](Object source, TypeAdapterConfig config)
at Mapster.TypeAdapter.Adapt[TDestination](Object source)
at Fitverse.AgreementApi.Handlers.EditMembershipHandler.Handle(EditMembershipCommand request, CancellationToken cancellationToken) in /Users/wonsu/Repositories/Fitverse/Fitverse.AgreementApi/Handlers/EditMembershipHandler.cs:line 34
at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestPostProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestPreProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at Fitverse.AgreementApi.Controllers.SettingsController.EditMembership(Int32 id, JsonPatchDocument`1 membershipDto) in /Users/wonsu/Repositories/Fitverse/Fitverse.AgreementApi/Controllers/SettingsController.cs:line 52
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Hellang.Middleware.ProblemDetails.ProblemDetailsMiddleware.Invoke(HttpContext context)
I know that the issue is in this line of code:
var editedMembership = request.NewMembershipDto.Adapt<JsonPatchDocument<Membership>>();
But I don't know how to change it to properly map it to desired type. Could you help me? :)
I know that at the end I should probably get the membership from DB again, map it and return it instead of just mapping editedMembership, but I'll fit it after dealing with this mapping issue.
Add the mapping of IContractResolver helps resolve the issue.
private static TypeAdapterConfig GetConfiguredMappingConfig()
{
var config = TypeAdapterConfig.GlobalSettings;
IList<IRegister> registers = config.Scan(Assembly.GetExecutingAssembly());
config.Apply(registers);
config.NewConfig<IContractResolver, IContractResolver>()
.ConstructUsing(src => new DefaultContractResolver());
return config;
}

Threading issue when using IViewComponentHelper to convert ViewComponent to HTML string

I'm trying to use IViewComponentHelper in a multi threaded manner. But it's throwing :( (see full exception at bottom of post)
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.AspNetCore.Http.DefaultHttpContext.get_Items()
I have no idea why.
Here's my setup: (simplified for brevity)
Controller:
public async Task<IActionResult> Get()
{
var pdfStream = await _pdfService.GenerateAsync();
return File(pdfStream, "application/pdf");
}
PdfService:
public class PdfService
{
private readonly PdfSDK _pdfSDK;
public constructor(PdfSDK pdfSDK)
{
_pdfSDK = pdfSDK;
}
public async Task<Stream> GenerateAsync()
{
List<Task<PdfDocument>> tasks = await _context.Foos.Select(x => DoWorkAsync(x));
var pdfs = await Task.WhenAll(tasks);
var mergedPdf = _pdfSDK.MergePdfs(pdfs);
return mergedPdf.Stream;
}
private async Task<PdfDocument> DoWorkAsync(Foo foo)
{
var html = await _renderViewComponentService.RenderViewComponentAsStringAsync<MyViewComponent>(foo);
var document = await _pdfSDK.HtmlToDocumentAsync(html);
return document;
}
}
PdfSDK:
public class PdfSDK
{
public async Task<PdfDocument> HtmlToDocumentAsync(string html)
{
using var pdfEngine = new PdfEngine();
var pdf = await pdfEngine.HtmlAsPdfAsync(html);
return pdf;
}
public PdfDocument MergePdfs(params PdfDocument[] pdfs)
{
var pdf = PdfDocument.Merge(pdfs);
return pdf;
}
}
MyViewComponent:
public class MyViewComponent : ViewComponent
{
public IViewComponentResult Invoke(Foo args)
{
return View(args);
}
}
Default.cshtml
#model Foo
<h1>Hello from #Foo.Id<h1>
RenderViewComponentService:
public class RenderViewComponentService
{
private readonly IServiceProvider _serviceProvider;
private readonly ITempDataProvider _tempDataProvider;
private readonly IViewComponentHelper _viewComponentHelper;
public RenderViewComponentService(
IServiceProvider serviceProvider,
ITempDataProvider tempDataProvider,
IViewComponentHelper viewComponentHelper
)
{
_serviceProvider = serviceProvider;
_tempDataProvider = tempDataProvider;
_viewComponentHelper = viewComponentHelper;
}
public async Task<string> RenderViewComponentAsStringAsync<TViewComponent>(object args)
where TViewComponent : ViewComponent
{
var viewContext = GetFakeViewContext();
(_viewComponentHelper as IViewContextAware).Contextualize(viewContext);
// this appears to call InvokeAsync in TViewComponent, but it'll also call Invoke (synchronously) if it's implemented
// see https://learn.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.1#perform-synchronous-work
var htmlContent = await _viewComponentHelper.InvokeAsync<TViewComponent>(args); // exception is thrown here!
using var stringWriter = new StringWriter();
htmlContent.WriteTo(stringWriter, HtmlEncoder.Default);
var html = stringWriter.ToString();
return html;
}
private ViewContext GetFakeViewContext(ActionContext actionContext = null, TextWriter writer = null)
{
actionContext ??= GetFakeActionContext();
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
var tempData = new TempDataDictionary(actionContext.HttpContext, _tempDataProvider);
var viewContext = new ViewContext(
actionContext,
NullView.Instance,
viewData,
tempData,
writer ?? TextWriter.Null,
new HtmlHelperOptions());
return viewContext;
}
private ActionContext GetFakeActionContext()
{
var httpContext = new DefaultHttpContext
{
RequestServices = _serviceProvider,
};
var routeData = new RouteData();
var actionDescriptor = new ActionDescriptor();
return new ActionContext(httpContext, routeData, actionDescriptor);
}
private class NullView : IView
{
public static readonly NullView Instance = new NullView();
public string Path => string.Empty;
public Task RenderAsync(ViewContext context)
{
if (context == null) { throw new ArgumentNullException(nameof(context)); }
return Task.CompletedTask;
}
}
}
Exception:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.AspNetCore.Http.DefaultHttpContext.get_Items()
at Microsoft.AspNetCore.Mvc.Routing.UrlHelperFactory.GetUrlHelper(ActionContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorPageActivator.<>c__DisplayClass4_0.<.ctor>b__0(ViewContext context)
at Microsoft.Extensions.Internal.PropertyActivator`1.Activate(Object instance, TContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorPagePropertyActivator.Activate(Object page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorPageActivator.Activate(IRazorPage page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
at Microsoft.AspNetCore.Mvc.ViewComponents.ViewViewComponentResult.ExecuteAsync(ViewComponentContext context)
at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentInvoker.InvokeAsync(ViewComponentContext context)
at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentHelper.InvokeCoreAsync(ViewComponentDescriptor descriptor, Object arguments)
at MyProject.Services.RenderViewComponentService.RenderViewComponentToStringAsync[TViewComponent](Object args) in MyProject\Services\RenderViewComponentService.cs:line ??
at MyProject.Services.PdfService.DoWorkAsync(Foo foo) in MyProject\Services\PdfService.cs:line ??
at MyProject.Services.PdfService.GenerateAsync() in MyProject\Services\PdfService.cs:line ??
at MyProject.Controllers.MyController.Get() in MyProject\Controllers\MyController.cs:line ??
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker
invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task
lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.HeaderPropagation.HeaderPropagationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
I think the problem is how I Contextualize the IViewComponentHelper. But I'm at a loss on how else to do it.
Can you spot anything I'm doing wrong?

Categories

Resources