{"id":13429595,"url":"https://github.com/CarterCommunity/Carter","last_synced_at":"2025-03-16T03:32:04.681Z","repository":{"id":40523103,"uuid":"87864000","full_name":"CarterCommunity/Carter","owner":"CarterCommunity","description":"Carter is framework that is a thin layer of extension methods and functionality over ASP.NET Core allowing code to be more explicit and most importantly more enjoyable.","archived":false,"fork":false,"pushed_at":"2024-06-06T12:12:43.000Z","size":24272,"stargazers_count":2140,"open_issues_count":7,"forks_count":177,"subscribers_count":49,"default_branch":"main","last_synced_at":"2024-10-29T15:04:41.665Z","etag":null,"topics":["asp-net","asp-net-core","csharp","dotnet-core","middleware","mit-license","nancy"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CarterCommunity.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["jchannon"]}},"created_at":"2017-04-10T22:38:26.000Z","updated_at":"2024-10-28T22:32:58.000Z","dependencies_parsed_at":"2023-09-21T17:13:38.620Z","dependency_job_id":"d2a36822-0274-4771-999b-2958936b813f","html_url":"https://github.com/CarterCommunity/Carter","commit_stats":{"total_commits":341,"total_committers":48,"mean_commits":7.104166666666667,"dds":"0.25513196480938416","last_synced_commit":"d3ff3183041695c16156e40d4797393171da86b5"},"previous_names":["jchannon/botwin"],"tags_count":53,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CarterCommunity%2FCarter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CarterCommunity%2FCarter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CarterCommunity%2FCarter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CarterCommunity%2FCarter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CarterCommunity","download_url":"https://codeload.github.com/CarterCommunity/Carter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243822310,"owners_count":20353496,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asp-net","asp-net-core","csharp","dotnet-core","middleware","mit-license","nancy"],"created_at":"2024-07-31T02:00:42.281Z","updated_at":"2025-03-16T03:32:04.675Z","avatar_url":"https://github.com/CarterCommunity.png","language":"C#","readme":"# Carter\n\nCarter is a framework that is a thin layer of extension methods and functionality over ASP.NET Core allowing the code to be more explicit and most importantly more enjoyable.\n\nFor a better understanding, take a good look at the [samples](https://github.com/CarterCommunity/Carter/tree/master/samples) inside this repo. The samples demonstrate usages of elegant extensions around common ASP.NET Core types as shown below.  \n\nOther extensions include:\n\n* `Validate\u003cT\u003e / ValidateAsync\u003cT\u003e` - [FluentValidation](https://github.com/JeremySkinner/FluentValidation) extensions to validate incoming HTTP requests which is not available with ASP.NET Core Minimal APIs.\n* `BindFile/BindFiles/BindFileAndSave/BindFilesAndSave` - Allows you to easily get access to a file/files that has been uploaded. Alternatively you can call `BindFilesAndSave` and this will save it to a path you specify.\n* Routes to use in common ASP.NET Core middleware e.g., `app.UseExceptionHandler(\"/errorhandler\");`.\n* `IResponseNegotiator`s allow you to define how the response should look on a certain Accept header(content negotiation). Handling JSON is built in the default response but implementing an interface allows the user to choose how they want to represent resources.\n* All interface implementations for Carter components are registered into ASP.NET Core DI automatically. Implement the interface and off you go.\n\n### Releases\n\n* Latest NuGet Release [![NuGet Version](http://img.shields.io/nuget/v/Carter.svg?style=flat)](https://www.nuget.org/packages/carter) \n* Latest NuGet Pre-Release [![NuGet Version](http://img.shields.io/nuget/vpre/Carter.svg?style=flat)](https://www.nuget.org/packages/carter) \n* Lateset CI Release [![feedz.io](https://img.shields.io/badge/endpoint.svg?url=https%3A%2F%2Ff.feedz.io%2Fcarter%2Fcarter%2Fshield%2FCarter%2Flatest)](https://f.feedz.io/carter/carter/packages/Carter/latest/download) \n* Build Status [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FCarterCommunity%2FCarter%2Fbadge%3Fref%3Dmain\u0026style=flat)](https://actions-badge.atrox.dev/CarterCommunity/Carter/goto?ref=main)\n\n### Join our Slack Channel\n\n[![Join our slack channel](https://raw.githubusercontent.com/CarterCommunity/Carter/main/slack.png)](https://join.slack.com/t/cartercommunity/shared_invite/enQtMzY2Nzc0NjU2MTgyLWY3M2Y2Yjk3NzViN2Y3YTQ4ZDA5NWFlMTYxMTIwNDFkMTc5YWEwMDFiOWUyM2Q4ZmY5YmRkODYyYTllZDViMmE)\n\n#### Routing\n\nCarter uses `IEndpointRouteBuilder` routing and all the extensions `IEndpointConventionBuilder` offers also known as Minimal APIs. For example you can define a route with authorization required like so:\n\n```csharp\napp.MapGet(\"/\", () =\u003e \"There's no place like 127.0.0.1\").RequireAuthorization();\n```\n\n\n### Where does the name \"Carter\" come from?\n\nI have been a huge fan of, and core contributor to [Nancy](http://nancyfx.org), the best .NET web framework, for many years, and the name \"Nancy\" came about due to it being inspired from Sinatra the Ruby web framework. Frank Sinatra had a daughter called Nancy and so that's where it came from.\n\nI was also trying to think of a derivative name, and I had recently listened to the song Empire State of Mind where Jay-Z declares he is the new Sinatra. His real name is Shaun Carter so I took Carter and here we are!\n\n### CI Builds\n\nIf you'd like to try the latest builds from the master branch add `https://f.feedz.io/carter/carter/nuget/index.json` to your NuGet.config and pick up the latest and greatest version of Carter.\n\n### Getting Started\n\nYou can get started using either the template or by adding the package manually to a new or existing application.\n\n#### Template\n\n[https://www.nuget.org/packages/CarterTemplate/](https://www.nuget.org/packages/CarterTemplate/)\n\n1. Install the template - `dotnet new install CarterTemplate`\n\n2. Create a new application using template - `dotnet new carter -n MyCarterApp -o MyCarterApp`\n\n3. Go into the new directory created for the application `cd MyCarterApp`\n\n4. Run the application - `dotnet run`\n\n#### Package\n\n[https://www.nuget.org/packages/Carter](https://www.nuget.org/packages/Carter)\n\n1. Create a new empty ASP.NET Core application - `dotnet new web -n MyCarterApp`\n\n2. Change into the new project location - `cd ./MyCarterApp`\n\n3. Add Carter package - `dotnet add package carter`\n\n4. Modify your Program.cs to use Carter\n\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.Services.AddCarter();\n\nvar app = builder.Build();\n\napp.MapCarter();\napp.Run();\n```\n\n5. Create a new Module\n\n```csharp\n    public class HomeModule : ICarterModule\n    {\n        public void AddRoutes(IEndpointRouteBuilder app)\n        {\n            app.MapGet(\"/\", () =\u003e \"Hello from Carter!\");\n        }\n    }\n```\n\n6. Run the application - `dotnet run`\n\n### Sample\n\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.Services.AddSingleton\u003cIActorProvider, ActorProvider\u003e();\nbuilder.Services.AddCarter();\n\nvar app = builder.Build();\n\napp.MapCarter();\napp.Run();\n\npublic class HomeModule : ICarterModule\n{\n    public void AddRoutes(IEndpointRouteBuilder app)\n    {\n        app.MapGet(\"/\", () =\u003e \"Hello from Carter!\");\n        app.MapGet(\"/qs\", (HttpRequest req) =\u003e\n        {\n            var ids = req.Query.AsMultiple\u003cint\u003e(\"ids\");\n            return $\"It's {string.Join(\",\", ids)}\";\n        });\n        app.MapGet(\"/conneg\", (HttpResponse res) =\u003e res.Negotiate(new { Name = \"Dave\" }));\n        app.MapPost(\"/validation\", HandlePost);\n    }\n\n    private IResult HandlePost(HttpContext ctx, Person person, IDatabase database)\n    {\n        var result = ctx.Request.Validate(person);\n\n        if (!result.IsValid)\n        {\n            return Results.UnprocessableEntity(result.GetFormattedErrors());\n        }\n\n        var id = database.StorePerson(person);\n\n        ctx.Response.Headers.Location = $\"/{id}\";\n        return Results.StatusCode(201);\n    }\n}\n\npublic record Person(string Name);\n\npublic interface IDatabase\n{\n    int StorePerson(Person person);\n}\n\npublic class Database : IDatabase\n{\n    public int StorePerson(Person person)\n    {\n        //db stuff\n    }\n}\n```\n\n[More samples](https://github.com/CarterCommunity/Carter/tree/master/samples)\n\n### Configuration\n\nAs mentioned earlier Carter will scan for implementations in your app and register them for DI. However, if you want a more controlled app, Carter comes with a `CarterConfigurator` that allows you to register modules, validators and response negotiators manually.\n\nCarter will use a response negotiator based on `System.Text.Json`, though it provides for custom implementations via the `IResponseNegotiator` interface. To use your own implementation of `IResponseNegotiator` (say, `CustomResponseNegotiator`), add the following line to the initial Carter configuration, in this case as part of `Program.cs`:\n\n```csharp\n\n    builder.Services.AddCarter(configurator: c =\u003e\n    {\n        c.WithResponseNegotiator\u003cCustomResponseNegotiator\u003e();\n        c.WithModule\u003cMyModule\u003e();\n        c.WithValidator\u003cTestModelValidator\u003e()\n    });\n\n```\n\nHere again, Carter already ships with a response negotiator using `Newtonsoft.Json`, so you can wire up the Newtonsoft implementation with the following line:\n\n```csharp\n    builder.Services.AddCarter(configurator: c =\u003e\n    {\n        c.WithResponseNegotiator\u003cNewtonsoftJsonResponseNegotiator\u003e();\n    });\n```\n","funding_links":["https://github.com/sponsors/jchannon"],"categories":["Frameworks, Libraries and Tools","C\\#","csharp","C# #","C#","框架, 库和工具","Application Frameworks"],"sub_categories":["Application Frameworks","应用程序框架"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCarterCommunity%2FCarter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FCarterCommunity%2FCarter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCarterCommunity%2FCarter/lists"}