├── .gitattributes ├── .gitignore ├── Images ├── AspnetCoreodata80_debug1.png ├── AspnetCoreodata80_debug2.png ├── ConfigurationBuilder.png ├── ConfigurationInterface1.png ├── ConfigurationInterface2.png ├── ConfigurationProvider.png ├── IConfigurationProvider.png ├── api_versioning_swagger.png └── readme.md ├── README.md ├── docs ├── Asp.Net program startup investigation.md ├── AspNetCore.md └── Configuration │ ├── ConfiguartionPath.md │ ├── Configuration Interfaces.md │ ├── ConfigurationBuilder.md │ ├── ConfigurationProvider.md │ └── ConfigurationSource.md ├── sln └── AspNetCore │ └── AspNetCore.sln ├── src ├── AspNetClassic.Geography │ ├── AspNetClassic.Geography.sln │ ├── AspNetClassic.Geography │ │ ├── App_Start │ │ │ └── WebApiConfig.cs │ │ ├── AspNetClassic.Geography.csproj │ │ ├── Controllers │ │ │ ├── CustomersController.cs │ │ │ └── ValuesController.cs │ │ ├── Extensions │ │ │ ├── GeographConvert.cs │ │ │ └── GeographyWrapper.cs │ │ ├── Global.asax │ │ ├── Global.asax.cs │ │ ├── Models │ │ │ ├── Customer.cs │ │ │ ├── CustomerGeoContext.cs │ │ │ └── EdmModelBuilder.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Web.Debug.config │ │ ├── Web.Release.config │ │ ├── Web.config │ │ └── packages.config │ └── readme.md ├── AttributeRouting80Rc │ ├── AttributeRouting80Rc.sln │ └── AttributeRouting80Rc │ │ ├── AttributeRouting80Rc.csproj │ │ ├── Controllers │ │ ├── HandAbolusteController.cs │ │ ├── HandBookController.cs │ │ ├── HandCustomerController.cs │ │ ├── HandleMultipleController.cs │ │ ├── HandleOthersController.cs │ │ ├── ODataEndpointController.cs │ │ └── WeatherForecastController.cs │ │ ├── Models │ │ ├── Address.cs │ │ ├── BookAndPress.cs │ │ ├── BookStoreContext.cs │ │ ├── CustomerAndOrder.cs │ │ ├── CustomerOrderContext.cs │ │ ├── DataSource.cs │ │ └── EdmModelBuilder.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json ├── BookStore │ ├── BookStore.sln │ └── BookStore │ │ ├── BookStore.csproj │ │ ├── Controllers │ │ ├── BooksController.cs │ │ └── PressesController.cs │ │ ├── Models │ │ ├── Address.cs │ │ ├── Book.cs │ │ ├── BookStoreContext.cs │ │ ├── Category.cs │ │ ├── DataSource.cs │ │ └── Press.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json ├── BookStoreAspNetCoreOData8Preview │ ├── BookStoreAspNetCoreOData8Preview.sln │ ├── BookStoreAspNetCoreOData8Preview │ │ ├── BookStoreAspNetCoreOData8Preview.csproj │ │ ├── Controllers │ │ │ ├── BooksController.cs │ │ │ ├── PressesController.cs │ │ │ └── WeatherForecastController.cs │ │ ├── Models │ │ │ ├── Address.cs │ │ │ ├── Book.cs │ │ │ ├── BookStoreContext.cs │ │ │ ├── Category.cs │ │ │ ├── DataSource.cs │ │ │ └── Press.cs │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ └── README.md ├── BookStoreDotNet5 │ ├── BookStore.sln │ └── BookStore │ │ ├── BookStore.csproj │ │ ├── Controllers │ │ ├── BooksController.cs │ │ └── PressesController.cs │ │ ├── Models │ │ ├── Address.cs │ │ ├── Book.cs │ │ ├── BookStoreContext.cs │ │ ├── Category.cs │ │ ├── DataSource.cs │ │ └── Press.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json ├── DependencyInjection │ └── DependencyInjectionTest │ │ ├── DependencyInjectionTest.sln │ │ ├── Readme.md │ │ ├── global.json │ │ └── src │ │ └── DependencyInjectionTest │ │ ├── ConstructorDependencyTest.cs │ │ ├── DependencyInjectionTest.xproj │ │ ├── DependencyInjectionTest.xproj.user │ │ ├── Program.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ └── project.json ├── EFCore │ ├── EFCoreConsole │ │ ├── Data │ │ │ └── MachineContext.cs │ │ ├── EFCoreConsole.csproj │ │ ├── Migrations │ │ │ ├── 20180614230649_EFCoreConsole.Data.MachineContext.Designer.cs │ │ │ ├── 20180614230649_EFCoreConsole.Data.MachineContext.cs │ │ │ └── MachineContextModelSnapshot.cs │ │ ├── Models │ │ │ ├── Machine.cs │ │ │ ├── MachineType.cs │ │ │ ├── MachineWarranty.cs │ │ │ ├── OperatingSys.cs │ │ │ ├── SupportLong.cs │ │ │ ├── SupportTicket.cs │ │ │ └── WarrantyProvider.cs │ │ └── Program.cs │ └── EFCoreLinqTest │ │ ├── EFCoreLinqTest.sln │ │ └── EFCoreLinqTest │ │ ├── EFCoreLinqTest.csproj │ │ └── Program.cs ├── FilterExtensionFor801 │ ├── FilterExtensionFor801.sln │ └── FilterExtensionFor801 │ │ ├── Controllers │ │ ├── CustomersController.cs │ │ └── WeatherForecastController.cs │ │ ├── FilterExtensionFor801.csproj │ │ ├── Models │ │ ├── Customer.cs │ │ ├── CustomerMetadata.cs │ │ ├── EdmModelBuilder.cs │ │ ├── FilterDbContext.cs │ │ └── MetadataWrapper.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json ├── IoCTest │ ├── IoCTest.sln │ └── IoCTest │ │ ├── Cat.cs │ │ ├── CatExtensions.cs │ │ ├── InjectionAttribute.cs │ │ ├── IoCTest.csproj │ │ ├── Program.cs │ │ ├── ServiceRegistry.cs │ │ ├── SimpleCat.cs │ │ └── SimpleCatTests.cs ├── ModelBuilderTest │ ├── ModelBuilderTest.sln │ └── ModelBuilderTest │ │ ├── ModelBuilderTest.csproj │ │ └── Program.cs ├── MyLearn │ ├── MyLearn.sln │ └── MyLearn │ │ ├── ApplicationBuilderTest.cs │ │ ├── Models │ │ └── Models.cs │ │ ├── MyLearn.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── ServiceDescriptorTests.cs │ │ └── ServiceScopeTests.cs ├── NewQueryOptionIn8 │ ├── NewQueryOptionIn8.sln │ ├── NewQueryOptionIn8 │ │ ├── Controllers │ │ │ ├── ProductsController.cs │ │ │ ├── SalesController.cs │ │ │ └── WeatherForecastController.cs │ │ ├── Extensions │ │ │ └── ProductSaleSearchBinder.cs │ │ ├── Models │ │ │ ├── IProductSaleRepository.cs │ │ │ ├── ModelBuilder.cs │ │ │ ├── Product.cs │ │ │ └── ProductSaleInMemoryRespository.cs │ │ ├── NewQueryOptionIn8.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ └── readme.md ├── ODataApiVersion │ ├── ODataApiVersion.sln │ ├── ODataApiVersion │ │ ├── Controllers │ │ │ ├── WeatherForecastController.cs │ │ │ ├── v1 │ │ │ │ └── CustomersController.cs │ │ │ └── v2 │ │ │ │ └── CustomersController.cs │ │ ├── Extensions │ │ │ ├── EntitySetCustomersSegment.cs │ │ │ ├── EntitySetWithKeySegment.cs │ │ │ ├── IODataModelProvider.cs │ │ │ ├── MyODataModelProvider.cs │ │ │ ├── MyODataRoutingApplicationModelProvider.cs │ │ │ └── MyODataRoutingMatcherPolicy.cs │ │ ├── Models │ │ │ ├── CustomerBase.cs │ │ │ ├── v1 │ │ │ │ └── Customer.cs │ │ │ └── v2 │ │ │ │ └── Customer.cs │ │ ├── ODataApiVersion.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ └── Readme.md ├── ODataCborExample │ ├── ODataCborClient │ │ ├── Connected Services │ │ │ └── OData Service │ │ │ │ ├── ConnectedService.json │ │ │ │ ├── OData ServiceCsdl.xml │ │ │ │ └── Reference.cs │ │ ├── ODataCborClient.csproj │ │ ├── ODataClient.cs │ │ └── Program.cs │ ├── ODataCborExample.sln │ ├── ODataCborExample │ │ ├── Controllers │ │ │ ├── BooksController.cs │ │ │ └── WeatherForecastController.cs │ │ ├── Extensions │ │ │ ├── CborLoggerMiddleware.cs │ │ │ ├── CborMediaTypeResolver.cs │ │ │ ├── CborODataJsonReaderFactory.cs │ │ │ ├── CborODataJsonWriterFactory.cs │ │ │ ├── CborODataReader.cs │ │ │ ├── CborODataWriter.Async.cs │ │ │ ├── CborODataWriter.cs │ │ │ └── IMessageWriter.cs │ │ ├── Models │ │ │ ├── Book.cs │ │ │ └── EdmModelBuilder.cs │ │ ├── ODataCborExample.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ └── readme.md ├── ODataCustomizePayloadFormat │ ├── ODataCustomizePayloadFormat.sln │ ├── ODataCustomizePayloadFormat │ │ ├── Controllers │ │ │ ├── BooksController.cs │ │ │ └── CustomersController.cs │ │ ├── Extensions │ │ │ ├── Cbor │ │ │ │ └── CborODataWriter.cs │ │ │ ├── Csv │ │ │ │ ├── CsvFormat.cs │ │ │ │ ├── CsvMediaTypeResolver.cs │ │ │ │ ├── CsvODataReader.cs │ │ │ │ ├── CsvOutputContext.cs │ │ │ │ └── CsvWriter.cs │ │ │ ├── CustomizedFormat.cs │ │ │ ├── CustomizedInputContext.cs │ │ │ ├── CustomizedMediaTypeResolver.cs │ │ │ ├── CustomizedOutputContext.cs │ │ │ ├── CustomizedWriter.cs │ │ │ └── Yaml │ │ │ │ ├── YamlODataReader.cs │ │ │ │ └── YamlODataWriter.cs │ │ ├── Models │ │ │ ├── Address.cs │ │ │ ├── Book.cs │ │ │ ├── Customer.cs │ │ │ └── EdmModelBuilder.cs │ │ ├── ODataCustomizePayloadFormat.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ └── readme.md ├── ODataETagExtensions │ ├── ODataETagClient │ │ ├── Connected Services │ │ │ └── OData Service │ │ │ │ ├── ConnectedService.json │ │ │ │ ├── OData ServiceCsdl.xml │ │ │ │ └── Reference.cs │ │ ├── Customer.cs │ │ ├── ODataETagClient.csproj │ │ └── Program.cs │ ├── ODataETagExtensions.sln │ └── ODataETagWebApi │ │ ├── Controllers │ │ ├── CustomersController.cs │ │ └── WeatherForecastController.cs │ │ ├── Extensions │ │ ├── ETagDeserializerProvider.cs │ │ ├── ETagResourceDeserializer.cs │ │ ├── ETagResourceSerializer.cs │ │ └── ETagSerializerProvider.cs │ │ ├── Models │ │ └── Customer.cs │ │ ├── ODataETagWebApi.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json ├── ODataProtobufExample │ ├── ODataProtobufClient │ │ ├── GrpcBookstoreClient.cs │ │ ├── ODataProtobufClient.csproj │ │ ├── Program.cs │ │ └── Protos │ │ │ └── bookstore.proto │ ├── ODataProtobufExample.sln │ ├── ODataProtobufExample │ │ ├── Controllers │ │ │ ├── ShelfBooksController.cs │ │ │ └── WeatherForecastController.cs │ │ ├── Extensions │ │ │ ├── ProtobufFormat.cs │ │ │ ├── ProtobufInputContext.cs │ │ │ ├── ProtobufMediaTypeResolver.cs │ │ │ ├── ProtobufOutputContext.cs │ │ │ ├── ProtobufReader.cs │ │ │ └── ProtobufWriter.cs │ │ ├── Models │ │ │ ├── ModelBuilder.cs │ │ │ ├── Shelf.cs │ │ │ └── ShelfBookInMemoryRepository.cs │ │ ├── ODataProtobufExample.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Protos │ │ │ └── bookstore.proto │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ └── Readme.md ├── OmitNullPropertySample │ ├── OmitNullPropertySample.sln │ └── OmitNullPropertySample │ │ ├── Controllers │ │ ├── SchoolStudentController.cs │ │ └── WeatherForecastController.cs │ │ ├── Extensions │ │ ├── OmitNullResourceSerializer.cs │ │ └── RequestExtensions.cs │ │ ├── Models │ │ ├── Address.cs │ │ ├── Color.cs │ │ ├── EdmModelBuilder.cs │ │ ├── ISchoolStudentRepository.cs │ │ ├── School.cs │ │ ├── SchoolStudentRepositoryInMemory.cs │ │ └── Student.cs │ │ ├── OmitNullPropertySample.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json ├── SelectImprovement │ ├── SelectImprovement.sln │ └── SelectImprovement │ │ ├── Controllers │ │ └── CustomersController.cs │ │ ├── Models │ │ ├── Address.cs │ │ ├── Customer.cs │ │ ├── DefaultDataRespository.cs │ │ ├── IDataRepository.cs │ │ ├── Order.cs │ │ └── ZipCode.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── SelectImprovement.csproj │ │ ├── Startup.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json ├── UntypedApp │ ├── UntypedApp.sln │ ├── UntypedApp │ │ ├── Controllers │ │ │ └── HandlePeopleController.cs │ │ ├── Extensions │ │ │ ├── MyResourceSerializer.cs │ │ │ └── MyUntypedResourceMapper.cs │ │ ├── Models │ │ │ ├── Address.cs │ │ │ ├── Color.cs │ │ │ ├── Course.cs │ │ │ ├── DataSource.cs │ │ │ ├── EdmModelBuilder.cs │ │ │ ├── Gender.cs │ │ │ ├── Person.cs │ │ │ └── UserType.cs │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── UntypedApp.csproj │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ └── readme.md └── gRPC.OData │ ├── gRPC.OData.Client │ ├── GrpcBookstoreClient.cs │ ├── IBookStoreClient.cs │ ├── ODataBookstoreClient.cs │ ├── Program.cs │ ├── Protos │ │ └── Bookstore.proto │ └── gRPC.OData.Client.csproj │ ├── gRPC.OData.Server │ ├── Controllers │ │ ├── ShelfBooksController.cs │ │ └── WeatherForecastController.cs │ ├── Extensions │ │ └── EndpointDebugMiddleware.cs │ ├── Models │ │ ├── EdmModelBuilder.cs │ │ ├── IShelfBookRepository.cs │ │ ├── ShelfBookInMemoryRepository.cs │ │ └── ShelfExtensions.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Protos │ │ └── Bookstore.proto │ ├── Services │ │ └── BookstoreService.cs │ ├── WeatherForecast.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ └── gRPC.OData.Server.csproj │ ├── gRPC.OData.sln │ └── readme.md └── tests ├── ObjectResultExecutorTests ├── ObjectResultExecutorTests.sln └── ObjectResultExecutorTests │ ├── Customer.cs │ ├── ObjectResultExecutorTest.cs │ ├── ObjectResultExecutorTests.csproj │ └── Program.cs └── ObjectResultExecutorXunitTests ├── Customer.cs ├── ObjectResultExecutorTest.cs ├── ObjectResultExecutorXunitTests.csproj └── UnitTest1.cs /.gitattributes: -------------------------------------------------------------------------------- 1 | *.doc diff=astextplain 2 | *.DOC diff=astextplain 3 | *.docx diff=astextplain 4 | *.DOCX diff=astextplain 5 | *.dot diff=astextplain 6 | *.DOT diff=astextplain 7 | *.pdf diff=astextplain 8 | *.PDF diff=astextplain 9 | *.rtf diff=astextplain 10 | *.RTF diff=astextplain 11 | 12 | *.jpg binary 13 | *.png binary 14 | *.gif binary 15 | 16 | *.cs text=auto diff=csharp 17 | *.vb text=auto 18 | *.resx text=auto 19 | *.c text=auto 20 | *.cpp text=auto 21 | *.cxx text=auto 22 | *.h text=auto 23 | *.hxx text=auto 24 | *.py text=auto 25 | *.rb text=auto 26 | *.java text=auto 27 | *.html text=auto 28 | *.htm text=auto 29 | *.css text=auto 30 | *.scss text=auto 31 | *.sass text=auto 32 | *.less text=auto 33 | *.js text=auto 34 | *.lisp text=auto 35 | *.clj text=auto 36 | *.sql text=auto 37 | *.php text=auto 38 | *.lua text=auto 39 | *.m text=auto 40 | *.asm text=auto 41 | *.erl text=auto 42 | *.fs text=auto 43 | *.fsx text=auto 44 | *.hs text=auto 45 | 46 | *.csproj text=auto 47 | *.vbproj text=auto 48 | *.fsproj text=auto 49 | *.dbproj text=auto 50 | *.sln text=auto eol=crlf 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | [Bb]in 2 | [Oo]bj 3 | [Tt]est[Rr]esults 4 | *.suo 5 | *.user 6 | *.[Cc]ache 7 | *[Rr]esharper* 8 | packages 9 | NuGet.exe 10 | _[Ss]cripts 11 | *.exe 12 | *.dll 13 | *.nupkg 14 | *.dot[Cc]over 15 | *.vsp 16 | *.psess 17 | *.orig 18 | *.sln.ide 19 | .nuget/ 20 | *.sln.ide/ 21 | _ReSharper.*/ 22 | packages/ 23 | artifacts/ 24 | PublishProfiles/ 25 | .vs/ 26 | debugSettings.json 27 | project.lock.json 28 | *.docstates 29 | *net45.csproj 30 | *net451.csproj 31 | *k10.csproj 32 | *.pidb 33 | *.userprefs 34 | *DS_Store 35 | *.ncrunchsolution 36 | *.*sdf 37 | *.ipch -------------------------------------------------------------------------------- /Images/AspnetCoreodata80_debug1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhg/MyAspNetCore/f08a774c4bbe160f6359ad5241b713c70112789c/Images/AspnetCoreodata80_debug1.png -------------------------------------------------------------------------------- /Images/AspnetCoreodata80_debug2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhg/MyAspNetCore/f08a774c4bbe160f6359ad5241b713c70112789c/Images/AspnetCoreodata80_debug2.png -------------------------------------------------------------------------------- /Images/ConfigurationBuilder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhg/MyAspNetCore/f08a774c4bbe160f6359ad5241b713c70112789c/Images/ConfigurationBuilder.png -------------------------------------------------------------------------------- /Images/ConfigurationInterface1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhg/MyAspNetCore/f08a774c4bbe160f6359ad5241b713c70112789c/Images/ConfigurationInterface1.png -------------------------------------------------------------------------------- /Images/ConfigurationInterface2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhg/MyAspNetCore/f08a774c4bbe160f6359ad5241b713c70112789c/Images/ConfigurationInterface2.png -------------------------------------------------------------------------------- /Images/ConfigurationProvider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhg/MyAspNetCore/f08a774c4bbe160f6359ad5241b713c70112789c/Images/ConfigurationProvider.png -------------------------------------------------------------------------------- /Images/IConfigurationProvider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhg/MyAspNetCore/f08a774c4bbe160f6359ad5241b713c70112789c/Images/IConfigurationProvider.png -------------------------------------------------------------------------------- /Images/api_versioning_swagger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhg/MyAspNetCore/f08a774c4bbe160f6359ad5241b713c70112789c/Images/api_versioning_swagger.png -------------------------------------------------------------------------------- /Images/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AspNetCore 2 | Study ASP.NET Core, Share materials, points, views 3 | -------------------------------------------------------------------------------- /docs/Asp.Net program startup investigation.md: -------------------------------------------------------------------------------- 1 | The typical Asp.NET Core application entry points: 2 | 3 | ```C# 4 | public static void Main(string[] args) 5 | { 6 | var host = new WebHostBuilder() 7 | .UseKestrel() 8 | .UseContentRoot(Directory.GetCurrentDirectory()) 9 | .UseIISIntegration() 10 | .UseStartup() 11 | .Build(); 12 | 13 | host.Run(); 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/AspNetCore.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhg/MyAspNetCore/f08a774c4bbe160f6359ad5241b713c70112789c/docs/AspNetCore.md -------------------------------------------------------------------------------- /docs/Configuration/Configuration Interfaces.md: -------------------------------------------------------------------------------- 1 | ## IConfiguration 2 | 3 | Below is the interface inheritance: 4 | 5 | ![Image of Interface](https://github.com/xuzhg/AspNetCore/blob/master/Images/ConfigurationInterface1.png) 6 | 7 | Where: 8 | 1. **IConfiguration**: represents a set of key/value application configuration properties. 9 | 2. **IConfigurationRoot**: derived from `IConfiguration`, represents the root of `IConfiguration` hierarchy. 10 | 3. **IConfigurationSection**: derived from `IConfiguration`, represents a section of application configuration values. 11 | 12 | ## IConfigurationBuilder & IConfigurationProvider & IConfigurationSource 13 | 14 | ![Image of Interface](https://github.com/xuzhg/AspNetCore/blob/master/Images/ConfigurationInterface2.png) 15 | -------------------------------------------------------------------------------- /docs/Configuration/ConfigurationBuilder.md: -------------------------------------------------------------------------------- 1 | ## IConfigurationBuilder 2 | 3 | ![IConfigurationBuilder Interface](https://github.com/xuzhg/AspNetCore/blob/master/Images/ConfigurationBuilder.png) 4 | 5 | ## ConfigurationBuilder 6 | 7 | It's the default implementation of `IConfigurationBuilder` interface. 8 | Basically, it's a wrapper of `IList`. 9 | 10 | You can access the readonly property `Sources` to query the `IConfiguarationSource` added in this builder. 11 | You can call `Add(IConfigurationSource source)` method to add a `IConfigurationSource` into this builder. 12 | 13 | The main/key method is `Build()`, it returns an instance of `IConfigurationRoot`. 14 | Below is the detail implmentation of `Build()` method: 15 | 16 | ```C# 17 | public IConfigurationRoot Build() 18 | { 19 | var providers = new List(); 20 | foreach (var source in _sources) 21 | { 22 | var provider = source.Build(this); 23 | providers.Add(provider); 24 | } 25 | return new ConfigurationRoot(providers); 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/Configuration/ConfigurationSource.md: -------------------------------------------------------------------------------- 1 | ## IConfigurationSource 2 | 3 | ```C# 4 | 5 | public interface IConfigurationSource 6 | { 7 | IConfigurationProvider Build(IConfigurationBuilder builder); 8 | } 9 | 10 | ``` 11 | 12 | The `Build(...)` method will be called by `ConfigurationBuilder`. 13 | 14 | # Implementation 15 | 16 | Here's the implementation for the `IConfigurationSource` 17 | 18 | - MemoryConfigurationSource 19 | - AzureKeyVaultKeyCongfigurationSource 20 | - CommandLineConfigurationSource 21 | - DockerSecretsConfigurationSource 22 | - FileConfiguarationSource 23 | - IniConfigurationSource 24 | - JsonConfigurationSource 25 | - XmlConfigurationSource 26 | 27 | 28 | Each implementation of `IConfigurationSource` is very simple, the `Build(...)` method will return the corresponding `IConfigurationProvider`. 29 | For example: 30 | 31 | ```C# 32 | public class JsonConfigurationSource : FileConfigurationSource 33 | { 34 | public override IConfigurationProvider Build(IConfigurationBuilder builder) 35 | { 36 | EnsureDefaults(builder); 37 | return new JsonConfigurationProvider(this); 38 | } 39 | } 40 | ``` 41 | The `JsonConfigurationSource` returns the `JsonConfigurationProvider`. 42 | 43 | For the `IConfigurationProvider`, please refer to [HERE](https://github.com/xuzhg/AspNetCore/blob/master/docs/Configuration/ConfigurationProvider.md) 44 | -------------------------------------------------------------------------------- /sln/AspNetCore/AspNetCore.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2026 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EFCoreConsole", "..\..\src\EFCore\EFCoreConsole\EFCoreConsole.csproj", "{6BF0CF3C-3754-4967-88CC-C116658B928F}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {6BF0CF3C-3754-4967-88CC-C116658B928F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {6BF0CF3C-3754-4967-88CC-C116658B928F}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {6BF0CF3C-3754-4967-88CC-C116658B928F}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {6BF0CF3C-3754-4967-88CC-C116658B928F}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {ECF6DA61-B059-41DB-BE5F-0EBF1696A6D3} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.1.32203.90 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetClassic.Geography", "AspNetClassic.Geography\AspNetClassic.Geography.csproj", "{E2ED7095-A6A2-485B-BC81-56281514258D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {E2ED7095-A6A2-485B-BC81-56281514258D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {E2ED7095-A6A2-485B-BC81-56281514258D}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {E2ED7095-A6A2-485B-BC81-56281514258D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {E2ED7095-A6A2-485B-BC81-56281514258D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {B9115299-6E39-4A38-86F2-4878F35CAF91} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | using AspNetClassic.Geography.Models; 2 | using Microsoft.AspNet.OData.Extensions; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Web.Http; 7 | 8 | namespace AspNetClassic.Geography 9 | { 10 | public static class WebApiConfig 11 | { 12 | public static void Register(HttpConfiguration config) 13 | { 14 | // Web API configuration and services 15 | CustomerGeoContext.Init(); 16 | 17 | config.MapODataServiceRoute("odata", "odata", EdmModelBuilder.BuildCustomerEdmModel()); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography/Controllers/CustomersController.cs: -------------------------------------------------------------------------------- 1 | using AspNetClassic.Geography.Models; 2 | using Microsoft.AspNet.OData; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Web; 7 | using System.Web.Http; 8 | 9 | namespace AspNetClassic.Geography.Controllers 10 | { 11 | public class CustomersController : ODataController 12 | { 13 | private CustomerGeoContext db = new CustomerGeoContext(); 14 | 15 | [EnableQuery] 16 | public IHttpActionResult Get() 17 | { 18 | return Ok(db.Customers); 19 | } 20 | 21 | public IHttpActionResult Get(int key) 22 | { 23 | Customer customer = db.Customers.First(c => c.Id == key); 24 | if (customer == null) 25 | { 26 | return NotFound(); 27 | } 28 | 29 | return Ok(customer); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Net.Http; 6 | using System.Web.Http; 7 | 8 | namespace AspNetClassic.Geography.Controllers 9 | { 10 | public class ValuesController : ApiController 11 | { 12 | // GET api/values 13 | public IEnumerable Get() 14 | { 15 | return new string[] { "value1", "value2" }; 16 | } 17 | 18 | // GET api/values/5 19 | public string Get(int id) 20 | { 21 | return "value"; 22 | } 23 | 24 | // POST api/values 25 | public void Post([FromBody] string value) 26 | { 27 | } 28 | 29 | // PUT api/values/5 30 | public void Put(int id, [FromBody] string value) 31 | { 32 | } 33 | 34 | // DELETE api/values/5 35 | public void Delete(int id) 36 | { 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="AspNetClassic.Geography.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Http; 6 | using System.Web.Mvc; 7 | using System.Web.Optimization; 8 | using System.Web.Routing; 9 | 10 | namespace AspNetClassic.Geography 11 | { 12 | public class WebApiApplication : HttpApplication 13 | { 14 | protected void Application_Start() 15 | { 16 | GlobalConfiguration.Configure(WebApiConfig.Register); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography/Models/Customer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Data.Entity.Spatial; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | using Microsoft.Spatial; 8 | using AspNetClassic.Geography.Extensions; 9 | 10 | namespace AspNetClassic.Geography.Models 11 | { 12 | public class Customer 13 | { 14 | private GeographyWrapper _ptWrapper; 15 | private GeographyWrapper _lineWrapper; 16 | 17 | public int Id { get; set; } 18 | 19 | public string Name { get; set; } 20 | 21 | public DbGeography Location 22 | { 23 | get { return _ptWrapper; } 24 | set { _ptWrapper = value; } 25 | } 26 | 27 | [NotMapped] 28 | public GeographyPoint EdmLocation 29 | { 30 | get { return _ptWrapper; } 31 | set { _ptWrapper = value; } 32 | } 33 | 34 | public DbGeography Line 35 | { 36 | get { return _lineWrapper; } 37 | set { _lineWrapper = value; } 38 | } 39 | 40 | [NotMapped] 41 | public GeographyLineString EdmLine 42 | { 43 | get { return _lineWrapper; } 44 | set { _lineWrapper = value; } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography/Models/EdmModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.OData.Builder; 2 | using Microsoft.OData.Edm; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Web; 7 | 8 | namespace AspNetClassic.Geography.Models 9 | { 10 | public class EdmModelBuilder 11 | { 12 | public static IEdmModel BuildCustomerEdmModel() 13 | { 14 | var builder = new ODataModelBuilder(); 15 | builder.EntitySet("Customers"); 16 | 17 | var customerType = builder.EntityType(); 18 | customerType.HasKey(c => c.Id).Ignore(c => c.Location); 19 | customerType.Ignore(c => c.Line); 20 | customerType.Property(c => c.Name); 21 | 22 | // Cannot call customerType.Property(c => c.HomeLocation) 23 | var customer = builder.StructuralTypes.First(t => t.ClrType == typeof(Customer)); 24 | customer.AddProperty(typeof(Customer).GetProperty("EdmLocation")).Name = "Location"; 25 | customer.AddProperty(typeof(Customer).GetProperty("EdmLine")).Name = "Line"; 26 | return builder.GetEdmModel(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("AspNetClassic.Geography")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("AspNetClassic.Geography")] 13 | [assembly: AssemblyCopyright("Copyright © 2022")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("cf01e95e-210d-42fd-832a-8eeb109124e3")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/AspNetClassic.Geography/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/AspNetClassic.Geography/readme.md: -------------------------------------------------------------------------------- 1 | # ASPNETClassic.Geography 2 | 3 | This sample is re-created using ASP.NET OData 7.5.x version to be related with blog post: 4 | 5 | https://devblogs.microsoft.com/odata/how-to-consume-sql-spatial-data-with-web-api-v2-2-for-odata-v4/ 6 | 7 | The old one is gone and cannot find. :(. 8 | 9 | Any question or concerns, please leave your comments or send email to saxu@microsoft.com. 10 | 11 | Thanks! 12 | -Sam 13 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30914.41 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AttributeRouting80Rc", "AttributeRouting80Rc\AttributeRouting80Rc.csproj", "{F354305E-6CF0-479F-B785-DBAD92BC3EF8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {F354305E-6CF0-479F-B785-DBAD92BC3EF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {F354305E-6CF0-479F-B785-DBAD92BC3EF8}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {F354305E-6CF0-479F-B785-DBAD92BC3EF8}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {F354305E-6CF0-479F-B785-DBAD92BC3EF8}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {F2DE4BE9-C555-4F95-BE5A-4F94BE31A2D6} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/AttributeRouting80Rc.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Controllers/HandAbolusteController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.AspNetCore.Mvc; 5 | using Microsoft.AspNetCore.OData.Routing.Attributes; 6 | 7 | namespace AttributeRouting80Rc.Controllers 8 | { 9 | [Route("v{version}")] 10 | public class HandAbolusteController : Controller 11 | { 12 | [ODataRouting] 13 | [HttpGet("/odata/orders({key})/SendTo(lat={lat},lon={lon})")] 14 | public string SendTo(int key, double lat, double lon) 15 | { 16 | return $"Send Order({key}) to location at ({lat},{lon})"; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Controllers/HandleMultipleController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.AspNetCore.Mvc; 5 | using Microsoft.AspNetCore.OData.Routing.Attributes; 6 | 7 | namespace AttributeRouting80Rc.Controllers 8 | { 9 | [Route("odata")] 10 | [Route("v{version}")] 11 | public class HandleMultipleController : Controller 12 | { 13 | [ODataRouting] 14 | [HttpGet("orders")] 15 | public string Get(string version) 16 | { 17 | if (version != null) 18 | { 19 | return $"Orders from version = {version}"; 20 | } 21 | else 22 | { 23 | return "Orders from odata"; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Controllers/HandleOthersController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.AspNetCore.Mvc; 5 | using Microsoft.AspNetCore.OData.Routing.Attributes; 6 | 7 | namespace AttributeRouting80Rc.Controllers 8 | { 9 | public class HandleOthersController : Controller 10 | { 11 | [ODataRouting] 12 | [HttpGet("odata/Orders/{key}")] 13 | public IActionResult Get(int key) 14 | { 15 | return Ok($"Orders{key} from OData"); 16 | } 17 | 18 | [HttpGet("odata/Orders({key})")] 19 | public IActionResult GetOrder(int key) 20 | { 21 | return Ok($"Orders{key} from non-OData"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace AttributeRouting80Rc.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Models/Address.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace AttributeRouting80Rc.Models 5 | { 6 | public class Address 7 | { 8 | public string City { get; set; } 9 | public string Street { get; set; } 10 | } 11 | 12 | public class CnAddress : Address 13 | { 14 | public string Postcode { get; set; } 15 | } 16 | 17 | public class UsAddress : Address 18 | { 19 | public string Zipcode { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Models/BookAndPress.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace AttributeRouting80Rc.Models 5 | { 6 | public class Book 7 | { 8 | public int Id { get; set; } 9 | public string ISBN { get; set; } 10 | public string Title { get; set; } 11 | public string Author { get; set; } 12 | public decimal Price { get; set; } 13 | public Address Location { get; set; } 14 | public Press Press { get; set; } 15 | } 16 | 17 | public class Press 18 | { 19 | public int Id { get; set; } 20 | public string Name { get; set; } 21 | public string Email { get; set; } 22 | public Category Category { get; set; } 23 | } 24 | 25 | public enum Category 26 | { 27 | Book, 28 | Magazine, 29 | EBook 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Models/BookStoreContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace AttributeRouting80Rc.Models 7 | { 8 | public class BookStoreContext : DbContext 9 | { 10 | public BookStoreContext(DbContextOptions options) 11 | : base(options) 12 | { 13 | } 14 | 15 | public DbSet Books { get; set; } 16 | public DbSet Presses { get; set; } 17 | 18 | protected override void OnModelCreating(ModelBuilder modelBuilder) 19 | { 20 | modelBuilder.Entity().OwnsOne(c => c.Location); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Models/CustomerAndOrder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace AttributeRouting80Rc.Models 7 | { 8 | public class Customer 9 | { 10 | public int Id { get; set; } 11 | 12 | public string Name { get; set; } 13 | 14 | public Color FavoriteColor { get; set; } 15 | 16 | // public string[] Emails { get; set; } 17 | 18 | public virtual Address HomeAddress { get; set; } 19 | 20 | public virtual IList Orders { get; set; } 21 | } 22 | 23 | public class Order 24 | { 25 | public int Id { get; set; } 26 | 27 | public int Price { get; set; } 28 | } 29 | 30 | public enum Color 31 | { 32 | Red, 33 | 34 | Green, 35 | 36 | Blue 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Models/CustomerOrderContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace AttributeRouting80Rc.Models 7 | { 8 | public class CustomerOrderContext : DbContext 9 | { 10 | public CustomerOrderContext(DbContextOptions options) 11 | : base(options) 12 | { 13 | } 14 | 15 | public DbSet Customers { get; set; } 16 | public DbSet Orders { get; set; } 17 | 18 | protected override void OnModelCreating(ModelBuilder modelBuilder) 19 | { 20 | modelBuilder.Entity().OwnsOne(c => c.HomeAddress); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Models/EdmModelBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.OData.Edm; 5 | using Microsoft.OData.ModelBuilder; 6 | 7 | namespace AttributeRouting80Rc.Models 8 | { 9 | public static class EdmModelBuilder 10 | { 11 | public static IEdmModel BuildCustomerModel() 12 | { 13 | ODataConventionModelBuilder builder = new(); 14 | builder.EntitySet("Customers"); 15 | builder.EntitySet("Orders"); 16 | 17 | var function = builder.EntityType().Function("PlayPiano").Returns(); 18 | function.Parameter("kind"); 19 | function.Parameter("name"); 20 | 21 | ConfigOrder(builder); 22 | 23 | return builder.GetEdmModel(); 24 | } 25 | 26 | public static IEdmModel BuildBookModel() 27 | { 28 | ODataConventionModelBuilder builder = new(); 29 | builder.EntitySet("Books"); 30 | builder.EntitySet("Presses"); 31 | builder.EntitySet("Orders"); 32 | 33 | ConfigOrder(builder); 34 | 35 | return builder.GetEdmModel(); 36 | } 37 | 38 | private static void ConfigOrder(ODataConventionModelBuilder builder) 39 | { 40 | var function = builder.EntityType().Function("SendTo").Returns(); 41 | function.Parameter("lat"); 42 | function.Parameter("lon"); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace AttributeRouting80Rc 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:56394", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "AttributeRouting80Rc": { 21 | "commandName": "Project", 22 | "dotnetRunMessages": "true", 23 | "launchBrowser": true, 24 | "launchUrl": "$odata", 25 | "applicationUrl": "http://localhost:5000", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AttributeRouting80Rc 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AttributeRouting80Rc/AttributeRouting80Rc/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /src/BookStore/BookStore.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2026 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookStore", "BookStore\BookStore.csproj", "{33059C61-51F3-4EAB-9E7D-E11529A17DD0}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {33059C61-51F3-4EAB-9E7D-E11529A17DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {33059C61-51F3-4EAB-9E7D-E11529A17DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {33059C61-51F3-4EAB-9E7D-E11529A17DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {33059C61-51F3-4EAB-9E7D-E11529A17DD0}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {40E277FC-3CDA-416F-857C-BC4CF01A75A9} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/BookStore/BookStore/BookStore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BookStore/BookStore/Controllers/PressesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using BookStore.Models; 6 | using Microsoft.AspNet.OData; 7 | using Microsoft.AspNetCore.Mvc; 8 | 9 | namespace BookStore.Controllers 10 | { 11 | public class PressesController : ODataController 12 | { 13 | private BookStoreContext _db; 14 | 15 | public PressesController(BookStoreContext context) 16 | { 17 | _db = context; 18 | if (context.Books.Count() == 0) 19 | { 20 | foreach (var b in DataSource.GetBooks()) 21 | { 22 | context.Books.Add(b); 23 | context.Presses.Add(b.Press); 24 | } 25 | context.SaveChanges(); 26 | } 27 | } 28 | 29 | [EnableQuery] 30 | public IActionResult Get() 31 | { 32 | return Ok(_db.Presses); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/BookStore/BookStore/Models/Address.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace BookStore.Models 7 | { 8 | public class Address 9 | { 10 | public string City { get; set; } 11 | public string Street { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/BookStore/BookStore/Models/Book.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace BookStore.Models 8 | { 9 | public class Book 10 | { 11 | public int Id { get; set; } 12 | public string ISBN { get; set; } 13 | public string Title { get; set; } 14 | public string Author { get; set; } 15 | public decimal Price { get; set; } 16 | public Address Location { get; set; } 17 | public Press Press { get; set; } 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/BookStore/BookStore/Models/BookStoreContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace BookStore.Models 8 | { 9 | public class BookStoreContext : DbContext 10 | { 11 | public BookStoreContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | } 15 | 16 | public DbSet Books { get; set; } 17 | public DbSet Presses { get; set; } 18 | 19 | protected override void OnModelCreating(ModelBuilder modelBuilder) 20 | { 21 | modelBuilder.Entity().OwnsOne(c => c.Location); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/BookStore/BookStore/Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace BookStore.Models 7 | { 8 | public enum Category 9 | { 10 | Book, 11 | Magazine, 12 | EBook 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/BookStore/BookStore/Models/Press.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace BookStore.Models 7 | { 8 | public class Press 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Email { get; set; } 13 | public Category Category { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/BookStore/BookStore/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace BookStore 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | CreateWebHostBuilder(args).Build().Run(); 18 | } 19 | 20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/BookStore/BookStore/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:23376", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "BookStore": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "applicationUrl": "http://localhost:5001", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/BookStore/BookStore/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/BookStore/BookStore/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } 9 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30524.135 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookStoreAspNetCoreOData8Preview", "BookStoreAspNetCoreOData8Preview\BookStoreAspNetCoreOData8Preview.csproj", "{A6D0446C-2717-4002-8F47-12EDA5782779}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {A6D0446C-2717-4002-8F47-12EDA5782779}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {A6D0446C-2717-4002-8F47-12EDA5782779}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {A6D0446C-2717-4002-8F47-12EDA5782779}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {A6D0446C-2717-4002-8F47-12EDA5782779}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {90A61DCC-4469-4042-B534-C37020F4A7EF} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/Controllers/PressesController.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using BookStore.Models; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.AspNetCore.OData.Query; 5 | using Microsoft.AspNetCore.OData.Routing.Controllers; 6 | 7 | namespace BookStore.Controllers 8 | { 9 | public class PressesController : ODataController 10 | { 11 | private BookStoreContext _db; 12 | 13 | public PressesController(BookStoreContext context) 14 | { 15 | _db = context; 16 | if (context.Books.Count() == 0) 17 | { 18 | foreach (var b in DataSource.GetBooks()) 19 | { 20 | context.Books.Add(b); 21 | context.Presses.Add(b.Press); 22 | } 23 | context.SaveChanges(); 24 | } 25 | } 26 | 27 | [EnableQuery] 28 | public IActionResult Get() 29 | { 30 | return Ok(_db.Presses); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/Models/Address.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace BookStore.Models 7 | { 8 | public class Address 9 | { 10 | public string City { get; set; } 11 | public string Street { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/Models/Book.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace BookStore.Models 8 | { 9 | public class Book 10 | { 11 | public int Id { get; set; } 12 | public string ISBN { get; set; } 13 | public string Title { get; set; } 14 | public string Author { get; set; } 15 | public decimal Price { get; set; } 16 | public Address Location { get; set; } 17 | public Press Press { get; set; } 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/Models/BookStoreContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace BookStore.Models 8 | { 9 | public class BookStoreContext : DbContext 10 | { 11 | public BookStoreContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | } 15 | 16 | public DbSet Books { get; set; } 17 | public DbSet Presses { get; set; } 18 | 19 | protected override void OnModelCreating(ModelBuilder modelBuilder) 20 | { 21 | modelBuilder.Entity().OwnsOne(c => c.Location); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace BookStore.Models 7 | { 8 | public enum Category 9 | { 10 | Book, 11 | Magazine, 12 | EBook 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/Models/Press.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace BookStore.Models 7 | { 8 | public class Press 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Email { get; set; } 13 | public Category Category { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace BookStoreAspNetCoreOData8Preview 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:50246", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "vbeta/Books", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "BookStoreAspNetCoreOData8Preview": { 21 | "commandName": "Project", 22 | "dotnetRunMessages": "true", 23 | "launchBrowser": true, 24 | "launchUrl": "vbeta/Books(1)", 25 | "applicationUrl": "http://localhost:5000", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BookStoreAspNetCoreOData8Preview 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/BookStoreAspNetCoreOData8Preview/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /src/BookStoreAspNetCoreOData8Preview/README.md: -------------------------------------------------------------------------------- 1 | # ASP.NET Core OData 8.0 preview 2 | 3 | This project is a sample project used in odata blog at: 4 | https://devblogs.microsoft.com/odata/asp-net-odata-8-0-preview-for-net-5/ 5 | 6 | Please send email to saxu@microsoft.com for any questions and concerns. 7 | 8 | Thanks! 9 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2026 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookStore", "BookStore\BookStore.csproj", "{33059C61-51F3-4EAB-9E7D-E11529A17DD0}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {33059C61-51F3-4EAB-9E7D-E11529A17DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {33059C61-51F3-4EAB-9E7D-E11529A17DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {33059C61-51F3-4EAB-9E7D-E11529A17DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {33059C61-51F3-4EAB-9E7D-E11529A17DD0}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {40E277FC-3CDA-416F-857C-BC4CF01A75A9} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/BookStore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/Controllers/PressesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using BookStore.Models; 6 | using Microsoft.AspNet.OData; 7 | using Microsoft.AspNetCore.Mvc; 8 | 9 | namespace BookStore.Controllers 10 | { 11 | public class PressesController : ODataController 12 | { 13 | private BookStoreContext _db; 14 | 15 | public PressesController(BookStoreContext context) 16 | { 17 | _db = context; 18 | if (context.Books.Count() == 0) 19 | { 20 | foreach (var b in DataSource.GetBooks()) 21 | { 22 | context.Books.Add(b); 23 | context.Presses.Add(b.Press); 24 | } 25 | context.SaveChanges(); 26 | } 27 | } 28 | 29 | [EnableQuery] 30 | public IActionResult Get() 31 | { 32 | return Ok(_db.Presses); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/Models/Address.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace BookStore.Models 7 | { 8 | public class Address 9 | { 10 | public string City { get; set; } 11 | public string Street { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/Models/Book.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace BookStore.Models 8 | { 9 | public class Book 10 | { 11 | public int Id { get; set; } 12 | public string ISBN { get; set; } 13 | public string Title { get; set; } 14 | public string Author { get; set; } 15 | public decimal Price { get; set; } 16 | public Address Location { get; set; } 17 | public Press Press { get; set; } 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/Models/BookStoreContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace BookStore.Models 8 | { 9 | public class BookStoreContext : DbContext 10 | { 11 | public BookStoreContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | } 15 | 16 | public DbSet Books { get; set; } 17 | public DbSet Presses { get; set; } 18 | 19 | protected override void OnModelCreating(ModelBuilder modelBuilder) 20 | { 21 | modelBuilder.Entity().OwnsOne(c => c.Location); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace BookStore.Models 7 | { 8 | public enum Category 9 | { 10 | Book, 11 | Magazine, 12 | EBook 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/Models/Press.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace BookStore.Models 7 | { 8 | public class Press 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Email { get; set; } 13 | public Category Category { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace BookStore 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | CreateWebHostBuilder(args).Build().Run(); 18 | } 19 | 20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:23376", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "BookStore": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "applicationUrl": "http://localhost:5001", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/BookStoreDotNet5/BookStore/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } 9 | -------------------------------------------------------------------------------- /src/DependencyInjection/DependencyInjectionTest/Readme.md: -------------------------------------------------------------------------------- 1 | ## DI has two methodologies 2 | 3 | ### Constructor-based dependency injection 4 | 5 | ```C# 6 | public interface IMyInterface 7 | { 8 | } 9 | 10 | public class MyClass : IMyInterface 11 | { 12 | } 13 | 14 | public class DIClass 15 | { 16 | public DIClass(IMyInterface myInterface) 17 | { 18 | ... 19 | } 20 | } 21 | 22 | ``` 23 | 24 | So, we can use the DI to create the instance of `DIClass`, the DI will help us create a `IMyInterface` instance and pass as argument to call the constructor: 25 | 26 | * Register the service: 27 | 28 | ```C# 29 | IServiceCollection services = new ServiceCollection(); 30 | services.AddSingleton(typeof(IMyInterface), typeof(MyClass)); 31 | services.AddScoped(); 32 | 33 | ``` 34 | 35 | * Get the service object 36 | 37 | ```C# 38 | IServiceProvider provider = services.BuildServiceProvider(); 39 | DIClass c = provider.GetRequiredService(); // here will call MyClass construtor, then call DIClass construtor. 40 | ``` 41 | 42 | **Where**, `c` will be a valid object. 43 | 44 | 45 | ### Action parameter injection with [FromServices] attribute 46 | 47 | ```C# 48 | public IActionResult About([FromServices] IMyInterface myInterface) 49 | { 50 | } 51 | ``` 52 | -------------------------------------------------------------------------------- /src/DependencyInjection/DependencyInjectionTest/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "projects": [ "src", "test" ], 3 | "sdk": { 4 | "version": "1.0.0-preview2-003121" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/DependencyInjection/DependencyInjectionTest/src/DependencyInjectionTest/DependencyInjectionTest.xproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | dc79fffb-2754-4420-bab3-250be8e8cda6 10 | DependencyInjectionTest 11 | .\obj 12 | .\bin\ 13 | v4.5.2 14 | 15 | 16 | 2.0 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/DependencyInjection/DependencyInjectionTest/src/DependencyInjectionTest/DependencyInjectionTest.xproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | DependencyInjectionTest 5 | 6 | -------------------------------------------------------------------------------- /src/DependencyInjection/DependencyInjectionTest/src/DependencyInjectionTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("DependencyInjectionTest")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("dc79fffb-2754-4420-bab3-250be8e8cda6")] 20 | -------------------------------------------------------------------------------- /src/DependencyInjection/DependencyInjectionTest/src/DependencyInjectionTest/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | "buildOptions": { 4 | "emitEntryPoint": true 5 | }, 6 | 7 | "dependencies": { 8 | "Microsoft.Extensions.DependencyInjection": "1.0.0", 9 | "xunit": "2.2.0-beta2-build3300", 10 | "dotnet-test-xunit": "2.2.0-preview2-build1029" 11 | }, 12 | 13 | "frameworks": { 14 | "net461": { } 15 | }, 16 | 17 | "testRunner": "xunit" 18 | } 19 | -------------------------------------------------------------------------------- /src/EFCore/EFCoreConsole/EFCoreConsole.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/EFCore/EFCoreConsole/Models/Machine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace EFCoreConsole.Models 6 | { 7 | public partial class Machine 8 | { 9 | public Machine() 10 | { 11 | SupportTicket = new HashSet(); 12 | } 13 | 14 | public int MachineId { get; set; } 15 | public string Name { get; set; } 16 | public string GeneralRole { get; set; } 17 | public string InstalledRoles { get; set; } 18 | public int OperatingSysId { get; set; } 19 | public int MachineTypeId { get; set; } 20 | public MachineType MachineType { get; set; } 21 | public OperatingSys OperatingSys { get; set; } 22 | public ICollection SupportTicket { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/EFCore/EFCoreConsole/Models/MachineType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace EFCoreConsole.Models 6 | { 7 | public partial class MachineType 8 | { 9 | public MachineType() 10 | { 11 | Machine = new HashSet(); 12 | } 13 | 14 | public int MachineTypeId { get; set; } 15 | public string Description { get; set; } 16 | public ICollection Machine { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/EFCore/EFCoreConsole/Models/MachineWarranty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace EFCoreConsole.Models 6 | { 7 | public partial class MachineWarranty 8 | { 9 | public int MachineWarrantyId { get; set; } 10 | public string ServiceTag { get; set; } 11 | public DateTime WarrantyExpiration { get; set; } 12 | public int MachineId { get; set; } 13 | public int WarrantyProviderId { get; set; } 14 | public WarrantyProvider WarrantyProvider { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/EFCore/EFCoreConsole/Models/OperatingSys.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace EFCoreConsole.Models 6 | { 7 | public partial class OperatingSys 8 | { 9 | public OperatingSys() 10 | { 11 | Machine = new HashSet(); 12 | } 13 | 14 | public int OperatingSysId { get; set; } 15 | public string Name { get; set; } 16 | public bool StillSupported { get; set; } 17 | public ICollection Machine { get; set; } 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/EFCore/EFCoreConsole/Models/SupportLong.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace EFCoreConsole.Models 6 | { 7 | public partial class SupportLog 8 | { 9 | public int SupportLogId { get; set; } 10 | public DateTime SupportLogEntryDate { get; set; } 11 | public string SupportLogEntry { get; set; } 12 | public string SupportLogUpdatedBy { get; set; } 13 | public int SupportTicketId { get; set; } 14 | public SupportTicket SupportTicket { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/EFCore/EFCoreConsole/Models/SupportTicket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace EFCoreConsole.Models 6 | { 7 | public partial class SupportTicket 8 | { 9 | public SupportTicket() 10 | { 11 | SupportLog = new HashSet(); 12 | } 13 | public int SupportTicketId { get; set; } 14 | public DateTime DateReported { get; set; } 15 | public DateTime? DateResolved { get; set; } 16 | public string IssueDescription { get; set; } 17 | public string IssueDetail { get; set; } 18 | public string TicketOpenedBy { get; set; } 19 | public int MachineId { get; set; } 20 | public Machine Machine { get; set; } 21 | public ICollection SupportLog { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/EFCore/EFCoreConsole/Models/WarrantyProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace EFCoreConsole.Models 6 | { 7 | public partial class WarrantyProvider 8 | { 9 | public WarrantyProvider() 10 | { 11 | MachineWarranty = new HashSet(); 12 | } 13 | 14 | public int WarrantyProviderId { get; set; } 15 | public string ProviderName { get; set; } 16 | public int? SupportExtension { get; set; } 17 | public string SupportNumber { get; set; } 18 | public ICollection MachineWarranty { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/EFCore/EFCoreLinqTest/EFCoreLinqTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2026 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EFCoreLinqTest", "EFCoreLinqTest\EFCoreLinqTest.csproj", "{F108C3DE-6AB6-4E8A-9310-A655E90E672A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {F108C3DE-6AB6-4E8A-9310-A655E90E672A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {F108C3DE-6AB6-4E8A-9310-A655E90E672A}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {F108C3DE-6AB6-4E8A-9310-A655E90E672A}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {F108C3DE-6AB6-4E8A-9310-A655E90E672A}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {B3C35EA2-977D-43AE-816E-8D9A5B3F0B2A} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/EFCore/EFCoreLinqTest/EFCoreLinqTest/EFCoreLinqTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31410.223 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilterExtensionFor801", "FilterExtensionFor801\FilterExtensionFor801.csproj", "{F9A270CC-3506-4F9F-ACBF-2C12F3D1726C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {F9A270CC-3506-4F9F-ACBF-2C12F3D1726C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {F9A270CC-3506-4F9F-ACBF-2C12F3D1726C}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {F9A270CC-3506-4F9F-ACBF-2C12F3D1726C}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {F9A270CC-3506-4F9F-ACBF-2C12F3D1726C}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {FCEEDF9C-86B0-40C5-AD09-7AD8EFA60C09} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace FilterExtensionFor801.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/FilterExtensionFor801.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/Models/Customer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations.Schema; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace FilterExtensionFor801.Models 8 | { 9 | public class Customer 10 | { 11 | private MetadataWrapper _wrapper; 12 | 13 | public int Id { get; set; } 14 | 15 | public string Name { get; set; } 16 | 17 | public string CustomMetadata 18 | { 19 | get => _wrapper; 20 | set => _wrapper = value; 21 | } 22 | 23 | [NotMapped] // Not put into DB 24 | public CustomerMetadata Metadata 25 | { 26 | get => _wrapper; 27 | set => _wrapper = value; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/Models/CustomerMetadata.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace FilterExtensionFor801.Models 7 | { 8 | public class CustomerMetadata 9 | { 10 | public IDictionary Dynamics { get; set; } = new Dictionary(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/Models/EdmModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.OData.Edm; 2 | using Microsoft.OData.ModelBuilder; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace FilterExtensionFor801.Models 9 | { 10 | public class EdmModelBuilder 11 | { 12 | public static IEdmModel GetEdmModel() 13 | { 14 | var builder = new ODataConventionModelBuilder(); 15 | builder.EntitySet("Customers"); 16 | 17 | builder.EntityType().Ignore(c => c.CustomMetadata); 18 | builder.EntityType().ComplexProperty(c => c.Metadata); 19 | 20 | return builder.GetEdmModel(); 21 | } 22 | 23 | public static IEdmModel GetEdmModel2() 24 | { 25 | var builder = new ODataConventionModelBuilder(); 26 | builder.EntitySet("Customers"); 27 | 28 | builder.EntityType().Property(c => c.CustomMetadata); 29 | // builder.EntityType().ComplexProperty(c => c.Metadata); 30 | 31 | return builder.GetEdmModel(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/Models/FilterDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace FilterExtensionFor801.Models 4 | { 5 | public class FilterDbContext : DbContext 6 | { 7 | public FilterDbContext(DbContextOptions options) 8 | : base(options) 9 | { 10 | 11 | } 12 | 13 | public DbSet Customers { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace FilterExtensionFor801 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:51477", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "FilterExtensionFor801": { 21 | "commandName": "Project", 22 | "dotnetRunMessages": "true", 23 | "launchBrowser": true, 24 | "launchUrl": "weatherforecast", 25 | "applicationUrl": "http://localhost:5000", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FilterExtensionFor801 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/FilterExtensionFor801/FilterExtensionFor801/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /src/IoCTest/IoCTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2042 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IoCTest", "IoCTest\IoCTest.csproj", "{CFD64C8F-9A5A-4963-A9B9-7999267A029D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {CFD64C8F-9A5A-4963-A9B9-7999267A029D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {CFD64C8F-9A5A-4963-A9B9-7999267A029D}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {CFD64C8F-9A5A-4963-A9B9-7999267A029D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {CFD64C8F-9A5A-4963-A9B9-7999267A029D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {BF814B04-5870-4344-97B7-680173ACADF7} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/IoCTest/IoCTest/InjectionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace IoCTest 6 | { 7 | [AttributeUsage(AttributeTargets.Constructor | 8 | AttributeTargets.Property | 9 | AttributeTargets.Method, 10 | AllowMultiple = false)] 11 | public class InjectionAttribute : Attribute 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/IoCTest/IoCTest/IoCTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/IoCTest/IoCTest/ServiceRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace IoCTest 6 | { 7 | public class ServiceRegistry 8 | { 9 | public Type ServiceType { get; } 10 | public Lifetime Lifetime { get; } 11 | public Func Factory { get; } 12 | internal ServiceRegistry Next { get; set; } 13 | 14 | public ServiceRegistry(Type serviceType, Lifetime lifetime, Func factory) 15 | { 16 | ServiceType = serviceType; 17 | Lifetime = lifetime; 18 | Factory = factory; 19 | } 20 | 21 | internal IEnumerable AsEnumerable() 22 | { 23 | var list = new List(); 24 | for (var self = this; self != null; self = self.Next) 25 | { 26 | list.Add(self); 27 | } 28 | return list; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ModelBuilderTest/ModelBuilderTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30021.99 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModelBuilderTest", "ModelBuilderTest\ModelBuilderTest.csproj", "{578C4B35-0492-42C9-B1B2-6C00EC961489}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {578C4B35-0492-42C9-B1B2-6C00EC961489}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {578C4B35-0492-42C9-B1B2-6C00EC961489}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {578C4B35-0492-42C9-B1B2-6C00EC961489}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {578C4B35-0492-42C9-B1B2-6C00EC961489}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {733836C9-5009-4B9E-86A3-F2FB8D7486BC} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/ModelBuilderTest/ModelBuilderTest/ModelBuilderTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net5.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/MyLearn/MyLearn.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29418.71 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLearn", "MyLearn\MyLearn.csproj", "{77C6775D-B087-4217-BEEB-F5ACA9223CD7}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {77C6775D-B087-4217-BEEB-F5ACA9223CD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {77C6775D-B087-4217-BEEB-F5ACA9223CD7}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {77C6775D-B087-4217-BEEB-F5ACA9223CD7}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {77C6775D-B087-4217-BEEB-F5ACA9223CD7}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {7FFA6B13-BB89-4B1A-BE71-A6DB4D7C99F3} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/MyLearn/MyLearn/ApplicationBuilderTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using Xunit; 6 | using Xunit.Abstractions; 7 | using Microsoft.AspNetCore.Builder; 8 | using Microsoft.AspNetCore.Http; 9 | using System.Threading.Tasks; 10 | 11 | namespace MyLearn 12 | { 13 | public class ApplicationBuilderTest 14 | { 15 | private readonly ITestOutputHelper _output; 16 | 17 | public ApplicationBuilderTest(ITestOutputHelper output) 18 | { 19 | this._output = output; 20 | } 21 | 22 | [Fact] 23 | public void Test() 24 | { 25 | ServiceProvider serviceProvider = new ServiceCollection().BuildServiceProvider(); 26 | 27 | ApplicationBuilder builder = new ApplicationBuilder(serviceProvider); 28 | 29 | var requestDelegate = builder.Build(); 30 | 31 | Assert.NotNull(requestDelegate); 32 | 33 | HttpContext context = new DefaultHttpContext(); 34 | Task task = requestDelegate.Invoke(context); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/MyLearn/MyLearn/Models/Models.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Text; 5 | 6 | namespace MyLearn.Models 7 | { 8 | public interface IFoo 9 | { } 10 | 11 | public interface IBar 12 | { } 13 | 14 | public interface IBaz 15 | { } 16 | 17 | public class Foo : Disposable, IFoo { } 18 | 19 | public class Bar : Disposable, IBar { } 20 | 21 | public class Baz : Disposable, IBaz { } 22 | 23 | public class Disposable : IDisposable 24 | { 25 | public void Dispose() 26 | { 27 | Debug.WriteLine($"{this.GetType()}.Dispose()"); 28 | } 29 | } 30 | 31 | public interface IFoobar : IDisposable 32 | { 33 | 34 | } 35 | 36 | public class Foobar : IFoobar 37 | { 38 | ~Foobar() 39 | { 40 | Debug.WriteLine("Foobar.Finalize()"); 41 | } 42 | 43 | public void Dispose() 44 | { 45 | Debug.WriteLine("Foobar.Dispose()"); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/MyLearn/MyLearn/MyLearn.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/MyLearn/MyLearn/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MyLearn 4 | { 5 | class Program 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/MyLearn/MyLearn/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:7525/", 7 | "sslPort": 44353 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "MyLearn": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/MyLearn/MyLearn/ServiceDescriptorTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using MyLearn.Models; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using Xunit; 7 | 8 | namespace MyLearn 9 | { 10 | public class ServiceDescriptorTests 11 | { 12 | [Fact] 13 | public void TestConstructor() 14 | { 15 | var serviceDescriptor = new ServiceDescriptor(typeof(IFoo), typeof(Foo), ServiceLifetime.Scoped); 16 | 17 | Assert.NotNull(serviceDescriptor.ServiceType); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.1.31911.260 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NewQueryOptionIn8", "NewQueryOptionIn8\NewQueryOptionIn8.csproj", "{84DBAE8D-F268-48C8-B451-7AE4A6A9A698}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {84DBAE8D-F268-48C8-B451-7AE4A6A9A698}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {84DBAE8D-F268-48C8-B451-7AE4A6A9A698}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {84DBAE8D-F268-48C8-B451-7AE4A6A9A698}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {84DBAE8D-F268-48C8-B451-7AE4A6A9A698}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {8FC696A5-96FE-4FDF-9B8C-3A89B8326EE2} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/Controllers/ProductsController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.OData.Query; 3 | using NewQueryOptionIn8.Models; 4 | 5 | namespace NewQueryOptionIn8.Controllers 6 | { 7 | public class ProductsController : Controller 8 | { 9 | IProductSaleRepository _repository; 10 | 11 | public ProductsController(IProductSaleRepository repo) 12 | { 13 | _repository = repo; 14 | } 15 | 16 | [EnableQuery] 17 | public IActionResult Get() 18 | { 19 | return Ok(_repository.Products); 20 | } 21 | 22 | [EnableQuery] 23 | public IActionResult Get(int key) 24 | { 25 | return Ok(_repository.Products.FirstOrDefault(p => p.Id == key)); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/Controllers/SalesController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.OData.Query; 3 | using NewQueryOptionIn8.Models; 4 | 5 | namespace NewQueryOptionIn8.Controllers 6 | { 7 | public class SalesController : Controller 8 | { 9 | IProductSaleRepository _repository; 10 | 11 | public SalesController(IProductSaleRepository repo) 12 | { 13 | _repository = repo; 14 | } 15 | 16 | [EnableQuery] 17 | public IActionResult Get() 18 | { 19 | return Ok(_repository.Sales); 20 | } 21 | 22 | [EnableQuery] 23 | public IActionResult Get(int key) 24 | { 25 | return Ok(_repository.Sales.FirstOrDefault(s => s.Id == key)); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace NewQueryOptionIn8.Controllers 4 | { 5 | [ApiController] 6 | [Route("[controller]")] 7 | public class WeatherForecastController : ControllerBase 8 | { 9 | private static readonly string[] Summaries = new[] 10 | { 11 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 12 | }; 13 | 14 | private readonly ILogger _logger; 15 | 16 | public WeatherForecastController(ILogger logger) 17 | { 18 | _logger = logger; 19 | } 20 | 21 | [HttpGet] 22 | public IEnumerable Get() 23 | { 24 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 25 | { 26 | Date = DateTime.Now.AddDays(index), 27 | TemperatureC = Random.Shared.Next(-20, 55), 28 | Summary = Summaries[Random.Shared.Next(Summaries.Length)] 29 | }) 30 | .ToArray(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/Models/IProductSaleRepository.cs: -------------------------------------------------------------------------------- 1 | namespace NewQueryOptionIn8.Models 2 | { 3 | public interface IProductSaleRepository 4 | { 5 | IEnumerable Products { get; } 6 | 7 | IEnumerable Sales { get; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/Models/ModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.OData.Edm; 2 | using Microsoft.OData.ModelBuilder; 3 | 4 | namespace NewQueryOptionIn8.Models 5 | { 6 | public class ModelBuilder 7 | { 8 | public static IEdmModel GetEdmModel() 9 | { 10 | var builder = new ODataConventionModelBuilder(); 11 | builder.EntitySet("Products"); 12 | builder.EntitySet("Sales"); 13 | return builder.GetEdmModel(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/Models/Product.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.OData.Edm; 2 | 3 | namespace NewQueryOptionIn8.Models 4 | { 5 | public class Product 6 | { 7 | public int Id { get; set; } 8 | 9 | public string Name { get; set; } 10 | 11 | public Category Category { get; set; } 12 | 13 | public Color Color { get; set; } 14 | 15 | public Address Location { get; set; } 16 | 17 | public double Price { get; set; } 18 | 19 | public int Qty { get; set; } 20 | 21 | public double TaxRate { get; set; } 22 | 23 | public IList Sales { get; set; } 24 | } 25 | 26 | public class Sale 27 | { 28 | public int Id { get; set; } 29 | 30 | public Date SaleDate { get; set; } 31 | 32 | public int ProductId { get; set; } 33 | 34 | public int Amount { get; set; } 35 | } 36 | 37 | public class Address 38 | { 39 | public string Street { get; set; } 40 | 41 | public string City { get; set; } 42 | 43 | public int ZipCode { get; set; } 44 | } 45 | 46 | public enum Category 47 | { 48 | Food, 49 | 50 | Office, 51 | 52 | Music 53 | } 54 | 55 | public enum Color 56 | { 57 | Red, 58 | 59 | Yellow, 60 | 61 | Blue, 62 | 63 | Brown, 64 | 65 | White 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/NewQueryOptionIn8.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.OData; 2 | using Microsoft.AspNetCore.OData.Query.Expressions; 3 | using NewQueryOptionIn8.Extensions; 4 | using NewQueryOptionIn8.Models; 5 | 6 | var builder = WebApplication.CreateBuilder(args); 7 | 8 | // Add services to the container. 9 | 10 | builder.Services.AddScoped(); 11 | 12 | builder.Services.AddControllers(). 13 | AddOData(opt => opt.EnableQueryFeatures() 14 | .AddRouteComponents("odata", ModelBuilder.GetEdmModel(), services => services.AddSingleton())); 15 | 16 | var app = builder.Build(); 17 | 18 | // Configure the HTTP request pipeline. 19 | 20 | app.UseAuthorization(); 21 | 22 | app.MapControllers(); 23 | 24 | app.Run(); 25 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:22984", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "NewQueryOptionIn8": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "weatherforecast", 17 | "applicationUrl": "http://localhost:5102", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "weatherforecast", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | namespace NewQueryOptionIn8 2 | { 3 | public class WeatherForecast 4 | { 5 | public DateTime Date { get; set; } 6 | 7 | public int TemperatureC { get; set; } 8 | 9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 10 | 11 | public string Summary { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/NewQueryOptionIn8/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /src/NewQueryOptionIn8/readme.md: -------------------------------------------------------------------------------- 1 | # NewQueryOptionIn8 2 | 3 | This project is for the $compute and $search post. Feel free to leave your comments and questions. 4 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31410.223 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ODataApiVersion", "ODataApiVersion\ODataApiVersion.csproj", "{07ADE90C-5D5C-469E-9CD0-D6DF157260D3}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {07ADE90C-5D5C-469E-9CD0-D6DF157260D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {07ADE90C-5D5C-469E-9CD0-D6DF157260D3}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {07ADE90C-5D5C-469E-9CD0-D6DF157260D3}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {07ADE90C-5D5C-469E-9CD0-D6DF157260D3}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {CE26E987-79A9-4E5C-B491-44270DC4440B} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace ODataApiVersion.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/Controllers/v1/CustomersController.cs: -------------------------------------------------------------------------------- 1 | // Copyright saxu@microsoft.com. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System.Linq; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.AspNetCore.OData.Query; 7 | using Microsoft.AspNetCore.OData.Routing.Controllers; 8 | using ODataApiVersion.Models.v1; 9 | 10 | namespace ODataApiVersion.Controllers.v1 11 | { 12 | [ApiVersion("1.0")] 13 | public class CustomersController : ODataController 14 | { 15 | private Customer[] customers = new Customer[] 16 | { 17 | new Customer 18 | { 19 | Id = 1, 20 | ApiVersion = "v1.0", 21 | Name = "Sam", 22 | PhoneNumber = "111-222-3333" 23 | }, 24 | new Customer 25 | { 26 | Id = 2, 27 | ApiVersion = "v1.0", 28 | Name = "Peter", 29 | PhoneNumber = "456-ABC-8888" 30 | } 31 | }; 32 | 33 | [EnableQuery] 34 | public IActionResult Get() 35 | { 36 | return Ok(customers); 37 | } 38 | 39 | [EnableQuery] 40 | public IActionResult Get(int key) 41 | { 42 | var customer = customers.FirstOrDefault(c => c.Id == key); 43 | if (customer == null) 44 | { 45 | return NotFound($"Cannot find customer with Id={key}."); 46 | } 47 | 48 | return Ok(customer); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/Extensions/IODataModelProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright saxu@microsoft.com. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.OData.Edm; 5 | 6 | namespace ODataApiVersion.Extensions 7 | { 8 | public interface IODataModelProvider 9 | { 10 | IEdmModel GetEdmModel(string apiVersion); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/Models/CustomerBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright saxu@microsoft.com. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace ODataApiVersion.Models 5 | { 6 | public abstract class CustomerBase 7 | { 8 | public int Id { get; set; } 9 | 10 | public string ApiVersion { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/Models/v1/Customer.cs: -------------------------------------------------------------------------------- 1 | // Copyright saxu@microsoft.com. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace ODataApiVersion.Models.v1 5 | { 6 | public class Customer : CustomerBase 7 | { 8 | public string Name { get; set; } 9 | 10 | public string PhoneNumber { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/Models/v2/Customer.cs: -------------------------------------------------------------------------------- 1 | // Copyright saxu@microsoft.com. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace ODataApiVersion.Models.v2 5 | { 6 | public class Customer : CustomerBase 7 | { 8 | public string FirstName { get; set; } 9 | 10 | public string LastName { get; set; } 11 | 12 | public string Email { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/ODataApiVersion.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace ODataApiVersion 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:33545", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "ODataApiVersion": { 21 | "commandName": "Project", 22 | "dotnetRunMessages": "true", 23 | "launchBrowser": true, 24 | "launchUrl": "weatherforecast", 25 | "applicationUrl": "http://localhost:5000", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ODataApiVersion 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/ODataApiVersion/ODataApiVersion/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /src/ODataApiVersion/Readme.md: -------------------------------------------------------------------------------- 1 | # ASP.NET Core OData (8.x) API Versioning Sample 2 | 3 | --- 4 | This is the project repository for post at: https://devblogs.microsoft.com/odata/api-versioning-extension-with-asp-net-core-odata-8/ 5 | 6 | For details, please refer to the post. 7 | 8 | ## Update at 12/21/2021 9 | 10 | Enable OpenAPI/Swagger via customer requirement. 11 | 12 | ### OpenAPI/Swagger 13 | 14 | If you run the sample and send the following request in a Web brower: 15 | 16 | `/swagger`, you will get the following (similar) swagger page: 17 | 18 | ![image](../../Images/api_versioning_swagger.png) 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborClient/Connected Services/OData Service/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.OData.ConnectedService", 3 | "Version": "1.0.0.0", 4 | "GettingStartedDocument": { 5 | "Uri": "http://odata.github.io/odata.net/" 6 | }, 7 | "ExtendedData": { 8 | "EnableNamingAlias": true, 9 | "IgnoreUnexpectedElementsAndAttributes": true, 10 | "IncludeT4File": false, 11 | "ExcludedOperationImports": [], 12 | "ExcludedBoundOperations": [], 13 | "ServiceName": "OData Service", 14 | "Endpoint": "http://localhost:5015/odata/$metadata", 15 | "EdmxVersion": { 16 | "Major": 4, 17 | "Minor": 0, 18 | "Build": 0, 19 | "Revision": 0, 20 | "MajorRevision": 0, 21 | "MinorRevision": 0 22 | }, 23 | "GeneratedFileNamePrefix": "Reference", 24 | "UseNamespacePrefix": false, 25 | "NamespacePrefix": null, 26 | "UseDataServiceCollection": true, 27 | "MakeTypesInternal": false, 28 | "OpenGeneratedFilesInIDE": false, 29 | "GenerateMultipleFiles": false, 30 | "CustomHttpHeaders": null, 31 | "IncludeWebProxy": false, 32 | "WebProxyHost": null, 33 | "IncludeWebProxyNetworkCredentials": false, 34 | "StoreWebProxyNetworkCredentials": false, 35 | "WebProxyNetworkCredentialsUsername": null, 36 | "WebProxyNetworkCredentialsPassword": null, 37 | "WebProxyNetworkCredentialsDomain": null, 38 | "IncludeCustomHeaders": false, 39 | "StoreCustomHttpHeaders": false, 40 | "ExcludedSchemaTypes": [] 41 | } 42 | } -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborClient/Connected Services/OData Service/OData ServiceCsdl.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborClient/ODataCborClient.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborClient/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | using ODataCborClient; 3 | 4 | 5 | 6 | ODataClient client = new ODataClient(@"http://localhost:5015/odata/"); 7 | 8 | Console.WriteLine("----------- List books by default!"); 9 | 10 | await client.ListBooks(); 11 | 12 | Console.WriteLine("----------- Press any key to list books using CBOR!"); 13 | Console.ReadKey(); 14 | 15 | await client.ListBooks("application/cbor"); 16 | 17 | Console.WriteLine("Press any key to quit!"); 18 | Console.ReadKey(); -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace ODataCborExample.Controllers 4 | { 5 | [ApiController] 6 | [Route("[controller]")] 7 | public class WeatherForecastController : ControllerBase 8 | { 9 | private static readonly string[] Summaries = new[] 10 | { 11 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 12 | }; 13 | 14 | private readonly ILogger _logger; 15 | 16 | public WeatherForecastController(ILogger logger) 17 | { 18 | _logger = logger; 19 | } 20 | 21 | [HttpGet] 22 | public IEnumerable Get() 23 | { 24 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 25 | { 26 | Date = DateTime.Now.AddDays(index), 27 | TemperatureC = Random.Shared.Next(-20, 55), 28 | Summary = Summaries[Random.Shared.Next(Summaries.Length)] 29 | }) 30 | .ToArray(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/Extensions/CborLoggerMiddleware.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace ODataCborExample.Extensions 4 | { 5 | public class CborLoggerMiddleware 6 | { 7 | private RequestDelegate _next; 8 | 9 | public CborLoggerMiddleware(RequestDelegate next) 10 | { 11 | _next = next; 12 | } 13 | 14 | public async Task InvokeAsync(HttpContext context, IMessageWriter writer) 15 | { 16 | var accept = context.Request.Headers.Accept.First().Split(';').First(); 17 | Stopwatch stopwatch = Stopwatch.StartNew(); 18 | stopwatch.Start(); 19 | 20 | await _next(context); 21 | 22 | stopwatch.Stop(); 23 | writer.Write($"{accept} spends {stopwatch.ElapsedMilliseconds}ms."); 24 | } 25 | } 26 | 27 | public static class MyCborLoggerExtensions 28 | { 29 | public static IApplicationBuilder UseMyCborLogger( 30 | this IApplicationBuilder builder) 31 | { 32 | return builder.UseMiddleware(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/Extensions/CborMediaTypeResolver.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | using Microsoft.OData; 8 | 9 | namespace ODataCborExample.Extensions 10 | { 11 | public class CborMediaTypeResolver : ODataMediaTypeResolver 12 | { 13 | private readonly ODataMediaTypeFormat[] _mediaTypeFormats = 14 | { 15 | new ODataMediaTypeFormat(new ODataMediaType("application", "cbor"), ODataFormat.Json) 16 | }; 17 | 18 | public override IEnumerable GetMediaTypeFormats(ODataPayloadKind payloadKind) 19 | { 20 | if (payloadKind == ODataPayloadKind.Resource || payloadKind == ODataPayloadKind.ResourceSet) 21 | { 22 | return _mediaTypeFormats.Concat(base.GetMediaTypeFormats(payloadKind)); 23 | } 24 | 25 | return base.GetMediaTypeFormats(payloadKind); 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/Extensions/IMessageWriter.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | 8 | namespace ODataCborExample.Extensions 9 | { 10 | // copied from ASP.NET Core doc 11 | public interface IMessageWriter 12 | { 13 | void Write(string message); 14 | } 15 | 16 | public class LoggingMessageWriter : IMessageWriter 17 | { 18 | 19 | private readonly ILogger _logger; 20 | 21 | public LoggingMessageWriter(ILogger logger) => 22 | _logger = logger; 23 | 24 | public void Write(string message) => 25 | _logger.LogInformation(message); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/Models/Book.cs: -------------------------------------------------------------------------------- 1 | namespace ODataCborExample.Models 2 | { 3 | public class Book 4 | { 5 | public int Id { get; set; } 6 | 7 | public string Title { get; set; } 8 | 9 | public string Author { get; set; } 10 | 11 | public string ISBN { get; set; } 12 | 13 | public int Pages { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/Models/EdmModelBuilder.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //--------------------------------------------------------------------- 6 | 7 | using Microsoft.OData.Edm; 8 | using Microsoft.OData.ModelBuilder; 9 | 10 | namespace ODataCborExample.Models; 11 | 12 | public static class EdmModelBuilder 13 | { 14 | public static IEdmModel GetEdmModel() 15 | { 16 | var builder = new ODataConventionModelBuilder(); 17 | builder.EntitySet("Books"); 18 | return builder.GetEdmModel(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/ODataCborExample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | disable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:21482", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "ODataCborExample": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "$odata", 17 | "applicationUrl": "http://localhost:5015", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "weatherforecast", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | namespace ODataCborExample 2 | { 3 | public class WeatherForecast 4 | { 5 | public DateTime Date { get; set; } 6 | 7 | public int TemperatureC { get; set; } 8 | 9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 10 | 11 | public string? Summary { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/ODataCborExample/ODataCborExample/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /src/ODataCborExample/readme.md: -------------------------------------------------------------------------------- 1 | # ODataCborExample 2 | 3 | This project is for the CBOR OData payload format post. 4 | Feel free to leave your comments and questions. 5 | 6 | 7 | Post is at: https://devblogs.microsoft.com/odata/ 8 | 9 | 10 | ## Writing test 11 | 12 | If i send the "GET http://localhost:5015/odata/books" with and without accept=application/cbor, 13 | 14 | I can get the following result: 15 | 16 | ![image](https://user-images.githubusercontent.com/9426627/236030268-eb7879dc-6e55-4990-9262-e2f29e40d554.png) 17 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.33209.295 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ODataCustomizePayloadFormat", "ODataCustomizePayloadFormat\ODataCustomizePayloadFormat.csproj", "{3FFE08BE-B643-42C8-9549-CEB4FFD7E5F8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3FFE08BE-B643-42C8-9549-CEB4FFD7E5F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3FFE08BE-B643-42C8-9549-CEB4FFD7E5F8}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3FFE08BE-B643-42C8-9549-CEB4FFD7E5F8}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3FFE08BE-B643-42C8-9549-CEB4FFD7E5F8}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {1F5DBBE0-C54E-41B1-A8B0-F3649C229B84} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/Extensions/Csv/CsvMediaTypeResolver.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //--------------------------------------------------------------------- 6 | 7 | using Microsoft.OData; 8 | 9 | namespace ODataCustomizePayloadFormat.Extensions.Csv; 10 | 11 | /// 12 | /// Keep this class for the post reference. 13 | /// Please refer to the for all type resolver. 14 | /// 15 | public class CsvMediaTypeResolver : ODataMediaTypeResolver 16 | { 17 | private static readonly CsvMediaTypeResolver _instance = new CsvMediaTypeResolver(); 18 | 19 | private readonly ODataMediaTypeFormat[] _mediaTypeFormats = 20 | { 21 | new ODataMediaTypeFormat(new ODataMediaType("text", "csv"), new CsvFormat()), 22 | }; 23 | 24 | public static CsvMediaTypeResolver Instance => _instance; 25 | 26 | public override IEnumerable GetMediaTypeFormats(ODataPayloadKind payloadKind) 27 | { 28 | if (payloadKind == ODataPayloadKind.Resource || payloadKind == ODataPayloadKind.ResourceSet) 29 | { 30 | return _mediaTypeFormats.Concat(base.GetMediaTypeFormats(payloadKind)); 31 | } 32 | 33 | return base.GetMediaTypeFormats(payloadKind); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/Extensions/CustomizedMediaTypeResolver.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //--------------------------------------------------------------------- 6 | 7 | using Microsoft.OData; 8 | using ODataCustomizePayloadFormat.Extensions.Csv; 9 | 10 | namespace ODataCustomizePayloadFormat.Extensions; 11 | 12 | public class CustomizedMediaTypeResolver : ODataMediaTypeResolver 13 | { 14 | private static CustomizedFormat _customizedFormat = new CustomizedFormat(); 15 | 16 | private readonly ODataMediaTypeFormat[] _mediaTypeFormats = 17 | { 18 | new ODataMediaTypeFormat(new ODataMediaType("text", "csv"), new CsvFormat()), 19 | new ODataMediaTypeFormat(new ODataMediaType("application", "yaml"), _customizedFormat), 20 | new ODataMediaTypeFormat(new ODataMediaType("application", "cbor"), _customizedFormat) 21 | }; 22 | 23 | public override IEnumerable GetMediaTypeFormats(ODataPayloadKind payloadKind) 24 | { 25 | if (payloadKind == ODataPayloadKind.Resource || payloadKind == ODataPayloadKind.ResourceSet) 26 | { 27 | return _mediaTypeFormats.Concat(base.GetMediaTypeFormats(payloadKind)); 28 | } 29 | 30 | return base.GetMediaTypeFormats(payloadKind); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/Models/Address.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //--------------------------------------------------------------------- 6 | 7 | namespace ODataCustomizePayloadFormat.Models; 8 | 9 | public class Address 10 | { 11 | public string City { get; set; } 12 | 13 | public string Street { get; set; } 14 | } 15 | 16 | public class CnAddress : Address 17 | { 18 | public string Postcode { get; set; } 19 | } 20 | 21 | public class UsAddress : Address 22 | { 23 | public string Zipcode { get; set; } 24 | } 25 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/Models/Book.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //--------------------------------------------------------------------- 6 | 7 | namespace ODataCustomizePayloadFormat.Models 8 | { 9 | public class Book 10 | { 11 | public int Id { get; set; } 12 | 13 | public string Title { get; set; } 14 | 15 | public string Author { get; set; } 16 | 17 | public string ISBN { get; set; } 18 | 19 | public int Pages { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/Models/Customer.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //--------------------------------------------------------------------- 6 | 7 | namespace ODataCustomizePayloadFormat.Models; 8 | 9 | public class Customer 10 | { 11 | public int Id { get; set; } 12 | 13 | public string Name { get; set; } 14 | 15 | public Color FavoriteColor { get; set; } 16 | 17 | public IList Tokens { get; set; } 18 | 19 | public int Amount { get; set; } 20 | 21 | public virtual Address HomeAddress { get; set; } 22 | 23 | public virtual IList
FavoriteAddresses { get; set; } 24 | } 25 | 26 | public enum Color 27 | { 28 | Red, 29 | Green, 30 | Blue 31 | } -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/Models/EdmModelBuilder.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //--------------------------------------------------------------------- 6 | 7 | using Microsoft.OData.Edm; 8 | using Microsoft.OData.ModelBuilder; 9 | 10 | namespace ODataCustomizePayloadFormat.Models; 11 | 12 | public static class EdmModelBuilder 13 | { 14 | public static IEdmModel GetEdmModel() 15 | { 16 | var builder = new ODataConventionModelBuilder(); 17 | builder.EntitySet("Books"); 18 | builder.EntitySet("Customers"); 19 | return builder.GetEdmModel(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | disable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.OData; 2 | using Microsoft.AspNetCore.OData.Formatter; 3 | using Microsoft.OData; 4 | using ODataCustomizePayloadFormat.Extensions; 5 | using ODataCustomizePayloadFormat.Models; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | 9 | // Add services to the container. 10 | 11 | builder.Services.AddControllers(). 12 | AddOData(opt => 13 | opt.EnableQueryFeatures() 14 | .AddRouteComponents("odata", EdmModelBuilder.GetEdmModel(), 15 | service => service.AddSingleton(sp => new CustomizedMediaTypeResolver()))); 16 | // service => service.AddSingleton(sp => CsvMediaTypeResolver.Instance))); // keep here for post reference 17 | 18 | builder.Services.AddControllers(opt => 19 | { 20 | var odataFormatter = opt.OutputFormatters.OfType().First(); 21 | odataFormatter.SupportedMediaTypes.Add("text/csv"); 22 | odataFormatter.SupportedMediaTypes.Add("application/yaml"); 23 | odataFormatter.SupportedMediaTypes.Add("application/cbor"); 24 | }); 25 | 26 | var app = builder.Build(); 27 | 28 | // Configure the HTTP request pipeline. 29 | 30 | app.UseODataRouteDebug(); 31 | 32 | app.UseAuthorization(); 33 | 34 | app.MapControllers(); 35 | 36 | app.Run(); 37 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:57245", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "ODataCsvExample": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "$odata", 17 | "applicationUrl": "http://localhost:5296", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "$odata", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/ODataCustomizePayloadFormat/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /src/ODataCustomizePayloadFormat/readme.md: -------------------------------------------------------------------------------- 1 | # ODataCustomizePayloadFormat 2 | 3 | This project is for the CSV, YAML customized OData payload format post. 4 | Feel free to leave your comments and questions. 5 | 6 | 7 | ## CSV/YAML Writer 8 | 9 | See details at: https://devblogs.microsoft.com/odata/customize-odata-payload-serialization-format-within-asp-net-core-odata/ 10 | 11 | ## CSV Reader 12 | 13 | ### POST http://localhost:5296/odata/books 14 | 15 | ![image](https://user-images.githubusercontent.com/9426627/228117623-a887c4fa-d55f-4bfb-8faa-7545eaba26ee.png) 16 | 17 | ### Debug 18 | 19 | ![image](https://user-images.githubusercontent.com/9426627/228117836-0b958629-61a7-458f-9682-357e8ae7f985.png) 20 | 21 | 22 | ## YAML Reader 23 | 24 | ### POST http://localhost:5296/odata/books 25 | 26 | ![image](https://user-images.githubusercontent.com/9426627/228117956-b39ad8dd-87fd-45f4-8a72-578fe8390709.png) 27 | 28 | ### Debug 29 | 30 | ![image](https://user-images.githubusercontent.com/9426627/228118009-9bda6abc-8ad5-45fc-a38a-8c451183ee05.png) 31 | 32 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagClient/Connected Services/OData Service/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.OData.ConnectedService", 3 | "Version": "0.12.1.0", 4 | "GettingStartedDocument": { 5 | "Uri": "http://odata.github.io/odata.net/" 6 | }, 7 | "ExtendedData": { 8 | "EnableNamingAlias": true, 9 | "IgnoreUnexpectedElementsAndAttributes": true, 10 | "IncludeT4File": false, 11 | "ExcludedOperationImports": [], 12 | "ExcludedBoundOperations": [], 13 | "ServiceName": "OData Service", 14 | "Endpoint": "http://localhost:5000/odata/$metadata", 15 | "EdmxVersion": { 16 | "Major": 4, 17 | "Minor": 0, 18 | "Build": 0, 19 | "Revision": 0, 20 | "MajorRevision": 0, 21 | "MinorRevision": 0 22 | }, 23 | "GeneratedFileNamePrefix": "Reference", 24 | "UseNamespacePrefix": false, 25 | "NamespacePrefix": null, 26 | "UseDataServiceCollection": true, 27 | "MakeTypesInternal": false, 28 | "OpenGeneratedFilesInIDE": false, 29 | "GenerateMultipleFiles": false, 30 | "CustomHttpHeaders": null, 31 | "IncludeWebProxy": false, 32 | "WebProxyHost": null, 33 | "IncludeWebProxyNetworkCredentials": false, 34 | "WebProxyNetworkCredentialsUsername": null, 35 | "WebProxyNetworkCredentialsPassword": null, 36 | "WebProxyNetworkCredentialsDomain": null, 37 | "IncludeCustomHeaders": false, 38 | "ExcludedSchemaTypes": [] 39 | } 40 | } -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagClient/Connected Services/OData Service/OData ServiceCsdl.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagClient/Customer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ODataETagWebApi.Models 8 | { 9 | public partial class Customer 10 | { 11 | public Guid Label { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagClient/ODataETagClient.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net5.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace ODataETagWebApi.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/Extensions/ETagDeserializerProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.OData.Formatter.Deserialization; 3 | using Microsoft.OData.Edm; 4 | 5 | namespace ODataETagWebApi.Extensions 6 | { 7 | public class ETagDeserializerProvider : ODataDeserializerProvider 8 | { 9 | public ETagDeserializerProvider(IServiceProvider serviceProvider) 10 | : base(serviceProvider) 11 | { } 12 | 13 | public override IODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType, bool isDelta = false) 14 | { 15 | if (edmType.IsEntity() || edmType.IsComplex()) 16 | { 17 | return new ETagResourceDeserializer(this); 18 | } 19 | 20 | return base.GetEdmTypeDeserializer(edmType, isDelta); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/Extensions/ETagResourceSerializer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.OData.Formatter; 2 | using Microsoft.AspNetCore.OData.Formatter.Serialization; 3 | using Microsoft.AspNetCore.OData.Formatter.Value; 4 | using Microsoft.OData; 5 | using ODataETagWebApi.Models; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace ODataETagWebApi.Extensions 13 | { 14 | public class ETagResourceSerializer : ODataResourceSerializer 15 | { 16 | public ETagResourceSerializer(IODataSerializerProvider serializerProvider) 17 | : base(serializerProvider) 18 | { } 19 | 20 | public override ODataResource CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext) 21 | { 22 | ODataResource resource = base.CreateResource(selectExpandNode, resourceContext); 23 | 24 | if (resource.ETag == null && resourceContext.ResourceInstance is Customer c) 25 | { 26 | resource.ETag = EncodeETag(c.Label); 27 | } 28 | 29 | return resource; 30 | } 31 | 32 | private static string EncodeETag(Guid guid) 33 | { 34 | byte[] bytes = Encoding.UTF8.GetBytes(guid.ToString()); 35 | return Convert.ToBase64String(bytes); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/Extensions/ETagSerializerProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.OData.Formatter.Serialization; 3 | using Microsoft.OData.Edm; 4 | 5 | namespace ODataETagWebApi.Extensions 6 | { 7 | public class ETagSerializerProvider : ODataSerializerProvider 8 | { 9 | public ETagSerializerProvider(IServiceProvider serviceProvider) 10 | : base(serviceProvider) 11 | { } 12 | 13 | public override IODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType) 14 | { 15 | if (edmType.IsEntity() || edmType.IsComplex()) 16 | { 17 | return new ETagResourceSerializer(this); 18 | } 19 | 20 | return base.GetEdmTypeSerializer(edmType); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/Models/Customer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace ODataETagWebApi.Models 7 | { 8 | public class Customer 9 | { 10 | public int Id { get; set; } 11 | 12 | public string Name { get; set; } 13 | 14 | public Guid Label { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/ODataETagWebApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace ODataETagWebApi 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:21538", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "odata/$metadata", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "ODataETagWebApi": { 21 | "commandName": "Project", 22 | "dotnetRunMessages": "true", 23 | "launchBrowser": true, 24 | "launchUrl": "odata/$metadata", 25 | "applicationUrl": "http://localhost:5000", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ODataETagWebApi 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/ODataETagExtensions/ODataETagWebApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufClient/ODataProtobufClient.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | disable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | Client 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufClient/Protos/bookstore.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package bookstores; 4 | import "google/protobuf/empty.proto"; 5 | 6 | service Bookstore { 7 | // Returns a list of all shelves in the bookstore. 8 | rpc Shelves(google.protobuf.Empty) returns (ListShelvesResponse) {} 9 | } 10 | 11 | // A shelf resource. 12 | message Shelf { 13 | optional int64 id = 1; 14 | optional string theme = 2; 15 | repeated Book books = 3; 16 | } 17 | 18 | // A book resource. 19 | message Book { 20 | optional int64 id = 1; 21 | optional string author = 2; 22 | optional string title = 3; 23 | optional string isbn = 4; 24 | optional int32 page = 5; 25 | } 26 | 27 | // Response to ListShelves call. 28 | message ListShelvesResponse { 29 | // Shelves in the bookstore. 30 | repeated Shelf shelves = 1; 31 | } 32 | -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace ODataProtobufExample.Controllers 4 | { 5 | [ApiController] 6 | [Route("[controller]")] 7 | public class WeatherForecastController : ControllerBase 8 | { 9 | private static readonly string[] Summaries = new[] 10 | { 11 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 12 | }; 13 | 14 | private readonly ILogger _logger; 15 | 16 | public WeatherForecastController(ILogger logger) 17 | { 18 | _logger = logger; 19 | } 20 | 21 | [HttpGet] 22 | public IEnumerable Get() 23 | { 24 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 25 | { 26 | Date = DateTime.Now.AddDays(index), 27 | TemperatureC = Random.Shared.Next(-20, 55), 28 | Summary = Summaries[Random.Shared.Next(Summaries.Length)] 29 | }) 30 | .ToArray(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/Extensions/ProtobufInputContext.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //--------------------------------------------------------------------- 6 | 7 | using Microsoft.OData.Edm; 8 | using Microsoft.OData; 9 | 10 | namespace ODataProtobufExample.Protobuf; 11 | 12 | public class ProtobufInputContext : ODataInputContext 13 | { 14 | public ProtobufInputContext(ODataFormat format, 15 | ODataMessageReaderSettings settings, ODataMessageInfo messageInfo) 16 | : base(format, messageInfo, settings) 17 | { 18 | MessageStream = messageInfo.MessageStream; 19 | } 20 | 21 | public Stream MessageStream { get; private set; } 22 | 23 | public override Task CreateResourceSetReaderAsync(IEdmEntitySetBase entitySet, IEdmStructuredType resourceType) 24 | => Task.FromResult(new ProtobufReader(this, resourceType)); 25 | 26 | public override Task CreateResourceReaderAsync(IEdmNavigationSource navigationSource, IEdmStructuredType resourceType) 27 | => Task.FromResult(new ProtobufReader(this, resourceType)); 28 | } 29 | -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/Extensions/ProtobufMediaTypeResolver.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //--------------------------------------------------------------------- 6 | 7 | using Microsoft.OData; 8 | 9 | namespace ODataProtobufExample.Protobuf; 10 | 11 | /// 12 | /// Keep this class for the post reference. 13 | /// 14 | public class ProtobufMediaTypeResolver : ODataMediaTypeResolver 15 | { 16 | private readonly ODataMediaTypeFormat[] _mediaTypeFormats = 17 | { 18 | new ODataMediaTypeFormat(new ODataMediaType("application", "x-protobuf"), new ProtobufFormat()), 19 | }; 20 | 21 | public override IEnumerable GetMediaTypeFormats(ODataPayloadKind payloadKind) 22 | { 23 | if (payloadKind == ODataPayloadKind.Resource || payloadKind == ODataPayloadKind.ResourceSet) 24 | { 25 | return _mediaTypeFormats.Concat(base.GetMediaTypeFormats(payloadKind)); 26 | } 27 | 28 | return base.GetMediaTypeFormats(payloadKind); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/Models/ModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.OData.Edm; 2 | using Microsoft.OData.ModelBuilder; 3 | 4 | namespace Bookstores // keep the same namespace 5 | { 6 | public static class ModelBuilder 7 | { 8 | public static IEdmModel GetEdmModel() 9 | { 10 | var builder = new ODataConventionModelBuilder(); 11 | builder.EntitySet("Shelves"); 12 | builder.EntitySet("Books"); 13 | return builder.GetEdmModel(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/Models/Shelf.cs: -------------------------------------------------------------------------------- 1 | namespace Bookstores // keep the same namespace 2 | { 3 | //public sealed partial class Shelf 4 | //{ 5 | // public IList Books1 { get; set; } 6 | //} 7 | } -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/ODataProtobufExample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | disable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:12547", 8 | "sslPort": 44355 9 | } 10 | }, 11 | "profiles": { 12 | "ODataProtobufExample": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "weatherforecast", 17 | "applicationUrl": "http://localhost:5023;https://localhost:5024", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "weatherforecast", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/Protos/bookstore.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package bookstores; 4 | 5 | // A shelf resource. 6 | message Shelf { 7 | optional int64 id = 1; 8 | optional string theme = 2; 9 | repeated Book books = 3; 10 | } 11 | 12 | // A book resource. 13 | message Book { 14 | optional int64 id = 1; 15 | optional string author = 2; 16 | optional string title = 3; 17 | optional string isbn = 4; 18 | optional int32 page = 5; 19 | } 20 | -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | namespace ODataProtobufExample 2 | { 3 | public class WeatherForecast 4 | { 5 | public DateTime Date { get; set; } 6 | 7 | public int TemperatureC { get; set; } 8 | 9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 10 | 11 | public string Summary { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/ODataProtobufExample/ODataProtobufExample/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/ODataProtobufExample/Readme.md: -------------------------------------------------------------------------------- 1 | # ODataProtobufExample 2 | 3 | This project is for the protobuf customized OData payload format. Feel free to leave your comments and questions. 4 | 5 | ## Protobuf writer 6 | 7 | GET http://localhost:5023/odata/Shelves?$expand=Books 8 | 9 | image 10 | 11 | If you specify the Accept header as below, you can get: 12 | 13 | image 14 | 15 | ## Protobuf reader 16 | 17 | POST http://localhost:5023/odata/shelves 18 | 19 | ![image](https://user-images.githubusercontent.com/9426627/232617632-dbe361e5-fb0a-4158-8e68-61e890f2585a.png) 20 | 21 | Here's the response: 22 | image 23 | 24 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.32804.182 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmitNullPropertySample", "OmitNullPropertySample\OmitNullPropertySample.csproj", "{B68806D6-1E20-4EDA-B42C-3D031A4078CB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B68806D6-1E20-4EDA-B42C-3D031A4078CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B68806D6-1E20-4EDA-B42C-3D031A4078CB}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B68806D6-1E20-4EDA-B42C-3D031A4078CB}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B68806D6-1E20-4EDA-B42C-3D031A4078CB}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {524E5E41-C108-4C87-915D-AAB458A889F2} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/Controllers/SchoolStudentController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.OData.Query; 3 | using Microsoft.AspNetCore.OData.Routing.Controllers; 4 | using OmitNullPropertySample.Models; 5 | 6 | namespace OmitNullPropertySample.Controllers 7 | { 8 | [ApiController] 9 | [Route("odata")] 10 | public class SchoolStudentController : ODataController 11 | { 12 | private readonly ISchoolStudentRepository _repo; 13 | 14 | public SchoolStudentController(ISchoolStudentRepository repo) 15 | { 16 | _repo = repo; 17 | } 18 | 19 | [HttpGet("Schools")] 20 | [HttpGet("Schools/{key}")] 21 | [EnableQuery] 22 | public IActionResult GetSchool(int? key) 23 | { 24 | if (key != null) 25 | { 26 | return Ok(_repo.Schools.FirstOrDefault(s => s.ID == key.Value)); 27 | } 28 | else 29 | { 30 | return Ok(_repo.Schools); 31 | } 32 | } 33 | 34 | [HttpGet("Students")] 35 | [HttpGet("Students/{key}")] 36 | [EnableQuery] 37 | public IActionResult GetStudent(int? key) 38 | { 39 | if (key != null) 40 | { 41 | return Ok(_repo.Students.FirstOrDefault(s => s.ID == key.Value)); 42 | } 43 | else 44 | { 45 | return Ok(_repo.Students); 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace OmitNullPropertySample.Controllers 4 | { 5 | [ApiController] 6 | [Route("[controller]")] 7 | public class WeatherForecastController : ControllerBase 8 | { 9 | private static readonly string[] Summaries = new[] 10 | { 11 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 12 | }; 13 | 14 | private readonly ILogger _logger; 15 | 16 | public WeatherForecastController(ILogger logger) 17 | { 18 | _logger = logger; 19 | } 20 | 21 | [HttpGet] 22 | public IEnumerable Get() 23 | { 24 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 25 | { 26 | Date = DateTime.Now.AddDays(index), 27 | TemperatureC = Random.Shared.Next(-20, 55), 28 | Summary = Summaries[Random.Shared.Next(Summaries.Length)] 29 | }) 30 | .ToArray(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/Models/Address.cs: -------------------------------------------------------------------------------- 1 | namespace OmitNullPropertySample.Models 2 | { 3 | public class Address 4 | { 5 | public string City { get; set; } 6 | 7 | public string Street { get; set; } 8 | 9 | public int ZipCode { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/Models/Color.cs: -------------------------------------------------------------------------------- 1 | namespace OmitNullPropertySample.Models 2 | { 3 | public enum Color 4 | { 5 | Red, 6 | 7 | Green, 8 | 9 | Blue, 10 | 11 | Black, 12 | 13 | Yellow 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/Models/EdmModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Infrastructure; 2 | using Microsoft.OData.Edm; 3 | using Microsoft.OData.ModelBuilder; 4 | 5 | namespace OmitNullPropertySample.Models 6 | { 7 | public class EdmModelBuilder 8 | { 9 | public static IEdmModel GetEdmModel() 10 | { 11 | var builder = new ODataConventionModelBuilder(); 12 | builder.EntitySet("Schools"); 13 | builder.EntitySet("Students"); 14 | return builder.GetEdmModel(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/Models/ISchoolStudentRepository.cs: -------------------------------------------------------------------------------- 1 | namespace OmitNullPropertySample.Models 2 | { 3 | public interface ISchoolStudentRepository 4 | { 5 | IList Schools { get; } 6 | 7 | IList Students { get; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/Models/School.cs: -------------------------------------------------------------------------------- 1 | namespace OmitNullPropertySample.Models 2 | { 3 | public class School 4 | { 5 | public int ID { get; set; } 6 | 7 | public string Name { get; set; } 8 | 9 | public IList Emails { get; set; } 10 | 11 | public Address HeadQuarter { get; set; } 12 | 13 | public IList
Addresses { get; set; } 14 | 15 | public IList Students { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/Models/Student.cs: -------------------------------------------------------------------------------- 1 | namespace OmitNullPropertySample.Models 2 | { 3 | public class Student 4 | { 5 | public int ID { get; set; } 6 | 7 | public string Name { get; set; } 8 | 9 | public int Age { get; set; } 10 | 11 | public Color? FavoriteColor { get; set; } 12 | 13 | public Address HomeLocation { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/OmitNullPropertySample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | disable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.OData; 2 | using Microsoft.AspNetCore.OData.Formatter.Deserialization; 3 | using Microsoft.AspNetCore.OData.Formatter.Serialization; 4 | using OmitNullPropertySample.Extensions; 5 | using OmitNullPropertySample.Models; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | 9 | // Add services to the container. 10 | 11 | builder.Services.AddControllers() 12 | .AddOData(opt => opt.AddRouteComponents("odata", EdmModelBuilder.GetEdmModel(), 13 | services => services.AddSingleton()).EnableQueryFeatures()); 14 | 15 | builder.Services.AddTransient(); 16 | 17 | var app = builder.Build(); 18 | 19 | // Configure the HTTP request pipeline. 20 | 21 | app.UseODataRouteDebug(); 22 | 23 | app.UseHttpsRedirection(); 24 | 25 | app.UseAuthorization(); 26 | 27 | app.MapControllers(); 28 | 29 | app.Run(); 30 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:10425", 8 | "sslPort": 44384 9 | } 10 | }, 11 | "profiles": { 12 | "OmitNullPropertySample": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "$odata", 17 | "applicationUrl": "https://localhost:7282;http://localhost:5251", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "weatherforecast", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | namespace OmitNullPropertySample 2 | { 3 | public class WeatherForecast 4 | { 5 | public DateTime Date { get; set; } 6 | 7 | public int TemperatureC { get; set; } 8 | 9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 10 | 11 | public string? Summary { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/OmitNullPropertySample/OmitNullPropertySample/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29609.76 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SelectImprovement", "SelectImprovement\SelectImprovement.csproj", "{2C7EF8C9-4833-4DFF-8C2F-3CAB12952DA0}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {2C7EF8C9-4833-4DFF-8C2F-3CAB12952DA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {2C7EF8C9-4833-4DFF-8C2F-3CAB12952DA0}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {2C7EF8C9-4833-4DFF-8C2F-3CAB12952DA0}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {2C7EF8C9-4833-4DFF-8C2F-3CAB12952DA0}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {D1548949-06BF-4148-AE93-FC7CC21C73E1} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/Controllers/CustomersController.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.AspNet.OData; 4 | using Microsoft.Extensions.Logging; 5 | using SelectImprovement.Models; 6 | 7 | namespace SelectImprovement.Controllers 8 | { 9 | public class CustomersController : ODataController 10 | { 11 | private readonly ILogger _logger; 12 | private IDataRepository _repository; 13 | 14 | public CustomersController(IDataRepository repository, ILogger logger) 15 | { 16 | _repository = repository; 17 | _logger = logger; 18 | } 19 | 20 | [EnableQuery] 21 | public IActionResult Get() 22 | { 23 | return Ok(_repository.GetCustomers()); 24 | } 25 | 26 | [EnableQuery] 27 | public IActionResult Get(int key) 28 | { 29 | return Ok(_repository.GetCustomers().FirstOrDefault(c => c.Id == key)); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/Models/Address.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SelectImprovement.Models 7 | { 8 | public class Address 9 | { 10 | public string Street { get; set; } 11 | 12 | public string City { get; set; } 13 | 14 | public ZipCode ZipCode { get; set; } 15 | } 16 | 17 | public class BillAddress : Address 18 | { 19 | public string FirstName { get; set; } 20 | 21 | public string LastName { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/Models/Customer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SelectImprovement.Models 7 | { 8 | public class Customer 9 | { 10 | public int Id { get; set; } 11 | 12 | public string Name { get; set; } 13 | 14 | public IList Emails { get; set; } 15 | 16 | public Address HomeAddress { get; set; } 17 | 18 | public IList
FavoriteAddresses { get; set; } 19 | 20 | public Order PersonOrder { get; set; } 21 | 22 | public Order[] Orders { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/Models/IDataRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SelectImprovement.Models 4 | { 5 | public interface IDataRepository 6 | { 7 | IEnumerable GetCustomers(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/Models/Order.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SelectImprovement.Models 7 | { 8 | public class Order 9 | { 10 | public int Id { get; set; } 11 | 12 | public string Title { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/Models/ZipCode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SelectImprovement.Models 7 | { 8 | public class ZipCode 9 | { 10 | public int Id { get; set; } 11 | 12 | public string DisplayName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace SelectImprovement 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:29014", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "odata/$metadata", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "SelectImprovement": { 21 | "commandName": "Project", 22 | "launchBrowser": false, 23 | "launchUrl": "odata/Customers", 24 | "applicationUrl": "http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/SelectImprovement.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/SelectImprovement/SelectImprovement/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.6.33513.286 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UntypedApp", "UntypedApp\UntypedApp.csproj", "{E11E554D-1FD0-4BEC-BB41-A46C91B62531}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {E11E554D-1FD0-4BEC-BB41-A46C91B62531}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {E11E554D-1FD0-4BEC-BB41-A46C91B62531}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {E11E554D-1FD0-4BEC-BB41-A46C91B62531}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {E11E554D-1FD0-4BEC-BB41-A46C91B62531}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {31FBB053-9C51-4954-8E83-5D05C7A5ED3F} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/Extensions/MyResourceSerializer.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | using Microsoft.AspNetCore.OData.Formatter; 8 | using Microsoft.AspNetCore.OData.Formatter.Serialization; 9 | using Microsoft.OData.Edm; 10 | 11 | namespace UntypedApp.Extensions; 12 | 13 | public class MyResourceSerializer : ODataResourceSerializer 14 | { 15 | public MyResourceSerializer(IODataSerializerProvider serializerProvider) : base(serializerProvider) 16 | { 17 | } 18 | 19 | public override object CreateUntypedPropertyValue(IEdmStructuralProperty structuralProperty, ResourceContext resourceContext, out IEdmTypeReference actualType) 20 | { 21 | // add your logics here to return some values for untyped properties. 22 | // If returns an instance of ODataProperty, it will be used to write as property directly 23 | // Others, it will be used to write as resource/resourceSet. 24 | return base.CreateUntypedPropertyValue(structuralProperty, resourceContext, out actualType); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/Models/Address.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | namespace UntypedApp.Models; 8 | 9 | public class Address 10 | { 11 | public string City { get; set; } 12 | 13 | public string Street { get; set; } 14 | } 15 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/Models/Color.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | namespace UntypedApp.Models; 8 | 9 | public enum Color 10 | { 11 | Black, 12 | 13 | While, 14 | 15 | Yellow, 16 | 17 | Blue, 18 | 19 | Green 20 | } 21 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/Models/Course.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | namespace UntypedApp.Models; 8 | 9 | public class Course 10 | { 11 | public string Title { get; set; } 12 | 13 | private string AliasName { get => Title + "_alias"; } 14 | 15 | public IList Credits { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/Models/EdmModelBuilder.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | using Microsoft.OData.Edm; 8 | using Microsoft.OData.ModelBuilder; 9 | 10 | namespace UntypedApp.Models; 11 | 12 | public class EdmModelBuilder 13 | { 14 | public static IEdmModel GetEdmModel() 15 | { 16 | var builder = new ODataConventionModelBuilder(); 17 | builder.ComplexType
(); // add Address complex type explicitly since there's no reference to this type. 18 | builder.EntitySet("People"); 19 | EdmModel model = (EdmModel)builder.GetEdmModel(); 20 | 21 | // Add a complex type without C# class mapped 22 | EdmComplexType complexType = new EdmComplexType("UntypedApp.Models", "Message"); 23 | complexType.AddStructuralProperty("Description", EdmCoreModel.Instance.GetString(true)); 24 | complexType.AddStructuralProperty("Status", EdmCoreModel.Instance.GetString(false)); 25 | model.AddElement(complexType); 26 | return model; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/Models/Gender.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | namespace UntypedApp.Models; 8 | 9 | public enum Gender 10 | { 11 | Other, 12 | 13 | Male, 14 | 15 | Female 16 | } 17 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/Models/Person.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | namespace UntypedApp.Models; 8 | 9 | public class Person 10 | { 11 | public int Id { get; set; } 12 | 13 | public string Name { get; set; } 14 | 15 | public Gender Gender { get; set; } 16 | 17 | public object Data { get; set; } //=> Edm.Untyped 18 | 19 | public IList Infos { get; set; } = new List(); // Collection(Edm.Untyped) 20 | 21 | public IDictionary DynamicContainer { get; set; } // dynamic property container 22 | 23 | // public Address HomeAddress { get; set; } 24 | } 25 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/Models/UserType.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | namespace UntypedApp.Models; 8 | 9 | public enum UserType 10 | { 11 | Normal, 12 | 13 | Admin 14 | } 15 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/Program.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // 3 | // Copyright (C) saxu@microsoft.com 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | using Microsoft.AspNetCore.OData; 8 | using Microsoft.AspNetCore.OData.Formatter.Serialization; 9 | using UntypedApp.Extensions; 10 | using UntypedApp.Models; 11 | 12 | var builder = WebApplication.CreateBuilder(args); 13 | 14 | // Add services to the container. 15 | 16 | builder.Services.AddControllers() 17 | .AddOData(opt => 18 | opt.EnableQueryFeatures() 19 | .AddRouteComponents("odata", EdmModelBuilder.GetEdmModel(), services => 20 | services.AddSingleton() 21 | .AddSingleton()) 22 | ); 23 | 24 | var app = builder.Build(); 25 | 26 | // Configure the HTTP request pipeline. 27 | app.UseODataRouteDebug(); 28 | 29 | app.UseAuthorization(); 30 | 31 | app.MapControllers(); 32 | 33 | app.Run(); 34 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:17635", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "UntypedApp": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "$odata", 17 | "applicationUrl": "http://localhost:5299", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "$odata", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/UntypedApp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | disable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/UntypedApp/UntypedApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /src/UntypedApp/readme.md: -------------------------------------------------------------------------------- 1 | This project is for post at: https://devblogs.microsoft.com/odata/enable-un-typed-within-asp-net-core-odata/ 2 | 3 | Please let me know your thoughts or any issues! 4 | 5 | Thanks! 6 | -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Client/IBookStoreClient.cs: -------------------------------------------------------------------------------- 1 | using Bookstores; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace gRPC.OData.Client 9 | { 10 | public interface IBookStoreClient 11 | { 12 | Task ListShelves(); 13 | 14 | Task CreateShelf(Shelf shelf); 15 | 16 | Task GetShelf(long shelfId); 17 | 18 | Task DeleteShelf(long shelfId); 19 | 20 | Task ListBooks(long shelfId); 21 | 22 | Task CreateBook(long shelfId, Book book); 23 | 24 | Task GetBook(long shelfId, long bookId); 25 | 26 | Task DeleteBook(long shelfId, long bookId); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Client/gRPC.OData.Client.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Server/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace gRPC.OData.Server.Controllers 4 | { 5 | [ApiController] 6 | [Route("[controller]")] 7 | public class WeatherForecastController : ControllerBase 8 | { 9 | private static readonly string[] Summaries = new[] 10 | { 11 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 12 | }; 13 | 14 | private readonly ILogger _logger; 15 | 16 | public WeatherForecastController(ILogger logger) 17 | { 18 | _logger = logger; 19 | } 20 | 21 | [HttpGet] 22 | public IEnumerable Get() 23 | { 24 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 25 | { 26 | Date = DateTime.Now.AddDays(index), 27 | TemperatureC = Random.Shared.Next(-20, 55), 28 | Summary = Summaries[Random.Shared.Next(Summaries.Length)] 29 | }) 30 | .ToArray(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Server/Models/EdmModelBuilder.cs: -------------------------------------------------------------------------------- 1 |  2 | using Bookstores; 3 | using Microsoft.OData.Edm; 4 | using Microsoft.OData.ModelBuilder; 5 | 6 | namespace gRPC.OData.Server.Models 7 | { 8 | internal class EdmModelBuilder 9 | { 10 | public static IEdmModel GetEdmModel() 11 | { 12 | var builder = new ODataModelBuilder(); 13 | 14 | var shelf = builder.EntityType(); 15 | shelf.HasKey(b => b.Id); 16 | shelf.Property(b => b.Theme); 17 | 18 | var bookMessage = builder.EntityType(); 19 | bookMessage.HasKey(b => b.Id); 20 | bookMessage.Property(b => b.Title); 21 | bookMessage.Property(b => b.Author); 22 | 23 | builder.EntitySet("Books"); 24 | builder.EntitySet("Shelves").HasManyBinding(s => s.Books, "Books"); 25 | 26 | return builder.GetEdmModel(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Server/Models/IShelfBookRepository.cs: -------------------------------------------------------------------------------- 1 | using Bookstores; 2 | 3 | namespace gRPC.OData.Server.Models 4 | { 5 | public interface IShelfBookRepository 6 | { 7 | IEnumerable GetShelves(); 8 | 9 | Shelf CreateShelf(Shelf shelf); 10 | 11 | Shelf GetShelf(long shelfId); 12 | 13 | void DeleteShelf(long shelfId); 14 | 15 | IEnumerable GetBooks(long shelfId); 16 | 17 | Book CreateBook(long shelfId, Book book); 18 | 19 | Book GetBook(long shelfId, long bookId); 20 | 21 | void DeleteBook(long shelfId, long bookId); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Server/Models/ShelfExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Bookstores 2 | { 3 | public sealed partial class Shelf 4 | { 5 | public IList Books { get; set; } = new List(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Server/Program.cs: -------------------------------------------------------------------------------- 1 | using gRPC.OData.Server.Extensions; 2 | using gRPC.OData.Server.Models; 3 | using gRPC.OData.Server.Services; 4 | using Microsoft.AspNetCore.OData; 5 | 6 | var builder = WebApplication.CreateBuilder(args); 7 | 8 | // Add services to the container. 9 | builder.Services.AddTransient(); 10 | 11 | builder.Services.AddControllers() 12 | .AddOData(opt => opt.EnableQueryFeatures().AddRouteComponents("odata", EdmModelBuilder.GetEdmModel())); 13 | 14 | builder.Services.AddGrpc(); 15 | 16 | var app = builder.Build(); 17 | 18 | // Configure the HTTP request pipeline. 19 | 20 | app.UseEndpointDebug(); // send "/$endpoint" in browser to debug 21 | 22 | app.UseHttpsRedirection(); 23 | 24 | app.UseAuthorization(); 25 | 26 | app.MapGrpcService(); 27 | 28 | app.MapControllers(); 29 | 30 | app.Run(); 31 | -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Server/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:37485", 8 | "sslPort": 44355 9 | } 10 | }, 11 | "profiles": { 12 | "gRPC.OData.Server": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "$endpoint", 17 | "applicationUrl": "https://localhost:7260;http://localhost:5260", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "weatherforecast", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Server/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | namespace gRPC.OData.Server 2 | { 3 | public class WeatherForecast 4 | { 5 | public DateTime Date { get; set; } 6 | 7 | public int TemperatureC { get; set; } 8 | 9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 10 | 11 | public string? Summary { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Server/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Server/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "Kestrel": { 10 | "EndpointDefaults": { 11 | "Protocols": "Http2" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/gRPC.OData/gRPC.OData.Server/gRPC.OData.Server.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | all 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/ObjectResultExecutorTests/ObjectResultExecutorTests/Customer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ObjectResultExecutorTests 8 | { 9 | public class Customer 10 | { 11 | public int Id { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/ObjectResultExecutorTests/ObjectResultExecutorTests/ObjectResultExecutorTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/ObjectResultExecutorTests/ObjectResultExecutorTests/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ObjectResultExecutorTests 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /tests/ObjectResultExecutorXunitTests/Customer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ObjectResultExecutorXunitTests 8 | { 9 | public class Customer 10 | { 11 | public int Id { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/ObjectResultExecutorXunitTests/ObjectResultExecutorXunitTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | all 15 | 16 | 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | all 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /tests/ObjectResultExecutorXunitTests/UnitTest1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | 4 | namespace ObjectResultExecutorXunitTests 5 | { 6 | public class UnitTest1 7 | { 8 | [Fact] 9 | public void Test1() 10 | { 11 | 12 | } 13 | } 14 | } 15 | --------------------------------------------------------------------------------