├── src
├── section_3
│ ├── section3.4
│ │ ├── Views
│ │ │ ├── _ViewStart.cshtml
│ │ │ ├── _ViewImports.cshtml
│ │ │ ├── Home
│ │ │ │ ├── Privacy.cshtml
│ │ │ │ └── Index.cshtml
│ │ │ └── Shared
│ │ │ │ ├── _ValidationScriptsPartial.cshtml
│ │ │ │ ├── Error.cshtml
│ │ │ │ ├── _Layout.cshtml.css
│ │ │ │ └── _Layout.cshtml
│ │ ├── wwwroot
│ │ │ ├── favicon.ico
│ │ │ ├── js
│ │ │ │ └── site.js
│ │ │ ├── css
│ │ │ │ └── site.css
│ │ │ └── lib
│ │ │ │ ├── jquery
│ │ │ │ └── LICENSE.txt
│ │ │ │ ├── jquery-validation
│ │ │ │ └── LICENSE.md
│ │ │ │ ├── bootstrap
│ │ │ │ └── LICENSE
│ │ │ │ └── jquery-validation-unobtrusive
│ │ │ │ └── LICENSE.txt
│ │ ├── appsettings.Development.json
│ │ ├── appsettings.json
│ │ ├── Models
│ │ │ └── ErrorViewModel.cs
│ │ ├── section3.4.csproj
│ │ ├── Controllers
│ │ │ └── HomeController.cs
│ │ ├── Properties
│ │ │ └── launchSettings.json
│ │ └── Program.cs
│ ├── section3.3
│ │ ├── Views
│ │ │ ├── _ViewStart.cshtml
│ │ │ ├── Shared
│ │ │ │ ├── Error.cshtml
│ │ │ │ └── _Layout.cshtml
│ │ │ ├── Home
│ │ │ │ └── Index.cshtml
│ │ │ └── Web.config
│ │ ├── Global.asax
│ │ ├── favicon.ico
│ │ ├── Areas
│ │ │ └── HelpPage
│ │ │ │ ├── Views
│ │ │ │ ├── Help
│ │ │ │ │ ├── DisplayTemplates
│ │ │ │ │ │ ├── ImageSample.cshtml
│ │ │ │ │ │ ├── TextSample.cshtml
│ │ │ │ │ │ ├── SimpleTypeModelDescription.cshtml
│ │ │ │ │ │ ├── ComplexTypeModelDescription.cshtml
│ │ │ │ │ │ ├── CollectionModelDescription.cshtml
│ │ │ │ │ │ ├── InvalidSample.cshtml
│ │ │ │ │ │ ├── DictionaryModelDescription.cshtml
│ │ │ │ │ │ ├── KeyValuePairModelDescription.cshtml
│ │ │ │ │ │ ├── EnumTypeModelDescription.cshtml
│ │ │ │ │ │ ├── Samples.cshtml
│ │ │ │ │ │ ├── ModelDescriptionLink.cshtml
│ │ │ │ │ │ ├── ApiGroup.cshtml
│ │ │ │ │ │ ├── Parameters.cshtml
│ │ │ │ │ │ └── HelpPageApiModel.cshtml
│ │ │ │ │ ├── ResourceModel.cshtml
│ │ │ │ │ ├── Api.cshtml
│ │ │ │ │ └── Index.cshtml
│ │ │ │ ├── _ViewStart.cshtml
│ │ │ │ ├── Shared
│ │ │ │ │ └── _Layout.cshtml
│ │ │ │ └── Web.config
│ │ │ │ ├── ModelDescriptions
│ │ │ │ ├── SimpleTypeModelDescription.cs
│ │ │ │ ├── DictionaryModelDescription.cs
│ │ │ │ ├── CollectionModelDescription.cs
│ │ │ │ ├── ParameterAnnotation.cs
│ │ │ │ ├── EnumValueDescription.cs
│ │ │ │ ├── KeyValuePairModelDescription.cs
│ │ │ │ ├── IModelDocumentationProvider.cs
│ │ │ │ ├── ModelDescription.cs
│ │ │ │ ├── ComplexTypeModelDescription.cs
│ │ │ │ ├── EnumTypeModelDescription.cs
│ │ │ │ ├── ModelNameAttribute.cs
│ │ │ │ ├── ParameterDescription.cs
│ │ │ │ └── ModelNameHelper.cs
│ │ │ │ ├── SampleGeneration
│ │ │ │ ├── SampleDirection.cs
│ │ │ │ ├── TextSample.cs
│ │ │ │ ├── InvalidSample.cs
│ │ │ │ └── ImageSample.cs
│ │ │ │ ├── HelpPageAreaRegistration.cs
│ │ │ │ ├── ApiDescriptionExtensions.cs
│ │ │ │ └── Controllers
│ │ │ │ └── HelpController.cs
│ │ ├── fonts
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ └── glyphicons-halflings-regular.woff2
│ │ ├── App_Start
│ │ │ ├── FilterConfig.cs
│ │ │ ├── RouteConfig.cs
│ │ │ ├── WebApiConfig.cs
│ │ │ └── BundleConfig.cs
│ │ ├── Models
│ │ │ ├── Employee.cs
│ │ │ ├── Sale.cs
│ │ │ └── SalesContext.cs
│ │ ├── Controllers
│ │ │ ├── HomeController.cs
│ │ │ ├── ValuesController.cs
│ │ │ ├── AverageController.cs
│ │ │ └── TotalSalesController.cs
│ │ ├── Content
│ │ │ └── Site.css
│ │ ├── Global.asax.cs
│ │ ├── Redis.cs
│ │ ├── Migrations
│ │ │ ├── 202211301905089_initial.Designer.cs
│ │ │ ├── 202211302024328_initial.Designer.cs
│ │ │ ├── 202211301905089_initial.cs
│ │ │ ├── 202211302024328_initial.cs
│ │ │ └── Configuration.cs
│ │ ├── README.md
│ │ ├── Section3.3.sln
│ │ ├── Web.Debug.config
│ │ ├── Web.Release.config
│ │ └── Properties
│ │ │ └── AssemblyInfo.cs
│ ├── section3.5
│ │ ├── Views
│ │ │ ├── _ViewStart.cshtml
│ │ │ ├── Home
│ │ │ │ ├── About.cshtml
│ │ │ │ ├── Index.cshtml
│ │ │ │ └── Contact.cshtml
│ │ │ ├── Shared
│ │ │ │ ├── Error.cshtml
│ │ │ │ └── _Layout.cshtml
│ │ │ └── Web.config
│ │ ├── Global.asax
│ │ ├── favicon.ico
│ │ ├── fonts
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ └── glyphicons-halflings-regular.woff2
│ │ ├── App_Start
│ │ │ ├── FilterConfig.cs
│ │ │ ├── RouteConfig.cs
│ │ │ └── BundleConfig.cs
│ │ ├── Global.asax.cs
│ │ ├── Content
│ │ │ └── Site.css
│ │ ├── Controllers
│ │ │ └── HomeController.cs
│ │ ├── README.md
│ │ ├── section3.5.sln
│ │ ├── Web.Debug.config
│ │ ├── Web.Release.config
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ └── packages.config
│ └── section3.2
│ │ ├── appsettings.Development.json
│ │ ├── appsettings.json
│ │ ├── SalesContext.cs
│ │ ├── section3.2.csproj
│ │ ├── Program.cs
│ │ ├── Properties
│ │ └── launchSettings.json
│ │ ├── InitService.cs
│ │ └── Migrations
│ │ ├── 20221128165447_InitialCreate.cs
│ │ └── SalesContextModelSnapshot.cs
├── section_4
│ ├── section4.3
│ │ ├── section4.3.csproj
│ │ └── Program.cs
│ ├── section4.2
│ │ ├── section4.2.csproj
│ │ └── Program.cs
│ └── section4.1
│ │ └── section4.1.csproj
├── section_5
│ ├── section5.1
│ │ ├── section5.1.csproj
│ │ ├── Program.cs
│ │ └── Model.cs
│ ├── section5.2
│ │ ├── section5.2.csproj
│ │ ├── Model.cs
│ │ └── Program.cs
│ ├── section5.3
│ │ ├── section5.3.csproj
│ │ └── Model.cs
│ ├── section5.4
│ │ ├── section5.4.csproj
│ │ ├── Model.cs
│ │ └── Program.cs
│ └── section5.5
│ │ ├── section5.5.csproj
│ │ └── Model.cs
├── section_1
│ ├── section1.2
│ │ ├── section1.2.csproj
│ │ └── Program.cs
│ └── section1.5
│ │ ├── section1.5.csproj
│ │ └── Program.cs
└── section_2
│ ├── section2.1
│ └── section2.1.csproj
│ ├── section2.2
│ └── section2.2.csproj
│ ├── section2.3
│ └── section2.3.csproj
│ ├── section2.4
│ └── section2.4.csproj
│ ├── section2.5
│ ├── section2.5.csproj
│ └── Program.cs
│ ├── section2.6
│ └── section2.6.csproj
│ ├── section2.7
│ ├── section2.7.csproj
│ └── Program.cs
│ ├── section2.8
│ ├── section2.8.csproj
│ └── Program.cs
│ └── section2.9
│ ├── section2.9.csproj
│ └── Program.cs
├── images_for_readme
├── insight_web.png
├── cloud_new_sub_1.png
├── cloud_new_sub_2.png
├── cloud_new_sub_3.png
├── cloud_new_sub_4.png
├── download_repo_zip.png
└── insight_web_terms.png
├── docker-compose.yml
├── courseware
├── html
│ ├── section_6
│ │ ├── ru102n_6_6_3_1_get_your_certificate.html
│ │ ├── ru102n_6_6_0_course_wrap_up.html
│ │ ├── ru102n_6_6_1_subscribe_youtube_twitch.html
│ │ ├── ru102n_6_6_2_try_redis_cloud.html
│ │ ├── ru102n_6_0_0_final_exam_introduction.html
│ │ └── ru102n_6_6_3_2_get_your_certificate.html
│ ├── section_2
│ │ ├── ru102n_2_1_0_string_operations.html
│ │ ├── ru102n_2_5_0_hashes.html
│ │ ├── ru102n_2_4_0_sorted_sets.html
│ │ ├── ru102n_2_2_0_redis_lists.html
│ │ ├── ru102n_2_3_0_redis_sets.html
│ │ ├── ru102n_2_8_0_redis_transactions.html
│ │ ├── ru102n_2_9_0_pubsub.html
│ │ ├── ru102n_2_6_0_redis_streams.html
│ │ └── ru102n_2_0_0_overview.html
│ ├── section_5
│ │ ├── ru102n_5_2_0_inserting_objects.html
│ │ ├── ru102n_5_4_0_updates_and_deletion.html
│ │ ├── ru102n_5_0_0_unit_overview.html
│ │ └── ru102n_5_5_0_aggregations.html
│ ├── section_1
│ │ ├── ru102n_1_4_0_advanced_connections.html
│ │ ├── ru102n_1_2_0_getting_started_with_stack_exhange_redis.html
│ │ ├── ru102n_1_3_0_interfaces_of_stack_exchange_redis.html
│ │ ├── ru102n_1_3_1_i_connection_multiplexer.html
│ │ ├── ru102n_1_2_2_add_stack_exchange_redis.html
│ │ ├── ru102n_1_3_3_i_server.html
│ │ ├── ru102n_1_4_3_connect_to_redis_sentinel.html
│ │ ├── ru102n_1_3_4_i_subscriber.html
│ │ ├── ru102n_1_2_4_coding_challenge_solution.html
│ │ ├── ru102n_1_0_0_unit_overview.html
│ │ ├── ru102n_1_4_2_connect_to_redis_cluster.html
│ │ ├── ru102n_1_3_2_i_database.html
│ │ ├── ru102n_1_3_5_i_transaction.html
│ │ └── ru102n_1_5_0_pipelining.html
│ ├── README.md
│ ├── section_4
│ │ ├── ru102n_4_1_0_ad_hoc_api.html
│ │ ├── ru102n_4_3_0_graph.html
│ │ ├── ru102n_4_2_0_timeseries_dotnet.html
│ │ └── ru102n_4_0_0_overview.html
│ ├── section_3
│ │ ├── ru102n_3_0_0_overview.html
│ │ ├── ru102n_3_1_0_derived_clients.html
│ │ ├── ru102n_3_2_0_caching_aspnet_core.html
│ │ ├── ru102n_3_2_1_employee_aggregation_example_intro.html
│ │ ├── ru102n_3_4_0_distributed_sessions_aspnet_core.html
│ │ ├── ru102n_3_5_0_session_state_with_aspnet.html
│ │ └── ru102n_3_3_0_caching_asp_net_classic.html
│ └── section_0
│ │ ├── ru102n_0_1_1_about_redis.html
│ │ ├── ru102n_0_1_0_introduce_yourself.html
│ │ └── ru102n_0_3_0_course_setup.html
└── transcripts
│ └── README.md
└── LICENSE
/src/section_3/section3.4/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "_Layout";
3 | }
4 |
--------------------------------------------------------------------------------
/src/section_3/section3.3/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "~/Views/Shared/_Layout.cshtml";
3 | }
4 |
--------------------------------------------------------------------------------
/src/section_3/section3.5/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "~/Views/Shared/_Layout.cshtml";
3 | }
4 |
--------------------------------------------------------------------------------
/images_for_readme/insight_web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/images_for_readme/insight_web.png
--------------------------------------------------------------------------------
/src/section_3/section3.3/Global.asax:
--------------------------------------------------------------------------------
1 | <%@ Application Codebehind="Global.asax.cs" Inherits="section3._3.WebApiApplication" Language="C#" %>
2 |
--------------------------------------------------------------------------------
/src/section_3/section3.3/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.3/favicon.ico
--------------------------------------------------------------------------------
/src/section_3/section3.5/Global.asax:
--------------------------------------------------------------------------------
1 | <%@ Application Codebehind="Global.asax.cs" Inherits="section3._5.MvcApplication" Language="C#" %>
2 |
--------------------------------------------------------------------------------
/src/section_3/section3.5/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.5/favicon.ico
--------------------------------------------------------------------------------
/images_for_readme/cloud_new_sub_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/images_for_readme/cloud_new_sub_1.png
--------------------------------------------------------------------------------
/images_for_readme/cloud_new_sub_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/images_for_readme/cloud_new_sub_2.png
--------------------------------------------------------------------------------
/images_for_readme/cloud_new_sub_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/images_for_readme/cloud_new_sub_3.png
--------------------------------------------------------------------------------
/images_for_readme/cloud_new_sub_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/images_for_readme/cloud_new_sub_4.png
--------------------------------------------------------------------------------
/images_for_readme/download_repo_zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/images_for_readme/download_repo_zip.png
--------------------------------------------------------------------------------
/images_for_readme/insight_web_terms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/images_for_readme/insight_web_terms.png
--------------------------------------------------------------------------------
/src/section_3/section3.4/wwwroot/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.4/wwwroot/favicon.ico
--------------------------------------------------------------------------------
/src/section_3/section3.4/Views/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using section3._4
2 | @using section3._4.Models
3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
4 |
--------------------------------------------------------------------------------
/src/section_3/section3.3/Areas/HelpPage/Views/Help/DisplayTemplates/ImageSample.cshtml:
--------------------------------------------------------------------------------
1 | @using section3._3.Areas.HelpPage
2 | @model ImageSample
3 |
4 |
--------------------------------------------------------------------------------
/src/section_3/section3.3/Areas/HelpPage/Views/Help/DisplayTemplates/TextSample.cshtml:
--------------------------------------------------------------------------------
1 | @using section3._3.Areas.HelpPage
2 | @model TextSample
3 |
4 |
5 | @Model.Text 6 |-------------------------------------------------------------------------------- /src/section_3/section3.3/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.3/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/section_3/section3.3/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.3/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/section_3/section3.3/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.3/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /src/section_3/section3.5/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.5/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/section_3/section3.5/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.5/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/section_3/section3.5/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.5/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | services: 3 | redis: 4 | container_name: redisu-ru102n 5 | image: redis/redis-stack:latest 6 | ports: 7 | - "6379:6379" 8 | - "8001:8001" -------------------------------------------------------------------------------- /src/section_3/section3.3/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.3/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /src/section_3/section3.5/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redislabs-training/ru-dev-path-net/HEAD/src/section_3/section3.5/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /src/section_3/section3.2/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/section_3/section3.4/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/section_3/section3.4/Views/Home/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Privacy Policy"; 3 | } 4 |
Use this page to detail your site's privacy policy.
7 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/Views/Help/DisplayTemplates/SimpleTypeModelDescription.cshtml: -------------------------------------------------------------------------------- 1 | @using section3._3.Areas.HelpPage.ModelDescriptions 2 | @model SimpleTypeModelDescription 3 | @Model.Documentation -------------------------------------------------------------------------------- /src/section_3/section3.5/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "About"; 3 | } 4 |Use this area to provide additional information.
8 | -------------------------------------------------------------------------------- /src/section_3/section3.2/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /src/section_3/section3.4/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | // Change the Layout path below to blend the look and feel of the help page with your existing web pages 3 | Layout = "~/Views/Shared/_Layout.cshtml"; 4 | } -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/ModelDescriptions/SimpleTypeModelDescription.cs: -------------------------------------------------------------------------------- 1 | namespace section3._3.Areas.HelpPage.ModelDescriptions 2 | { 3 | public class SimpleTypeModelDescription : ModelDescription 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/Views/Help/DisplayTemplates/ComplexTypeModelDescription.cshtml: -------------------------------------------------------------------------------- 1 | @using section3._3.Areas.HelpPage.ModelDescriptions 2 | @model ComplexTypeModelDescription 3 | @Html.DisplayFor(m => m.Properties, "Parameters") -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/ModelDescriptions/DictionaryModelDescription.cs: -------------------------------------------------------------------------------- 1 | namespace section3._3.Areas.HelpPage.ModelDescriptions 2 | { 3 | public class DictionaryModelDescription : KeyValuePairModelDescription 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/section_3/section3.4/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/section_3/section3.4/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace section3._4.Models; 2 | 3 | public class ErrorViewModel 4 | { 5 | public string? RequestId { get; set; } 6 | 7 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 8 | } 9 | -------------------------------------------------------------------------------- /src/section_3/section3.4/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/ModelDescriptions/CollectionModelDescription.cs: -------------------------------------------------------------------------------- 1 | namespace section3._3.Areas.HelpPage.ModelDescriptions 2 | { 3 | public class CollectionModelDescription : ModelDescription 4 | { 5 | public ModelDescription ElementDescription { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/section_3/section3.5/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Home Page"; 3 | } 4 | 5 |Our Session Says the meaning of life is: @Session["the meaning of life"].
8 |4 | Redis Strings are the simplest of the Redis Data Structures. They map a single Redis 5 | Key to a single Redis Value. In spite of their simplicity they have a variety of 6 | capabilities that make them useful across a number of use cases. 7 |
-------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/ModelDescriptions/EnumValueDescription.cs: -------------------------------------------------------------------------------- 1 | namespace section3._3.Areas.HelpPage.ModelDescriptions 2 | { 3 | public class EnumValueDescription 4 | { 5 | public string Documentation { get; set; } 6 | 7 | public string Name { get; set; } 8 | 9 | public string Value { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/section_3/section3.3/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |4 | Redis OM enables you to insert your modeled objects into Redis. As we'll find out in this section, doing so is very straightforward, 5 | but there are some considerations you'll want to keep in mind as you are inserting your objects into Redis. 6 |
-------------------------------------------------------------------------------- /src/section_3/section3.3/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace section3._3 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new HandleErrorAttribute()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |Sample not available.
13 | } -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/ModelDescriptions/KeyValuePairModelDescription.cs: -------------------------------------------------------------------------------- 1 | namespace section3._3.Areas.HelpPage.ModelDescriptions 2 | { 3 | public class KeyValuePairModelDescription : ModelDescription 4 | { 5 | public ModelDescription KeyModelDescription { get; set; } 6 | 7 | public ModelDescription ValueModelDescription { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/ModelDescriptions/IModelDocumentationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace section3._3.Areas.HelpPage.ModelDescriptions 5 | { 6 | public interface IModelDocumentationProvider 7 | { 8 | string GetDocumentation(MemberInfo member); 9 | 10 | string GetDocumentation(Type type); 11 | } 12 | } -------------------------------------------------------------------------------- /src/section_3/section3.3/Models/Employee.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | 6 | namespace section3._3.Models 7 | { 8 | public class Employee 9 | { 10 | public int EmployeeId { get; set; } 11 | public string Name { get; set; } 12 | public ListOur Session tells us that the meaning of life is: @Context.Session.GetString("meaning of life")
11 |4 | Hashes are a simple, but very powerful data structure available within Redis. Hashes are similar to dictionaries in that they allow you to 5 | organize a set of key-value pairs at a particular key within Redis. 6 |
7 |8 | In this section we'll look at how to use hashes using the StackExchange.Redis 9 | library. 10 |
-------------------------------------------------------------------------------- /src/section_3/section3.3/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | 7 | namespace section3._3.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | public ActionResult Index() 12 | { 13 | ViewBag.Title = "Home Page"; 14 | 15 | return View(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/ModelDescriptions/ModelDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace section3._3.Areas.HelpPage.ModelDescriptions 4 | { 5 | ///4 | In this section we'll explore connecting the Multiplexer to instances of Redis 5 | that are beyond the unencrypted single server variety. We'll explore: 6 |
7 | 8 |Congratulations, you're at the end of the course! We hope that you enjoyed it, and that you were successful with the final exam. If so, please click Next for instructions showing how to add your certificate of completion to your LinkedIn profile.
2 |Thanks for spending your time with us, and we hope to see you on another Redis University course soon.
3 |Steve Lorello on behalf of the Redis University team.
-------------------------------------------------------------------------------- /courseware/html/section_2/ru102n_2_4_0_sorted_sets.html: -------------------------------------------------------------------------------- 1 |4 | Sorted Sets are similar conceptually to sets, however unlike regular sets, sorted sets 5 | store and retrieve members in order using the member's score. In this section we'll learn 6 | how to use Sorted Sets using the StackExchange.Redis library. We'll learn how to add to, 7 | combine, move between, and enumerate members with sorted sets. Read more about Sorted Sets on redis.io. 8 |
-------------------------------------------------------------------------------- /src/section_5/section5.1/Program.cs: -------------------------------------------------------------------------------- 1 | using Redis.OM; 2 | using section5._1; 3 | 4 | // TODO for Coding Challenge Start here on starting-point branch 5 | var provider = new RedisConnectionProvider("redis://localhost:6379"); 6 | 7 | provider.Connection.DropIndexAndAssociatedRecords(typeof(Sale)); 8 | provider.Connection.DropIndexAndAssociatedRecords(typeof(Employee)); 9 | 10 | await provider.Connection.CreateIndexAsync(typeof(Sale)); 11 | await provider.Connection.CreateIndexAsync(typeof(Employee)); 12 | 13 | Console.WriteLine("Created indexes."); 14 | // end coding challenge 15 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Content/Site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Set padding to keep content from hitting the edges */ 7 | .body-content { 8 | padding-left: 15px; 9 | padding-right: 15px; 10 | } 11 | 12 | /* Set width on the form input elements since they're 100% wide by default */ 13 | input, 14 | select, 15 | textarea { 16 | max-width: 280px; 17 | } 18 | 19 | .navbar-inverse .navbar-toggle:hover, 20 | .navbar-inverse .navbar-toggle:focus { 21 | background-color: #777; 22 | border-color: #fff 23 | } 24 | -------------------------------------------------------------------------------- /courseware/html/section_5/ru102n_5_4_0_updates_and_deletion.html: -------------------------------------------------------------------------------- 1 |4 | In this section we'll look at how Redis OM performs the "U" and "D" of CRUD: Updates, and Deletes. 5 |
6 |7 | Unlike a traditional 8 | relational database Redis Stack does not have the the ability to natively query, update, and delete records in isolation on the Redis 9 | Server, so we need to use the client to do so. Fortunately, Redis OM makes these tasks pretty straightforward as we'll be exploring in 10 | this section. 11 |
-------------------------------------------------------------------------------- /src/section_1/section1.2/Program.cs: -------------------------------------------------------------------------------- 1 | using StackExchange.Redis; 2 | 3 | // TODO for Coding Challenge Start here on starting-point branch 4 | var options = new ConfigurationOptions 5 | { 6 | // add and update parameters as needed 7 | EndPoints = {"localhost:6379"} 8 | }; 9 | 10 | // initalize a multiplexer with ConnectionMultiplexer.Connect() 11 | var muxer = ConnectionMultiplexer.Connect(options); 12 | 13 | // get an IDatabase here with GetDatabase 14 | var db = muxer.GetDatabase(); 15 | 16 | // add ping here 17 | Console.WriteLine($"ping: {db.Ping().TotalMilliseconds} ms"); 18 | // end programming challenge -------------------------------------------------------------------------------- /courseware/html/section_2/ru102n_2_2_0_redis_lists.html: -------------------------------------------------------------------------------- 1 | 4 | 5 |8 | Redis Lists are doubly linked lists that allow you to push and pop from the front and 9 | tail. This allows you to build what are in essence queues and stacks of Redis Strings. 10 | The StackExchange.Redis library provides an intuitive interface for working with Lists 11 | in the IDatabase that we will go over in this section. 12 |
-------------------------------------------------------------------------------- /courseware/transcripts/README.md: -------------------------------------------------------------------------------- 1 | # RU102N: Redis for .NET Developers: Video Transcripts 2 | 3 | This folder contains the video transcripts used for the RU102N: Redis for .NET Developers course from Redis University. These files are in [SubRip](https://en.wikipedia.org/wiki/SubRip) format. 4 | 5 | * [Sign up for the course here](https://university.redis.com/courses/ru102n/). 6 | * If you spot errors, or feel you can improve the materials, please [open an issue](https://github.com/redislabs-training/ru102n/issues) or [submit a pull request](https://github.com/redislabs-training/ru102n/pulls). 7 | 8 | Thanks, 9 | 10 | The Redis Developer Relations team. -------------------------------------------------------------------------------- /courseware/html/section_2/ru102n_2_3_0_redis_sets.html: -------------------------------------------------------------------------------- 1 |4 | Redis Sets are an implementation of a mathematical set. 5 | Like mathematical sets they have a number of key properties: 6 |
7 | 8 |15 | In this section we'll learn about how to leverage these properties using Redis Sets in .NET. 16 |
-------------------------------------------------------------------------------- /src/section_4/section4.1/section4.1.csproj: -------------------------------------------------------------------------------- 1 |4 | The Ad-Hoc API exposed by StackExchange.Redis is a powerful tool that allows you to execute Arbitrary commands against Redis. 5 |
6 |7 | Each of the 8 | Redis Stack libraries we'll be looking at in the forthcoming sections use this Ad-Hoc API to execute commands against Redis and to parse 9 | their results. In this section we'll look at how to run ad-hoc commands against Redis and parse their results. 10 |
11 |12 | We'll then use these ad-hoc 13 | commands to work with some of the Probabilistic Data Structures in Redis. 14 |
-------------------------------------------------------------------------------- /courseware/html/section_5/ru102n_5_0_0_unit_overview.html: -------------------------------------------------------------------------------- 1 |4 | Welcome to Unit 5 of RU102N. In this unit, we'll be covering the last two primary use cases of Redis Stack: 5 |
6 | 7 |13 | We'll be learning how to do all of this using Redis OM .NET, an Object Mapping library that 14 | facilities the storage and retrieval of your classes in Redis using LINQ. 15 |
-------------------------------------------------------------------------------- /courseware/html/section_1/ru102n_1_2_0_getting_started_with_stack_exhange_redis.html: -------------------------------------------------------------------------------- 1 | 4 |5 | Ok, so let's get started with StackExchange.Redis. In this bit, we'll look at some of 6 | the fundamental architectural choices of StackExchange.Redis. We'll discuss how to add it 7 | to your project, and then we'll go over how to connect to Redis from StackExchange.Redis 8 | and send the most basic of Redis Commands: PING. 9 |
-------------------------------------------------------------------------------- /src/section_3/section3.3/Models/SalesContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity; 3 | using System.Data.Entity.ModelConfiguration.Conventions; 4 | 5 | namespace section3._3.Models 6 | { 7 | public class SalesContext : DbContext 8 | { 9 | public DbSet10 | @Html.ActionLink("Help Page Home", "Index") 11 |
12 |@Model.Documentation
16 |4 | We'd be remiss if we went through an entire course about Redis, and did not mention ASP.NET or ASP.NET Core. In this unit we'll be looking 5 | at two of the more popular integrations of Redis in the ASP.NET ecosystem. 6 |
7 | 8 |14 | We'll be looking at how to do both of these in both ASP.NET and ASP.NET Core. We'll prioritize core as that's definitely the future of 15 | the ecosystem, but there are always a distinct possibility that you might be working on an older ASP.NET project that could use an integration. 16 |
-------------------------------------------------------------------------------- /courseware/html/section_4/ru102n_4_3_0_graph.html: -------------------------------------------------------------------------------- 1 |4 | Another feature of Redis Stack is the ability to work with Graph Databases. There are a few ways that 5 | you can interact with Graph Databases in Redis Stack: 6 |
7 | 8 |15 | In this section, we'll work with NRedisGraph to run our commands and use the results of some basic Graph Queries. 16 |
-------------------------------------------------------------------------------- /courseware/html/section_4/ru102n_4_2_0_timeseries_dotnet.html: -------------------------------------------------------------------------------- 1 |4 | Redis Stack supports a Time Series Data Structure, which allows your application to ingest and utilize time tagged numeric data in a series. 5 | There are three different modes that you can use to interact with the Time Series data structure in Redis. 6 |
7 | 8 |15 | In this section we'll be looking at how to use NRedisTimeSeries to interact with the Time Series Data Structure in Redis. 16 |
-------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/Views/Help/Api.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Web.Http 2 | @using section3._3.Areas.HelpPage.Models 3 | @model HelpPageApiModel 4 | 5 | @{ 6 | var description = Model.ApiDescription; 7 | ViewBag.Title = description.HttpMethod.Method + " " + description.RelativePath; 8 | } 9 | 10 | 11 |15 | @Html.ActionLink("Help Page Home", "Index") 16 |
17 |Possible enumeration values:
5 | 6 || Name | Value | Description |
|---|---|---|
| @value.Name | 15 |
16 | @value.Value 17 | |
18 |
19 | @value.Documentation 20 | |
21 |
6 | The public API of StackExchange.Redis is broken up across several critical 7 | interfaces. We'll briefly go over each of them in this section. You've 8 | actually already touched two of them IConnectionMultiplexer 9 | and IDatabase. 10 |
11 | 12 |8 | In this section we'll look at another really useful feature of Redis Stack and Redis OM, the ability to aggregate data within your 9 | documents together. Aggregations allow you to build pipelines for your documents to perform tasks such as: 10 |
11 | 12 |Redis, Inc is the home of Redis. We built Redis University, we sponsor the development of OSS Redis, and we're the creators of Redis Enterprise and Redis Cloud (for AWS, GCP, and Azure), the most sophisticated Redis deployments on the planet.
2 |Need a cloud-based Redis now? We welcome you to sign up for a free Redis Cloud Essentials instance.
-------------------------------------------------------------------------------- /courseware/html/section_1/ru102n_1_3_1_i_connection_multiplexer.html: -------------------------------------------------------------------------------- 1 | 4 |7 | The IConnectionMultiplexer is responsible for maintaining all of the 8 | connections to Redis. As I described in the previous section. It routes 9 | all the commands to Redis through a single connection for interactive commands, 10 | and a separate connection for subscription, which we'll discuss more in 11 | depth later. 12 |
13 | 14 |15 | The IConnectionMultiplexer is responsible for exposing a simple interface 16 | to get other critical interfaces of the library. Including the IDatabase, 17 | ISubscriber, and IServer. 18 |
-------------------------------------------------------------------------------- /courseware/html/section_0/ru102n_0_1_0_introduce_yourself.html: -------------------------------------------------------------------------------- 1 |We're so excited that you're taking this course and welcome you to Redis University!
2 |Did you know that hundreds of people from around the world are also taking this course at the same time as you? They are! I encourage you to stop by our Discord chat and introduce yourself.
3 |Once you've signed up, you'll find a channel for introductions at #introduce-yourself.
4 |And every course also has its own dedicated channel where you can talk to other people taking the same course.
5 |So come on by and say hello to your peers and the Redis Developer Relations team -- we look forward to meeting you.
6 |PS: Research suggests that learning with a group of people will boost your learning!
-------------------------------------------------------------------------------- /src/section_3/section3.5/README.md: -------------------------------------------------------------------------------- 1 | # Section 3.5 Special Instructions 2 | 3 | In section 3.5 we explore caching using Redis in ASP.NET, this section is completely optional as ASP.NET is now (somewhat) legacy having been largely supplanted by ASP.NET Core. None of the materials here will be included in the exam required to pass this course so if this is of no interest to you, feel free to skip. That said it should still be instructive for those of you still interested in ASP.NET to learn how to use Redis in this context, so please bear in mind that there are some additional requirements for this section. 4 | 5 | ## Additional Prerequisites 6 | 7 | * Because this uses ASP.NET and the .NET Framework, this needs to run on a Windows (preferably Windows 10+) machine or VM. 8 | * You must have the [.NET Framework 4.8.1 SDK](https://dotnet.microsoft.com/en-us/download/visual-studio-sdks) installed 9 | * It's highly recommended that you use either Visual Studio or Rider for this section. -------------------------------------------------------------------------------- /courseware/html/section_0/ru102n_0_3_0_course_setup.html: -------------------------------------------------------------------------------- 1 |To take this course successfully, you will need:
2 |Throughout the course, I've provided example code written in C# that you can run.
9 | 10 |If you don't have one or more of the prerequisites, you can follow the setup instructions in the course repo's README.
11 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Migrations/202211301905089_initial.Designer.cs: -------------------------------------------------------------------------------- 1 | //
12 | Request ID: @Model.RequestId
13 |
18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |
20 |21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |
26 | -------------------------------------------------------------------------------- /courseware/html/section_3/ru102n_3_1_0_derived_clients.html: -------------------------------------------------------------------------------- 1 |4 | In the .NET Redis Ecosystem, there are a variety of clients that are derived clients of StackExchange.Redis. In this unit we'll be looking 5 | at a few of them that are specifically built around ASP.NET and ASP.NET Core. 6 |
7 | 8 |9 | In general the derived clients of StackExchange.Redis take many of the same parameters as StackExchange.Redis does. However there are 10 | some important exceptions which we'll explore later in this unit. 11 |
12 |13 | In general these clients are configured along with the rest of your application, 14 | in the case of ASP.NET Core, they are typically best configured at application startup when configuring your application services. 15 |
16 |17 | Both of 18 | the cases we are going to explore here are heavily integrated into the ASP.NET stack, and you'll be surprised with how simple it is to get 19 | up and running with them. 20 |
-------------------------------------------------------------------------------- /courseware/html/section_4/ru102n_4_0_0_overview.html: -------------------------------------------------------------------------------- 1 |4 | Welcome to Unit 4 of RU102N. In this section we'll be taking a deeper look at Redis Stack. 5 |
6 | 7 |8 | Redis Stack enhances Redis with additional data structures and capabilities. These include: 9 |
10 | 11 |20 | Unit 4 will focus on the first three, while Unit 5 will focus exclusively on the last two. We'll explore the client ecosystem 21 | surrounding Redis Stack, and how you can leverage the ad-hoc API provided by StackExchange.Redis to execute any command you need to 22 | against Redis. 23 |
24 | -------------------------------------------------------------------------------- /courseware/html/section_6/ru102n_6_6_1_subscribe_youtube_twitch.html: -------------------------------------------------------------------------------- 1 |Redis Explained is a series of short, fun videos. Each episode covers a different Redis data type or topic. We'd love you to check out our YouTube channel and subscribe for regular updates!
3 | 4 | 5 |We also stream regularly on our Twitch.tv channel - follow us to be notified when we're live.
7 |Check out our complete event schedule on the Redis Developer site.
-------------------------------------------------------------------------------- /courseware/html/section_1/ru102n_1_2_2_add_stack_exchange_redis.html: -------------------------------------------------------------------------------- 1 | 4 |5 | There are of course a variety of ways to Add StackExchange.Redis to your project. 6 | From the base directory of the github project, first checkout the starting-point tag, 7 | this will leave you with a skeleton of the projects we are going to build in this course. 8 | Move to the src/section_1/section1.2 directory with cd src/section_1/section1.2. 9 |
10 |11 | This directory contains section1.2.csproj, which is a more or less empty csproj 12 | file. To Add StackExchange.Redis to this project, follow any of the methods outlined in 13 | NuGet, or just run: 14 | dotnet add package StackExchange.Redis 15 |
-------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/Views/Help/DisplayTemplates/Samples.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Net.Http.Headers 2 | @model DictionarySample not available.
22 | } 23 | else 24 | { 25 | @Html.DisplayFor(s => sample); 26 | } 27 | } 28 |8 | Transactions in Redis allow you to apply multiple commands in in isolation to Redis 9 | sequentially. StackExchange.Redis exposes the ITransaction which operationally is similar to the IBatch 10 | in that it allows you to dispatch a series of tasks, which you can then await after calling the Execute method 11 | to run the transaction. 12 |
13 |14 | Unlike IBatch however, all commands sent through a transaction are guaranteed to be executed 15 | sequentially. And you can apply some limited conditions to the transaction to allow it to self terminate if a watched 16 | key changes. In this section we'll learn how to work with Transactions in StackExchange.Redis. 17 |
-------------------------------------------------------------------------------- /src/section_3/section3.4/Views/Shared/_Layout.cshtml.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | a { 11 | color: #0077cc; 12 | } 13 | 14 | .btn-primary { 15 | color: #fff; 16 | background-color: #1b6ec2; 17 | border-color: #1861ac; 18 | } 19 | 20 | .nav-pills .nav-link.active, .nav-pills .show > .nav-link { 21 | color: #fff; 22 | background-color: #1b6ec2; 23 | border-color: #1861ac; 24 | } 25 | 26 | .border-top { 27 | border-top: 1px solid #e5e5e5; 28 | } 29 | .border-bottom { 30 | border-bottom: 1px solid #e5e5e5; 31 | } 32 | 33 | .box-shadow { 34 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 35 | } 36 | 37 | button.accept-policy { 38 | font-size: 1rem; 39 | line-height: inherit; 40 | } 41 | 42 | .footer { 43 | position: absolute; 44 | bottom: 0; 45 | width: 100%; 46 | white-space: nowrap; 47 | line-height: 60px; 48 | } 49 | -------------------------------------------------------------------------------- /courseware/html/section_6/ru102n_6_6_2_try_redis_cloud.html: -------------------------------------------------------------------------------- 1 | 15 |Thanks for completing this Redis University Course. We hope you enjoyed learning more about the world's most loved database. Here at Redis, we're excited to offer you the opportunity to experience Redis Enterprise, our best Redis experience.
17 |Redis Enterprise Cloud Essentials is a managed service providing a secure, scalable, and highly available Redis environment in the cloud. Sign up for our free tier to create your own private Redis Enterprise instance.
18 | 19 |8 | Using Redis as a Cache in ASP.NET Core is as simple as using the Distributed Cache API that's available for any manner of cache that you 9 | might use in ASP.NET Core. The only change that occurs when you add Redis to your caches in ASP.NET Core is that ASP.NET Core will 10 | use Redis as its cache provider. The remainder of the operations are abstracted away from us so we don't have to think about them. That 11 | means that fundamentally, the feature set provided by the Redis Cache Provider is limited to the IDistributedCache API. 12 |
13 | 14 |15 | In this section we'll be encountering our Employee Aggregation System for the first time, where we'll use a simple model, and running some 16 | aggregations against a SQLite database with Entity Framework to see how one might use a caching framework to remove the need to repeat 17 | major computation. 18 |
-------------------------------------------------------------------------------- /courseware/html/section_1/ru102n_1_3_3_i_server.html: -------------------------------------------------------------------------------- 1 | 4 | 5 |8 | The IServer is an abstraction to a single instance of a Redis Server. You can grab an instance of an IServer 9 | by using the IConnectionMultiplexer.GetServer command, passing in the exact endpoint information you want to 10 | retrieve. 11 |
12 |13 | IServer has a fundamentally different role than IDatabase as you're going to use it to handle the server 14 | level commands. That means that in general, data modeling commands are not appropriate to be used on a server. Rather 15 | operations like checking the server's info (the basic info of Redis), it's configuration, updating it's configuration, 16 | checking memory statistics, and the like are IServer operations. Even scanning for the keys of a Redis server should be 17 | done at the server level. 18 |
-------------------------------------------------------------------------------- /src/section_3/section3.2/section3.2.csproj: -------------------------------------------------------------------------------- 1 |8 | Connecting to Redis Sentinel 9 | is a bit different than connecting to other instances of Redis. 10 |
11 |12 | The key 13 | difference is that rather than connecting to the master server, you connect 14 | to one of the 'sentinels' - the instances of Redis responsible for monitoring 15 | your master and replicas, detecting fail-overs, and promoting new masters. 16 | 17 | Additionally, you must specify the ServiceName, which corresponds 18 | to the master name that you tell the sentinels to monitor when configuring them. 19 |
20 | 21 |22 |
23 | var options = new ConfigurationOptions
24 | {
25 | EndPoints = {"sentinel-1:26379"},
26 | ServiceName = "sentinel"
27 | };
28 |
29 | var muxer = ConnectionMultiplexer.Connect(options);
30 |
31 |
--------------------------------------------------------------------------------
/src/section_3/section3.3/Section3.3.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.3.32922.545
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "section3.3", "section3.3.csproj", "{B12C0F53-AA6D-4132-891A-CD6C7D3007BF}"
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 | {B12C0F53-AA6D-4132-891A-CD6C7D3007BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {B12C0F53-AA6D-4132-891A-CD6C7D3007BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {B12C0F53-AA6D-4132-891A-CD6C7D3007BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {B12C0F53-AA6D-4132-891A-CD6C7D3007BF}.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 = {6B4FFDDF-7895-4E6C-8A06-EF5BFCA4AF6D}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/src/section_3/section3.4/Program.cs:
--------------------------------------------------------------------------------
1 | using StackExchange.Redis;
2 |
3 | var builder = WebApplication.CreateBuilder(args);
4 |
5 | // Add services to the container.
6 | builder.Services.AddControllersWithViews();
7 |
8 | // TODO Section 3.4 Step 1
9 | // Add Redis Cache here.
10 | builder.Services.AddStackExchangeRedisCache(options => options.ConfigurationOptions = new ConfigurationOptions{
11 | EndPoints = { "localhost:6379" },
12 | Password = ""
13 | });
14 | // end Section 3.4 Step 1
15 |
16 | // add session service
17 | builder.Services.AddSession();
18 | var app = builder.Build();
19 |
20 | // Configure the HTTP request pipeline.
21 | if (!app.Environment.IsDevelopment())
22 | {
23 | app.UseExceptionHandler("/Home/Error");
24 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
25 | app.UseHsts();
26 | }
27 |
28 | app.UseHttpsRedirection();
29 | app.UseStaticFiles();
30 |
31 | app.UseRouting();
32 | app.UseAuthorization();
33 |
34 | // tell app to use session.
35 | app.UseSession();
36 |
37 | app.MapControllerRoute(
38 | name: "default",
39 | pattern: "{controller=Home}/{action=Index}/{id?}");
40 |
41 | app.Run();
42 |
--------------------------------------------------------------------------------
/src/section_3/section3.5/section3.5.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.3.32922.545
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "section3.5", "section3.5.csproj", "{7604CC12-E54E-42CE-9CE0-4C83CD42EC8D}"
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 | {7604CC12-E54E-42CE-9CE0-4C83CD42EC8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {7604CC12-E54E-42CE-9CE0-4C83CD42EC8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {7604CC12-E54E-42CE-9CE0-4C83CD42EC8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {7604CC12-E54E-42CE-9CE0-4C83CD42EC8D}.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 = {DED42B8C-7233-470C-8DB8-D84C147DADC2}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/courseware/html/section_1/ru102n_1_3_4_i_subscriber.html:
--------------------------------------------------------------------------------
1 |
4 |
5 | 8 | The ISubscriber is the interface responsible for maintaining subscriptions 9 | to Redis in the pub/sub interface. Unlike the other interfaces we've looked 10 | at thus far, the subscriber does not leverage the interactive connection. 11 |
12 | 13 |14 | The Multiplexer explicitly opens a separate connection for subscriptions 15 | because when you subscribe to any channel on a client in Redis, the client 16 | connection converts to subscription mode. This limits the connection to only use commands that implement subscriber functionality. 17 |
18 | 19 |20 | True to it's name however, the Multiplexer continues to maintain a single 21 | connection per server, and all subscriptions are handled on that single 22 | connection. 23 |
24 | 25 |26 | You you can get an instance of an ISubscriber by calling the 27 | IConnectionMultiplexer.GetSubscriber() method. 28 |
-------------------------------------------------------------------------------- /src/section_3/section3.4/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/section_3/section3.2/Program.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using section3._2; 3 | using StackExchange.Redis; 4 | 5 | var builder = WebApplication.CreateBuilder(args); 6 | 7 | // Add services to the container. 8 | 9 | builder.Services.AddControllers().AddNewtonsoftJson(x=>x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore); 10 | // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle 11 | builder.Services.AddEndpointsApiExplorer(); 12 | builder.Services.AddSwaggerGen(); 13 | builder.Services.AddDbContext4 | Pub/Sub allows for a subscriber to listen for events on channels in Redis using the 5 | Publisher/Subscriber messaging pattern. 6 |
7 |8 | Pub/Sub is unique in StackExchange.Redis as it is the only thing the library does that is not 9 | on the main interactive connection. Earlier in the course I mentioned that StackExchange.Redis opens two connection to Redis at a time. 10 |
11 |12 | The first of these is the interactive connection that you use to send all of your interactive commands to Redis on. The other is the subscriber 13 | connection. There's a really good reason for this, after subscribing to a channel in Redis, Redis flips the connection over to Subscriber 14 | mode which does not allow any non pub/sub related commands across, allowing it to send messages back to the client unhindered by other 15 | traffic on the channel. 16 |
17 | 18 |19 | In this section, we'll be learning how to use the pub/sub API in StackExchange.Redis. How to subscribe to channels, and handle messages 20 | that are dispatched from Redis to the client. 21 |
-------------------------------------------------------------------------------- /courseware/html/section_1/ru102n_1_2_4_coding_challenge_solution.html: -------------------------------------------------------------------------------- 1 | 4 |5 | The following is what my code looked like after the previous exercise, yours might 6 | be slightly different, and that's ok! but fundamentally, you should have: 7 |
8 | 9 |17 |
18 | // Start Programming Challenge
19 | using StackExchange.Redis;
20 | Console.WriteLine("Hello Redis!");
21 |
22 | var muxer = ConnectionMultiplexer.Connect(new ConfigurationOptions
23 | {
24 | EndPoints = {"localhost:6379"}
25 | });
26 |
27 | var db = muxer.GetDatabase();
28 | var res = db.Ping();
29 | Console.WriteLine($"The ping took: {res.TotalMilliseconds} ms");
30 | //End Programming Challenge
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/section_3/section3.3/Areas/HelpPage/SampleGeneration/ImageSample.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace section3._3.Areas.HelpPage
4 | {
5 | /// 4 | For our employee aggregations example, we'll keep it simple, we'll have two components of our model, Employees and Sales. They'll 5 | look like this: 6 |
7 | 8 |9 |
10 | public class Employee
11 | {
12 | public int EmployeeId { get; set; }
13 | public string Name { get; set; }
14 | public List<Sale> Sales { get; } = new();
15 | }
16 |
17 | public class Sale
18 | {
19 | public int SaleId { get; set; }
20 | public int Total { get; set; }
21 |
22 | public int EmployeeId { get; set; }
23 | public Employee Employee { get; set; }
24 | }
25 |
26 |
27 |
28 | 29 | We'll use Entity Framework and a local SQLite database for our example. If you are using a remote Redis Database, keep in mind that you'll 30 | incur some latency over the network when going to Redis vs going to our SQLite database, so if you want to truly compare apples to apples 31 | you can either run Redis locally (see the course setup instructions), or you can use a remote SQL Database by updating the adapter we're using in our 32 | example. 33 |
-------------------------------------------------------------------------------- /src/section_3/section3.2/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:62837", 8 | "sslPort": 44314 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5053", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7234;http://localhost:5053", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/Views/Help/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Web.Http 2 | @using System.Web.Http.Controllers 3 | @using System.Web.Http.Description 4 | @using System.Collections.ObjectModel 5 | @using section3._3.Areas.HelpPage.Models 6 | @model Collection28 | Provide a general description of your APIs here. 29 |
30 |2 | In this unit we'll be introducing the StackExchange.Redis Client as the primary 3 | interactive Redis client for the .NET ecosystem. In this unit we'll explore: 4 |
5 | 6 |18 | Throughout this unit, I'll have Hands-On materials for you to work through 19 | and code to actually let you get your hands dirty. These bits aren't graded, 20 | but you should ought to work through them all, what better way to learn is there than 21 | actually writing some code and seeing it work? 22 |
23 |24 | By the end of this unit, you'll 25 | have a firm grasp as to the fundamentals of the StackExchange.Redis library, 26 | and how to use it in your applications. 27 |
-------------------------------------------------------------------------------- /src/section_3/section3.5/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Optimization; 3 | 4 | namespace section3._5 5 | { 6 | public class BundleConfig 7 | { 8 | // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862 9 | public static void RegisterBundles(BundleCollection bundles) 10 | { 11 | bundles.Add(new ScriptBundle("~/bundles/jquery").Include( 12 | "~/Scripts/jquery-{version}.js")); 13 | 14 | bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( 15 | "~/Scripts/jquery.validate*")); 16 | 17 | // Use the development version of Modernizr to develop with and learn from. Then, when you're 18 | // ready for production, use the build tool at https://modernizr.com to pick only the tests you need. 19 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( 20 | "~/Scripts/modernizr-*")); 21 | 22 | bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( 23 | "~/Scripts/bootstrap.js")); 24 | 25 | bundles.Add(new StyleBundle("~/Content/css").Include( 26 | "~/Content/bootstrap.css", 27 | "~/Content/site.css")); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /courseware/html/section_6/ru102n_6_0_0_final_exam_introduction.html: -------------------------------------------------------------------------------- 1 |You've now completed all of the course materials. You're almost to the finishing line!
Now, it's time for the final exam. Here are a few things to know before you get started:
3 |After you've submitted your answers, you'll be graded automatically. If you receive a final grade of 65% or more, then you'll earn a certificate of completion.
Instructions are provided at the end of this section to generate and view your certificate, along with how to add the certificate to your LinkedIn profile.
And don't forget that the course Discord channel is still available if you have any questions or need assistance.
Thanks for sticking with it so far, and good luck with the exam!
12 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |8 | Of the "advanced" Redis Connections, cluster is probably the easiest to 9 | understand. Connecting to an OSS Cluster instance is the same as connecting 10 | to a standalone Redis Instance. The only exception is that when you are 11 | listing endpoints, you'll want to use more than one. This is so that if 12 | the endpoint you are trying to reach has failed over, the Multiplexer 13 | still has a chance to connect to the other master instances. 14 |
15 | 16 |17 | An example ConfigurationOptions for a cluster instance might look something along the lines of this, notice 18 | how the Endpoints collection takes multiple endpoints which the ConnectionMultiplexer can use as backups if 19 | one of the endpoints should fail to respond (possibly because it's failed over). 20 |
21 | 22 |23 |
24 | var options = new ConfigurationOptions
25 | {
26 | // add and update parameters as needed
27 | EndPoints = {"redis-1:6379", "redis-2:6379", "redis-3:6379"}
28 | };
29 |
30 |
--------------------------------------------------------------------------------
/courseware/html/section_1/ru102n_1_3_2_i_database.html:
--------------------------------------------------------------------------------
1 |
4 |
5 | 8 | The IDatabase can be thought of as the primary interactive interface to Redis. 9 | It provides a single interface for your entire Redis Instance, and is the 10 | preferred interface when you are executing single commands that manipulate 11 | your application's data to Redis. 12 |
13 | 14 |15 | The IDatabase, unlike the IServer, abstracts the particulars of your Redis 16 | deployments away. Consequentially, if you are running in a cluster and are 17 | preforming a write, the IDatabase does not require you to know which server 18 | in particular you need to write to. Also, if you have many replicas per master 19 | shard in your Cluster 20 | or Sentinel Redis 21 | deployments, the IDatabase will leverage the ConnectionMultiplexer to 22 | automatically distribute your reads across your deployment. 23 |
-------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/Views/Help/DisplayTemplates/ApiGroup.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Web.Http 2 | @using System.Web.Http.Controllers 3 | @using System.Web.Http.Description 4 | @using section3._3.Areas.HelpPage 5 | @using section3._3.Areas.HelpPage.Models 6 | @model IGrouping@controllerDocumentation
18 | } 19 || API | Description |
|---|---|
| @api.HttpMethod.Method @api.RelativePath | 28 |
29 | @if (api.Documentation != null)
30 | {
31 | @api.Documentation 32 | } 33 | else 34 | { 35 |No documentation available. 36 | } 37 | |
38 |
8 | The ITransaction provides an interface for Redis Transactions. 9 | Transactions in Redis differ from transactions in other databases, for a full 10 | description of transactions check out the transaction section of 11 | RU101. 12 |
13 | 14 |15 | The ITransaction interface is fundamentally an async interface. It exposes 16 | a very similar command set to the IDatabase, but it will only expose async 17 | versions of each command. That is because each command in ITransaction is 18 | async, as they will not be competed until after Execute is called. 19 | Only after the Execute is called can the underpinning tasks for the 20 | Transaction be awaited. 21 |
22 | 23 |24 | You can get an instance of an ITransaction by calling 25 | IDatabase.GetTransaction() on your IDatabase object. 26 |
-------------------------------------------------------------------------------- /src/section_2/section2.8/Program.cs: -------------------------------------------------------------------------------- 1 | using StackExchange.Redis; 2 | 3 | var muxer = ConnectionMultiplexer.Connect("localhost"); 4 | var db = muxer.GetDatabase(); 5 | 6 | // TODO for Coding Challenge Start here on starting-point branch 7 | var transaction = db.CreateTransaction(); 8 | 9 | transaction.HashSetAsync("person:1", new HashEntry[] 10 | { 11 | new ("name", "Steve"), 12 | new ("age", 32), 13 | new ("postal_code", "32999") 14 | }); 15 | transaction.SortedSetAddAsync("person:name:Steve", "person:1", 0); 16 | transaction.SortedSetAddAsync("person:postal_code:32999", "person:1", 0); 17 | transaction.SortedSetAddAsync("person:age", "person:1", 32); 18 | 19 | var success = transaction.Execute(); 20 | Console.WriteLine($"Transaction Successful: {success}"); 21 | 22 | // add condition that age == 32 23 | 24 | transaction.AddCondition(Condition.HashEqual("person:1", "age", 32)); 25 | transaction.HashIncrementAsync("person:1", "age"); 26 | transaction.SortedSetIncrementAsync("person:age", "person:1", 1); 27 | 28 | success = transaction.Execute(); 29 | Console.WriteLine($"Transaction Successful: {success}"); 30 | 31 | // Add a condition that will fail (e.g. age == 31) 32 | 33 | transaction.AddCondition(Condition.HashEqual("person:1", "age", 31)); 34 | transaction.HashIncrementAsync("person:1", "age"); 35 | transaction.SortedSetIncrementAsync("person:age", "person:1", 1); 36 | success = transaction.Execute(); 37 | 38 | Console.WriteLine($"Transaction Successful: {success}"); 39 | // end coding challenge 40 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Migrations/202211301905089_initial.cs: -------------------------------------------------------------------------------- 1 | namespace section3._3.Migrations 2 | { 3 | using System; 4 | using System.Data.Entity.Migrations; 5 | 6 | public partial class initial : DbMigration 7 | { 8 | public override void Up() 9 | { 10 | CreateTable( 11 | "dbo.Employee", 12 | c => new 13 | { 14 | EmployeeId = c.Int(nullable: false, identity: true), 15 | Name = c.String(), 16 | }) 17 | .PrimaryKey(t => t.EmployeeId); 18 | 19 | CreateTable( 20 | "dbo.Sale", 21 | c => new 22 | { 23 | SaleId = c.Int(nullable: false, identity: true), 24 | Total = c.Int(nullable: false), 25 | EmployeeId = c.Int(nullable: false), 26 | }) 27 | .PrimaryKey(t => t.SaleId) 28 | .ForeignKey("dbo.Employee", t => t.EmployeeId, cascadeDelete: true) 29 | .Index(t => t.EmployeeId); 30 | 31 | } 32 | 33 | public override void Down() 34 | { 35 | DropForeignKey("dbo.Sale", "EmployeeId", "dbo.Employee"); 36 | DropIndex("dbo.Sale", new[] { "EmployeeId" }); 37 | DropTable("dbo.Sale"); 38 | DropTable("dbo.Employee"); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Migrations/202211302024328_initial.cs: -------------------------------------------------------------------------------- 1 | namespace section3._3.Migrations 2 | { 3 | using System; 4 | using System.Data.Entity.Migrations; 5 | 6 | public partial class initial : DbMigration 7 | { 8 | public override void Up() 9 | { 10 | CreateTable( 11 | "dbo.Employee", 12 | c => new 13 | { 14 | EmployeeId = c.Int(nullable: false, identity: true), 15 | Name = c.String(), 16 | }) 17 | .PrimaryKey(t => t.EmployeeId); 18 | 19 | CreateTable( 20 | "dbo.Sale", 21 | c => new 22 | { 23 | SaleId = c.Int(nullable: false, identity: true), 24 | Total = c.Int(nullable: false), 25 | EmployeeId = c.Int(nullable: false), 26 | }) 27 | .PrimaryKey(t => t.SaleId) 28 | .ForeignKey("dbo.Employee", t => t.EmployeeId, cascadeDelete: true) 29 | .Index(t => t.EmployeeId); 30 | 31 | } 32 | 33 | public override void Down() 34 | { 35 | DropForeignKey("dbo.Sale", "EmployeeId", "dbo.Employee"); 36 | DropIndex("dbo.Sale", new[] { "EmployeeId" }); 37 | DropTable("dbo.Sale"); 38 | DropTable("dbo.Employee"); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/section_3/section3.3/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("section3._3")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("section3._3")] 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("083a157a-db65-4f53-8019-89b988df7552")] 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/section_3/section3.5/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("section3._5")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("section3._5")] 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("52e068cf-7ff5-45bf-9a71-cb60f50f4ca9")] 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/section_5/section5.2/Program.cs: -------------------------------------------------------------------------------- 1 | using Redis.OM; 2 | using Redis.OM.Modeling; 3 | using section5._2; 4 | 5 | var provider = new RedisConnectionProvider("redis://localhost:6379"); 6 | 7 | provider.Connection.DropIndexAndAssociatedRecords(typeof(Sale)); 8 | provider.Connection.DropIndexAndAssociatedRecords(typeof(Employee)); 9 | 10 | await provider.Connection.CreateIndexAsync(typeof(Sale)); 11 | await provider.Connection.CreateIndexAsync(typeof(Employee)); 12 | 13 | // TODO for Coding Challenge Start here on starting-point branch 14 | var employees = provider.RedisCollectionASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS, and JavaScript.
4 | 5 |ASP.NET Web API is a framework that makes it easy to build HTTP services that reach 10 | a broad range of clients, including browsers and mobile devices. ASP.NET Web API 11 | is an ideal platform for building RESTful applications on the .NET Framework.
12 | 13 |NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.
17 | 18 |You can easily find a web hosting company that offers the right mix of features and price for your applications.
22 | 23 |8 | Redis Streams are an append-only log like data structure that allows you to enqueue messages from producers to be consumed by consumers in 9 | your application. They are a powerful data structure with a rich feature set, and for a full explanation as to how and why to use Redis Streams, 10 | you can checkout RU202: Redis Streams. 11 |
12 | 13 |14 | In this section, we'll explore using Redis Streams in .NET using the StackExchange.Redis library. We'll learn how to: 15 |
16 | 17 |26 | Due to the multiplexed nature of StackExchange.Redis, it's important to note at the top that there is no mechanism for using the blocking 27 | paradigms available within the stream reading operations. 28 |
29 |30 | This means that the Stream Read operations, StreamRead & StreamReadGroup, will 31 | not be able to use the XREAD and XREADGROUP block timer or the special $ id to read only new messages. 32 |
-------------------------------------------------------------------------------- /src/section_5/section5.5/Model.cs: -------------------------------------------------------------------------------- 1 | using Redis.OM.Modeling; 2 | 3 | namespace section5._5; 4 | 5 | [Document(StorageType = StorageType.Json, Prefixes = new []{"Employee"}, IndexName = "employees")] 6 | public class Employee 7 | { 8 | [RedisIdField] 9 | [Indexed] 10 | public string? Id { get; set; } 11 | [Indexed] 12 | public List8 | In this Hands-On, we'll be exploring how to use Session State Management in ASP.NET Core. 9 | You'll likely want to open up the csproj file and check out the starting-point 10 | branch before proceeding, unless of course you'd prefer to build everything from scratch. 11 |
12 |13 | The csproj file is located at /src/section_3/section3.4/section3.4.csproj. 14 |
15 | 16 |17 | Session state is the state maintained between the client's browser and a web server. However as we live in a world of increasingly larger 18 | distributed systems, we run into a problem. Do we really want the client to be dependent on a single, theoretically stateless application 19 | server? 20 |
21 |22 | The answer is no, yet this session-state can be absolutely critical for the functionality of some applications. Hence it's often 23 | really helpful to have a intermediate database act as a central holder for this session state. This pattern is so popular in fact that it's 24 | heavily integrated into both ASP.NET and ASP.NET Core. 25 |
26 |27 | Since Redis is so often tapped as the database acting as the distributed session 28 | state store, there are very straightforward integrations to add Redis as a native integration which we'll be exploring throughout the next 29 | couple of sections. 30 |
31 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Areas/HelpPage/ApiDescriptionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Web; 4 | using System.Web.Http.Description; 5 | 6 | namespace section3._3.Areas.HelpPage 7 | { 8 | public static class ApiDescriptionExtensions 9 | { 10 | ///8 | ASP.NET has a well established Distributed Session State Provider for Redis called Microsoft.Web.RedisSessionStateProvider. 9 | It allows for a proper Integration of Session State with Redis, and similar to the ASP.NET Core case, is quite easy to get up and running with. 10 |
11 | 12 |13 | In this section, we'll be walking through a very simple application that leverages Session State, and see how to add Redis as a Provider of 14 | distributed session state in ASP.NET. 15 |
16 | 17 |18 | Because this is ASP.NET, this section is considered optional. None of the questions on the final exam will be derived from the material from this 19 | section. However, if you still work on non-core ASP.NET apps, this can still be quite useful, so if it's useful to you, I'd encourage you 20 | to walk through this tutorial. 21 |
22 | 23 || Name | Description | Type | Additional information |
|---|---|---|---|
| @parameter.Name | 20 |
21 | @parameter.Documentation 22 | |
23 | 24 | @Html.DisplayFor(m => modelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = modelDescription }) 25 | | 26 |
27 | @if (parameter.Annotations.Count > 0)
28 | {
29 | foreach (var annotation in parameter.Annotations)
30 | {
31 | @annotation.Documentation 32 | } 33 | } 34 | else 35 | { 36 |None. 37 | } 38 | |
39 |
None.
47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/section_3/section3.3/Controllers/AverageController.cs: -------------------------------------------------------------------------------- 1 | using section3._3.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Net.Http; 7 | using System.Threading.Tasks; 8 | using System.Web.Http; 9 | using System.Web.Http.Description; 10 | using System.Diagnostics; 11 | using System.Data.Entity; 12 | 13 | namespace section3._3.Controllers 14 | { 15 | public class AverageController : ApiController 16 | { 17 | private SalesContext _salesContext = new SalesContext(); 18 | 19 | 20 | [ResponseType(typeof(Dictionary@description.Documentation
13 | 14 |@Model.RequestDocumentation
22 | 23 | @if (Model.RequestModelDescription != null) 24 | { 25 | @Html.DisplayFor(m => m.RequestModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.RequestModelDescription }) 26 | if (Model.RequestBodyParameters != null) 27 | { 28 | @Html.DisplayFor(m => m.RequestBodyParameters, "Parameters") 29 | } 30 | } 31 | else 32 | { 33 |None.
34 | } 35 | 36 | @if (Model.SampleRequests.Count > 0) 37 | { 38 |@description.ResponseDescription.Documentation
47 | 48 | @if (Model.ResourceDescription != null) 49 | { 50 | @Html.DisplayFor(m => m.ResourceDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ResourceDescription }) 51 | if (Model.ResourceProperties != null) 52 | { 53 | @Html.DisplayFor(m => m.ResourceProperties, "Parameters") 54 | } 55 | } 56 | else 57 | { 58 |None.
59 | } 60 | 61 | @if (Model.SampleResponses.Count > 0) 62 | { 63 |4 | Welcome to Unit 2 of RU102N: Redis for .NET Developers. In the previous unit 5 | we covered the basics of how to connect and use the StackExchange.Redis library. In 6 | this unit we will get into the nitty gritty of how to use various Redis Data 7 | structures and features from StackExchange.Redis. In this unit we will cover: 8 |
9 | 10 |23 | We've linked to each of the relevant articles for each concept on redis.io. 24 | If you want a full explanation of each of these, and you haven't taken 25 | RU101: Introduction to Redis Data Structures, 26 | that course has full explanations for each of these concepts, and can be a great resource. 27 |
28 |29 | In this unit we will briefly introduce the concepts and demonstrate the mechanics of 30 | using them using the StackExchange.Redis library. 31 |
-------------------------------------------------------------------------------- /src/section_1/section1.5/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using StackExchange.Redis; 3 | 4 | var options = new ConfigurationOptions 5 | { 6 | EndPoints = { "localhost:6379" } 7 | }; 8 | 9 | var muxer = ConnectionMultiplexer.Connect(options); 10 | var db = muxer.GetDatabase(); 11 | 12 | var stopwatch = Stopwatch.StartNew(); 13 | // TODO for Coding Challenge Start here on starting-point branch 14 | // un-pipelined commands incur the added cost of an extra network round trip 15 | for (var i = 0; i < 1000; i++) 16 | { 17 | await db.PingAsync(); 18 | } 19 | 20 | Console.WriteLine($"1000 un-pipelined commands took: {stopwatch.ElapsedMilliseconds}ms to execute"); 21 | 22 | // If we run out async tasks to StackExchange.Redis concurrently, the library 23 | // will automatically manage pipelining of these commands to Redis, making 24 | // them significantly more performant as we remove most of the network round trips to Redis. 25 | var pingTasks = new List4 | Before we get started here, just a quick note... the sections on ASP.NET are completely optional, they are here because there are many 5 | developers still using ASP.NET, so this can be quite useful to them. 6 |
7 |8 | But the reality is that ASP.NET is rapidly becoming a largely 9 | legacy framework with the emergence of ASP.NET Core. So if you don't think the sections on ASP.NET will be useful to you, feel free to skip them. 10 |
11 |12 | None of the questions on the exam will involve this material. 13 |
14 | 15 |16 | Doing simple caching in ASP.NET is the only one of the use cases we'll discuss in this unit that does not involve the use of some derived 17 | library. It's a simple enough way to use Redis that one isn't particularly needed (though when you compare it to ASP.NET Core you'll see 18 | why a framework integration can be really nice). 19 |
20 | 21 |22 | In this section, we'll walk through an application with the same model as the ASP.NET Core example, the major differences are that instead 23 | of using EntityFramework Core, we use EntityFramework, and instead of using ASP.NET Core WebAPI we are using the ASP.NET API scaffolding, 24 | consequentially the structure of the projects are quite different. 25 |
26 | 27 |8 | Pipelining is a critically important concept for maximizing throughput to 9 | Redis. When you need to execute multiple commands against Redis, and the 10 | intermediate results can be temporarily ignored, pipelining can drastically 11 | reduce the number of round trips required to Redis, which can drastically 12 | increase performance, as many operations are hundreds of times faster than 13 | the Round Trip Time (RTT). 14 |
15 | 16 |17 | With StackExchange.Redis, there are two ways to pipeline commands, 18 | either implicitly with the Async API, and explicitly with the IBatch API. 19 |
20 | 21 |24 | If you use the async version of a command, the command will be automatically 25 | pipelined to Redis. If you use await to await the result of a 26 | task dispatched by one of these async commands, it will wait until the command 27 | is complete before returning control. However, if you group a set of tasks dispatched 28 | by the async methods together and await them all in one shot, the ConnectionMultiplexer 29 | will automatically find an efficient way to pipeline the commands to Redis, so that 30 | you can cut down the number of round trips significantly. 31 |
32 | 33 |36 | You can also be much more explicit about pipelining commands. The IBatch 37 | API only provides the async interface for commands. You can set up however many commands 38 | you want to pipeline with those async methods, preserving the tasks as they will provide 39 | you the results. 40 |
41 |
42 | When you have all the commands that you want pipelined dispatched,
43 | you can call Execute to run them all. This will pipeline all of your commands
44 | in one contiguous block to Redis. Using this method, no other commands will be interleaved
45 | with your batched commands from the client. However, if there are other clients sending
46 | commands to Redis, it's possible that their commands will be interleaved with the batched
47 | commands.
48 |
Once you have completed your final exam, if your combined grade for homework and the final exam is 65% or more, you will be eligible for a Certificate of Completion.
3 |Here are the steps to obtain your certificate:
4 |Navigate to the Progress Tab. Once here, if you have achieved 65% or more, then the Request Certificate button will be enabled.
6 |
Click on the View Certificate button.
9 |
You can now download and print your Certificate.
12 |
Yes! Its simple to add your certificate to your LinkedIn profile. This has the added benefit that your current and future employers can verify the authenticity of your certificate! Follow these simple instructions to add your certificate.
15 |
Add the Certificate details. This information comes from the Certificate your downloaded.
19 |
You need two items from the Certificate, indicated in the diagram below.
22 |
After you have added the certificate details, you can now view your new accomplishment!
25 |