Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 29 2019 22:35
    HeyJoel closed #294
  • Jan 29 2019 22:35
    HeyJoel commented #294
  • Jan 24 2019 12:13
    HeyJoel closed #297
  • Jan 24 2019 12:13
    HeyJoel commented #297
  • Jan 24 2019 12:11
    HeyJoel commented #296
  • Jan 24 2019 10:58
    HeyJoel milestoned #296
  • Jan 24 2019 10:58
    HeyJoel labeled #296
  • Jan 23 2019 11:24
    ernestoSerra commented #296
  • Jan 22 2019 21:44
    HeyJoel commented #150
  • Jan 22 2019 16:46
    j7rowan commented #150
  • Jan 21 2019 12:28
    HeyJoel commented #297
  • Jan 21 2019 12:28
    HeyJoel commented #297
  • Jan 21 2019 12:08
    Enlatic commented #297
  • Jan 21 2019 12:03
    HeyJoel commented #294
  • Jan 21 2019 11:55
    HeyJoel commented #297
  • Jan 21 2019 11:55
    Enlatic commented #297
  • Jan 21 2019 11:49
    HeyJoel commented #297
  • Jan 21 2019 11:47
    Enlatic edited #297
  • Jan 21 2019 11:46
    Enlatic edited #297
  • Jan 21 2019 11:45
    HeyJoel commented #296
Joel Mitchell
@HeyJoel
Great!
Richard Garside
@NogginBox

Cofoundry is an unobtrusive ASP.NET Core CMS focused on code-first development and user-friendly content management. Run integrated, decoupled or headless, it's your choice.

Is there any documentation on how to use as a headless CMS? I've found this sample so far, but no docs on it.

https://github.com/cofoundry-cms/Cofoundry.Samples.SPASite

Richard Garside
@NogginBox
We have an existing web app that we'd like to add some CMS content pages to. Thought that using a headless CMS would be ideal for this.
We'd create a standalone web app using the CMS to manage the content and then our existing app would use the CMS API to pull in content on the pages where it was required.
Is this something that Cofoundry can do?
I'm struggling to get my head round the CMS API and I've not found the SPA sample as helpful as I'd hoped it would be.
Joel Mitchell
@HeyJoel
That sample is about as close as you’d find. It’s up to you to take the data Api surface and expose it as you like, so it’s more lower level than you’re probably expecting, but gives you more control over how your api is designed. The next release has a more straightforward Api abstraction that will make it easier to work with with more discoverable data api surface.
Richard Garside
@NogginBox
Thanks @HeyJoel
Michal Grzegorzak
@MichalGrzegorzak
Any tips how to replace TinyMCE with own custom editor?
Joel Mitchell
@HeyJoel
There’s no documentation on how to do that although it is possible. You’d basically be making a new .net annotation and angular component rather than overriding the existing one. The best example might be to look at the Vimeo and youtube video plugins.
It’s not straightforward so you’d have to be feeling adventurous to give it a go.
Stefan Moonen
@Qonstrukt

@HeyJoel, have you been running Cofoundry on ASP.NET Core 3.1 for a while now? We've been running a staging environment but at some point between 24 and 96 hours our application is depleting it's SQL connection pool it seem with this error message:

