dotnet / eshop Goto Github PK
View Code? Open in Web Editor NEWA reference .NET application implementing an eCommerce site
License: MIT License
A reference .NET application implementing an eCommerce site
License: MIT License
From @bricelam
Today, database schema migrations are applied as certain components start up. This is problematic when multiple components (or multiple instances of the same component) use the same database.
Currently, for example, Ordering.BackgroundTasks immediately begins querying the OrderingDB database. This continually fails while waiting for Ordering.API to create and migrate the database schema to the latest version.
Data seeding (#10) should also be done at the same time.
Current implementation of eShop.Ordering.Infrastructure.MediatorExtension.DispatchDomainEventsAsync
will check tracked entities and publish all domain event those entices hold once, which triggers domain event handlers to handle published events.
However, in real world applications, domain event handlers might also cause new domain events generated, and in current implementation new created domain events will be ignored.
I wrote this implementation that will keep publishing created domain events from tracked entires recursively, utill there are no more left. Please consider.
static class MediatorExtension
{
public static async Task DispatchDomainEventsAsync(this IMediator mediator, OrderingContext ctx)
{
bool remains = true;
while(remains) {
var publishedCount = await DispatchDomainEventsRecursivelyAsync(mediator, ctx);
remains = publishedCount > 0;
}
}
private static async Task<int> DispatchDomainEventsRecursivelyAsync(this IMediator mediator, OrderingContext ctx)
{
var domainEntities = ctx.ChangeTracker
.Entries<Entity>()
.Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any());
var domainEvents = domainEntities
.SelectMany(x => x.Entity.DomainEvents)
.ToList();
int count = domainEvents.Count;
domainEntities.ToList()
.ForEach(entity => entity.Entity.ClearDomainEvents());
foreach (var domainEvent in domainEvents)
await mediator.Publish(domainEvent);
return count;
}
}
Would be happy to create the PR.
INSTALL STEPS
REPRO STEPS
ACTUAL
The black area is too small, resulting in poor readability of the number of shopping bags.
EXPECTED
From @bricelam:
It is the professional opinion of the EF team that the DDD patterns employed in the Ordering.API and related projects are of no value (and possibly even result in negative value) and can safely be removed for the sake of maintainability.
This includes, but is not limited to:
IdentityGuid
as the primary key (instead of the current surrogate key) for BuyerINSTALL STEPS
REPRO STEPS
ACTUAL
fail: Aspire.Hosting.Dcp.dcpctrl.ExecutableReconciler[0]
could not remove process's standard output file {"Controller": "usvc-dev.developer.microsoft.com/executable-reconciler", "Executable": {"name":"identity-api"}, "Reconciliation": 72, "State": "Running", "ExecutionID": "61", "path": "C:\Users\xxx\AppData\Local\Temp\identity-api_out_80dce640-5654-4d08-abc6-435287cc0eed", "error": "remove C:\Users\xxx\AppData\Local\Temp\identity-api_out_80dce640-5654-4d08-abc6-435287cc0eed: The process cannot access the file because it is being used by another process."}
EXPECTED
There are no errors in Debug Console.
REPRO STEPS
ACTUAL
It includes both http and https launch profiles
EXPECTED
It should only include the http launch profile. We don't have full support for the https profile yet.
INSTALL STEPS
REPRO STEPS
ACTUAL
Fatal error establishing database connection
An error occurred using the connection to database 'postgres' on server 'tcp://localhost:56882'.
EXPECTED
There are no errors in Structured Logs.
INSTALL STEPS
REPRO STEPS
dotnet run --project src/eShop.AppHost/eShop.AppHost.csproj
Building...
/.nuget/packages/grpc.tools/2.59.0/build/_protobuf/Google.Protobuf.Tools.targets(291,5): error MSB6003: The specified task executable "/.nuget/packages/grpc.tools/2.59.0/tools/macosx_x64/protoc" could not be run. System.ComponentModel.Win32Exception (13): An error occurred trying to start process '/.nuget/packages/grpc.tools/2.59.0/tools/macosx_x64/protoc' with working directory '/data/eShop/src/Basket.API'. Permission denied [/data/eShop/src/Basket.API/Basket.API.csproj]
/.nuget/packages/grpc.tools/2.59.0/build/_protobuf/Google.Protobuf.Tools.targets(291,5): error MSB6003: at System.Diagnostics.Process.ForkAndExecProcess(ProcessStartInfo startInfo, String resolvedFilename, String[] argv, String[] envp, String cwd, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean usesTerminal, Boolean throwOnNoExec) [/data/eShop/src/Basket.API/Basket.API.csproj]
/.nuget/packages/grpc.tools/2.59.0/build/_protobuf/Google.Protobuf.Tools.targets(291,5): error MSB6003: at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo) [/data/eShop/src/Basket.API/Basket.API.csproj]
/.nuget/packages/grpc.tools/2.59.0/build/_protobuf/Google.Protobuf.Tools.targets(291,5): error MSB6003: at Microsoft.Build.Utilities.ToolTask.ExecuteTool(String pathToTool, String responseFileCommands, String commandLineCommands) [/data/eShop/src/Basket.API/Basket.API.csproj]
/.nuget/packages/grpc.tools/2.59.0/build/_protobuf/Google.Protobuf.Tools.targets(291,5): error MSB6003: at Microsoft.Build.Utilities.ToolTask.Execute() [/data/eShop/src/Basket.API/Basket.API.csproj]
/.nuget/packages/grpc.tools/2.59.0/build/_protobuf/Google.Protobuf.Tools.targets(291,5): error MSB6003: The specified task executable "/.nuget/packages/grpc.tools/2.59.0/tools/macosx_x64/protoc" could not be run. System.ComponentModel.Win32Exception (13): An error occurred trying to start process '/.nuget/packages/grpc.tools/2.59.0/tools/macosx_x64/protoc' with working directory '/data/eShop/src/WebApp'. Permission denied [/data/eShop/src/WebApp/WebApp.csproj]
/.nuget/packages/grpc.tools/2.59.0/build/_protobuf/Google.Protobuf.Tools.targets(291,5): error MSB6003: at System.Diagnostics.Process.ForkAndExecProcess(ProcessStartInfo startInfo, String resolvedFilename, String[] argv, String[] envp, String cwd, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean usesTerminal, Boolean throwOnNoExec) [/data/eShop/src/WebApp/WebApp.csproj]
/.nuget/packages/grpc.tools/2.59.0/build/_protobuf/Google.Protobuf.Tools.targets(291,5): error MSB6003: at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo) [/data/eShop/src/WebApp/WebApp.csproj]
/.nuget/packages/grpc.tools/2.59.0/build/_protobuf/Google.Protobuf.Tools.targets(291,5): error MSB6003: at Microsoft.Build.Utilities.ToolTask.ExecuteTool(String pathToTool, String responseFileCommands, String commandLineCommands) [/data/eShop/src/WebApp/WebApp.csproj]
/.nuget/packages/grpc.tools/2.59.0/build/_protobuf/Google.Protobuf.Tools.targets(291,5): error MSB6003: at Microsoft.Build.Utilities.ToolTask.Execute() [/data/eShop/src/WebApp/WebApp.csproj]
The build failed. Fix the build errors and run again.
From @davidfowl:
The grpc service should require authentication (it seems like one method has allow anonymous)
Clicking on the Northern Mountains logo from any page should take you back home. It currently doesn't do that at the login page.
Would be interesting to see how much traffic we can handle with this architecture and where things start to break down.
@SrushtiPasari94 Assigning this to you as the tests in Catalog.FunctionalTests are runnable now. Can you use the tests I currently added as a template to add tests for the other endpoints in the app? Let me know if you run into any issues!
I installed the latest version of .net and tried to run this application, but it requires a preview version of .NET 8
To solve this, I changed global.json and chose version 8.0.100
Here's the global.json file
{
"sdk": {
"version": "8.0.100",
"rollForward": "latestPatch",
"allowPrerelease": false
}
}
INSTALL STEPS
REPRO STEPS
ACTUAL
Unexpected connection closure: AMQP close-reason, initiated by Library, code=0, text='End of stream', classId=0, methodId=0, cause=System.IO.EndOfStreamException: Reached the end of the stream. Possible authentication failure.
at RabbitMQ.Client.Impl.InboundFrame.ReadFrom(Stream reader, Byte[] frameHeaderBuffer, ArrayPool`1 pool, UInt32 maxMessageSize)
at RabbitMQ.Client.Impl.SocketFrameHandler.ReadFrame()
at RabbitMQ.Client.Framing.Impl.Connection.MainLoopIteration()
at RabbitMQ.Client.Framing.Impl.Connection.MainLoop()
EXPECTED
There are no errors in Structured Logs.
From @SteveSandersonMS
I'm not sure how to repro this but have seen it twice now. You can have a state where the user is logged in and has a non-expired auth token, so WebApp shows you as being logged in, but:
basketClient.GetBasketAsync
succeedbasketClient.UpdateBasketAsync
fail, reporting RpcException: Status(StatusCode="Unauthenticated", Detail="The caller is not authenticated.")
You can get out of this state by logging out and then back in. But of course we don't want this to occur in the first place.
I suspect the issue is one of two things:
Here's what shows up to the user when trying to add an item to the cart in this state:
From @danroth27
The web app is hosted on an HTTPS address, but it displays images that are retrieved over plain HTTP, which results in lots of "Mixed content" warnings in the browser dev console.
From @ReubenBond:
Currently, each project which needs a representation of an Order has its own representation. This makes refactoring complex and it leads to inconsistencies. Instead, we should have one or more shared projects which define the domain model.
If we see a benefit to having a mapped type in some cases (eg, types used in Blazor view models), we should do so, but we should simplify where we can.
From @ReubenBond:
Currently, there are many integration events which have duplicated representations across projects, which makes the complex Order processing flow even more complex because developers cannot use tooling to find usages of the integration event types.
Instead, let's use one or more shared projects to describe these events so that FindAllReferences/etc work.
From @danroth27:
When I ran the app on a new machine the catalog search tags didn't render with the right font. I had to manually install the Open Sans font family.
INSTALL STEPS
REPRO STEPS
ACTUAL
Error 400 (Bad Request) when calling the Webhooks API (POST http://webhooks-api/api/v1/webhooks) with GrantUrl: http://localhost:5228/check)
Data sent to the webhooks API was {"Url":"http://localhost:5228/webhook-received","Token":"6168DB8D-DC58-4094-AF24-483278923590","Event":"OrderPaid","GrantUrl":"http://localhost:5228/check"}
EXPECTED
Registering a new webhook in eshop dashboard successfully.
From @danroth27
The web app configures the exception handling middleware to route requests to /Error:
if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/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(); }But no /Error endpoint is defined in the app.
From @danroth27:
We should pick a consistent name for the shopping cart/bag/basket.
Currently we have Basket.API, Cart.razor, and user facing text that says, "Your shopping bag".
From @SteveSandersonMS:
The user-facing text is all consistent on "shopping bag".
In the code, WebApp uses the term Cart, and the underlying service uses the term Basket. So those are indeed inconsistent, but in a way that is sort of valid - nothing strictly requires them to use the same term even though it would be better if they did.
From @danroth27:
Repro steps:
Expected result: Products are rendered the same size as when there are three or more products
Actual result: Products are rendered smaller when there are less than three products shown
From @captainsafia:
Why can't these be records with primary constructors?
@davidfowl thinks they should be but we just need to test the entire flow.
From @davidfowl
Clean up all of the extraneous content, the extra content globs etc.
Databases are currently seeded with data from CSVs and in-memory data. We should just do it in-memory.
Hi @davidfowl ,
I was walking through the Catalog.API code. In this file https://github.com/dotnet/eShop/blob/main/src/Catalog.API/Apis/CatalogApi.cs I see a usage of [AsParameters] CatalogServices services
as a second parameter in all methods. I'm at loss to understand where CatalogServices is getting constructed. It is neither created in DI nor coming as a param. Can you please clarify?
Payment.API -> PaymentProcessor
Ordering.BackgroundTasks -> OrderProcessor
We need to do an accessibility pass. @3lcarry will be handling this.
A couple of known issues:
Every online store I've used allows anonymously adding items to a shopping cart and then prompts for login during check out. Unusually, eshop requires logging in before adding items to the cart. I think the demo should follow the usual rules for websites.
Was this done for technical reasons? i.e. tracking cart items against an account, or to show off requiring auth in the cart APIs
First!
There are lots of applications in there that no longer use auth or have been deleted.
Right now the .NET MAUI app only uses fake mock data. This needs to be updated to use the new endpoints.
Working with @michaelstonis
few error when load the project. try to acces nuget seem not authorise.
other error Assets file 'C:\Users\User\Downloads\eShop-main\src\EventBusRabbitMQ\obj\project.assets.json' not found. Run a NuGet package restore to generate this file.
EventBusRabbitMQ C:\Program Files\dotnet\sdk\8.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets 266
We want to remove the scanning so we can potentially AOT more of eshop.
cc @davidfowl
Include what tech was used and that we're able to use it.
INSTALL STEPS
REPRO STEPS
ACTUAL
Sorry, there was an error: invalid_request
Invalid redirect_uri
EXPECTED
Login successful.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.