System.InvalidOperationException: Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.
    at Microsoft.Data.Common.ADP.ExceptionWithStackTrace(Exception e)
 --- End of stack trace from previous location where exception was thrown ---
    at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
    at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
    at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
    at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(DbContext _, Boolean result, 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.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()

This also happens with an application that's not really being used, and it didn't before on .NET Core 2.2. Any clues?

Joel Mitchell
@HeyJoel
It’s not something I’ve seen before, are those periodic errors or does it just shutdown completely?
Stefan Moonen
@Qonstrukt
It stops working until at some point the connection pool seems to free up in itself. Although I'n not 100% sure yet. I'm investigating whether I should auto-restart these pods or that they recover by themselves. On the plus side, I do have the distributed Redis cache working, so I can now run multiple copies of that site successfully. :wink:
The problem was already there with the InMemory cache though.
Joel Mitchell
@HeyJoel
I’m guessing there’s not much traffic to the staging sites so that is odd. Are you seeing the exeption from logs? Is there any more to the stack trace? Im wondering if there’s any pattern to what code is triggering those errors, i just see ef code
Stefan Moonen
@Qonstrukt
Thought I'd ask you because we're not really touching EF ourselves, and just using the Cofoundry supplied helper methods.
But I don't think it's gonna help much since it happens whenever the connection pool is exhausted, so it happens in a lot of different instances.
Joel Mitchell
@HeyJoel
Some extra questions so I can rule a few things out:
  1. Are you seeing this using the logs in the ErrorLogging plugin?
  2. Are you using any other data access other than Cofoundry? (I expect EF uses the same underlying ADO connection pool)
  3. Are yo using the Hangfire background tasks plugin?
  4. How much traffic are you experiencing? Roughly - e.g. a couple of test users
Also, what platform / db are you using - sounds like K8s / linux?
Stefan Moonen
@Qonstrukt
  1. No, this Is console output, because it also fails to save logs to the database at this stage.
  2. No, the only other connections we make is to some Azure services and a Redis cluster.
  3. No
  4. It's staging, so hardly any traffic besides a health check every 5 seconds
Yes, it's K8s/Linux with the latest Microsoft-supplied ASP.NET Core 3.1 images. Hosted Azure SQL Server basic instance.
Stefan Moonen
@Qonstrukt
Should I try changing the Max Pool Size in the connection string maybe? What is the DbContext set to for Cofoundry?
Joel Mitchell
@HeyJoel
It will use the default which should be more than enough. I don't think anything much changed in the 3.1 migration from our perspective, but there's always big under-the-cover changes in EF and ASP.NET that might impact something. It will probably be a while for me to look into this one.
Stefan Moonen
@Qonstrukt
Yeah I figured, if you are running 3.1 instances yourself without these issues it might also be related to my own code still of course.
Joel Mitchell
@HeyJoel
Well, the ErrorLogging plugin is much neglected and if it's only picked up in logging I probably won't have seen it if it has occured. I'll need to have a dig around. Is it a recurring issues for you? If it was a one-off Azure-wobble you might see connection timeouts that could lead to pool exhaution.
Stefan Moonen
@Qonstrukt
Yes it's a consistent issue. I have one pod stuck in this state now. I'm waiting to see if it will recover by itself. The console output keeps spamming these errors for now.
Stefan Moonen
@Qonstrukt
I updated the gist with a full request log: https://gist.github.com/Qonstrukt/419d67f5b0bc8582b26dcf3e0501ff6c
You can see the Cofoundry.Plugins.ErrorLogging.Data.ErrorLoggingDbContext throwing the error, but that might be very well caused by something else first throwing the error. The fact that it uses a different DB context is interesting though.
Joel Mitchell
@HeyJoel
hmm, perhaps it's getting stuck with logging a lot of errors
Can you take out the error logging package?
Stefan Moonen
@Qonstrukt
Sure
Joel Mitchell
@HeyJoel
It's not great because it literally logs every error to the db and so it can easily get overloaded - it's on the (long) list of things to be sorted. It's better to set up production-grade logging using the .NET core error logger and other 3rd party tools.
Stefan Moonen
@Qonstrukt
Yeah, that's why I figured it's not a real problem to get rid of it. We have Loki and Grafana running, so I could just grab logs from the container output and process it from there.
Joel Mitchell
@HeyJoel
I suspect you might find that fixes that error (and exposes a new one), but if not, this article seems to have some good info on tracking down issues with connectons https://sqlperformance.com/2017/07/sql-performance/find-database-connection-leaks
Stefan Moonen
@Qonstrukt
Hmm, yeah I'm not able to look into those sys tables though it seems with an Azure hosted Sql Server.
Joel Mitchell
@HeyJoel
Ah ok. I wasn't seeing any issues when I ran it on one of our production sites with a reasonable amount of traffic, but the site isn't using the CMS parts of Cofoundry much.
Scott Remiger
@scottremigeraccuweather
I want to create a link to a page that may not exists so for example. I have a Product called WidgetA The users want to promote this product so they would create a custom page that is specific to that product. How would I check that the custom product page exists if so render that page otherwise, render a default page? Ideally, both would be manageable within the Pages area of the admin so the user can add a Header and Footer section to the default, but the contents would be rendered based on the product for the default page, whereas the custom page is the custom all the way and no Page-level model would be needed. I think it is here https://www.cofoundry.org/docs/content-management/custom-entity-pages but not understanding this vs Page and Page Types.
Joel Mitchell
@HeyJoel
@scottremigeraccuweather hi there, are you asking about redering an html link if a page exists? Or are you asking about a default page (404) if the product exists i.e. if a user navigates to /products/widget-a then a custom 404 would show? Or is it something else?
Scott Remiger
@scottremigeraccuweather
What I have is a situation where Widget-A will have a customized page with custom content and Widget-B, we just do not want to setup a custom page for Widget B and instead use values from a database and a default page template. So Widget-A would have a Page and Widget-B to Widget -Z would use the Page that is marked default.
Joel Mitchell
@HeyJoel
So, if I understand correctly, Widget A can be a normal custom (non CMS) page? CMS routing kicks in last in the pipeline, so you should be able to register a normal MVC route for that if you don't need any CMS content. The other pages you can handle as normal with a custom entity page (as you referenced earlier).
Bailey Ammons
@bammons
Hello there, is there anyway to get the default mailing to call an api service? For example when I add a user on the admin side I would like to be able to make an api call with the generated template. Or is there some way to intercept that mailing process when new users are added?
Joel Mitchell
@HeyJoel
You can make your own mail service integration. Take a look at the SendGrid plugin to see how that’s done.
Bailey Ammons
@bammons
Thanks, that was the trick
Oliver Smit
@technical2cents
Hi there Guys. I picked up a small issue inthe pagetemplate handler. the class GetPageTemplateDetailsByIdQueryHandler line 58 .GroupBy(v => v.PageId) , this causes an issue when querying metadata for pagetemplates and the line can be removed to solve the problem as there should be no group by on a non aggregate field., thought I would just share.
Eithere then that, enjoying your work :)
Joel Mitchell
@HeyJoel

Thanks @technical2cents for letting us know. The group by is required for the correct stats, but EF doesn't work well with GroupBy anymore. The fixed query should be:

queryModel.NumPages = await _dbContext
    .PageVersions
    .AsNoTracking()
    .Where(v => v.PageTemplateId == query.PageTemplateId)
    .Select(v => v.Page)
    .Distinct()
    .CountAsync();

I've committed the fix, thank you!

Oliver Smit
@technical2cents
Excellent. Thanks Joel.
Adam Yang
@adamy
Hi guys, has anyone successfully ran the ASP.NET identity alongside the Cofoundry v0.7 in .NET core 3.1? First the authentication urls don't load, I fixed it by add "routeBuilder.MapRazorPages();" in my RouteRegistration. Second, after I got the login screen, the user/password works, but I got redicted back to an unauthorised page after a successful login. Removed the Cofoundry pipeline and all back to work normally.
Joel Mitchell
@HeyJoel
Presumably there’s a reason you’re not using the Cofoundry user areas i.e. you’re running another application alongside Cofoundry? There’s no guidance here, but you’d probably need to override the Cofoundry auth startup task and modify it to your needs. I don’t have my laptop to hand so can’t look it up.
I was looking at making this area more configurable earlier in the year, so some feedback on your use-case would be helpful.
Adam Yang
@adamy
@HeyJoel Thanks. I am trying to add Cofoundry to an in-house ecommerce site that already has .Net core Identity for customers and admins. It is probably too hard to migrate my users to Cofoundry as there are too many changes. My client wants to be able to edit some contents on the site and create news items and updates. I like how Cofoundry works and it is relatively small footprint (compare with Orchard Core or Piranha). Ideally I would like all .Net core Identity users in "Admins" role can access the CMS admin portal and can do everything they want, but I can live with a seperate login system for CMS.
Joel Mitchell
@HeyJoel
@adamy that makes sense, it doesn't seem that uncommon to want to run a CMS alongside another application and it's something that's possible, but it's not straightforward. First off, I'm not very familiar with Identity, and it's been redesigned a few times since I last used it, so I can't help you too much on that part.