PageSourceSearch

https://openfeature.dev/assets/js/b3fe8fb2.32e0df00.js

js openfeature.dev collected 2026-09-24 08:39:52 UTC 15,671 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkdocs||=[]).push([[5799],{68066(e,n,t){t.d(n,{Ay:()=>o});var r=t(74848),a=t(28453);function i(e){const n={code:"code",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(n.p,{children:["Let's change the feature flag in our ",(0,r.jsx)(n.code,{children:"flags.flagd.json"}),", making ",(0,r.jsx)(n.code,{children:"defaultVariant"})," to ",(0,r.jsx)(n.code,{children:"on"})]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "flags": {\n    "welcome-message": {\n      "variants": {\n        "on": true,\n        "off": false\n      },\n      "state": "ENABLED",\n// diff-remove\n      "defaultVariant": "off"\n// diff-add\n      "defaultVariant": "on"\n    }\n  }\n}\n'})})]})}function o(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(i,{...e})}):i(e)}t.d(n,["RM",0,[]])},65735(e,n,t){t.d(n,{Ay:()=>o});var r=t(74848),a=t(28453);function i(e){const n={a:"a",blockquote:"blockquote",code:"code",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"Providers are an important concept in OpenFeature because they are responsible for the flag evaluation itself.\nAs we saw in the previous step, OpenFeature without a provider always returns the default value. If we want to actually perform feature\nflagging, we'll need to register a provider."}),"\n",(0,r.jsxs)(n.p,{children:["Create a new file named ",(0,r.jsx)(n.code,{children:"flags.flagd.json"})," and add the following JSON. Notice that there's a flag called ",(0,r.jsx)(n.code,{children:"welcome-message"})," which matches the flag\nkey referenced earlier. The ",(0,r.jsx)(n.code,{children:"welcome-message"})," flag has ",(0,r.jsx)(n.code,{children:"on"})," and ",(0,r.jsx)(n.code,{children:"off"})," variants that return ",(0,r.jsx)(n.code,{children:"true"})," and ",(0,r.jsx)(n.code,{children:"false"})," respectively.\nThe state property controls whether the feature flag is active or not. Finally, the defaultVariant property controls the variant that should be returned.\nIn this case, the defaultVariant is ",(0,r.jsx)(n.code,{children:"off"}),", therefore the value ",(0,r.jsx)(n.code,{children:"false"})," would be returned."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "flags": {\n    "welcome-message": {\n      "variants": {\n        "on": true,\n        "off": false\n      },\n      "state": "ENABLED",\n      "defaultVariant": "off"\n    }\n  }\n}\n'})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"NOTE: This configuration is specific for flagd and varies across providers."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"With the flagd configuration in place, start flagd service with the following docker command."}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["NOTE: On Windows WSL is required both for running docker and to store the file. This is a limitation of Docker (",(0,r.jsx)(n.a,{href:"https://github.com/docker/for-win/issues/8479",children:"https://github.com/docker/for-win/issues/8479"}),")"]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"docker run -p 8013:8013 -v $(pwd)/:/etc/flagd/ -it ghcr.io/open-feature/flagd:latest start --uri file:/etc/flagd/flags.flagd.json\n"})})]})}function o(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(i,{...e})}):i(e)}t.d(n,["RM",0,[]])},6197(e,n,t){t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"tutorials/getting-started/dotnet","title":".NET SDK and ASP.NET Core","description":"Getting Started with the OpenFeature .NET SDK","source":"@site/docs/tutorials/getting-started/dotnet.mdx","sourceDirName":"tutorials/getting-started","slug":"/tutorials/getting-started/dotnet","permalink":"/docs/tutorials/getting-started/dotnet","draft":false,"unlisted":false,"editUrl":"https://github.com/open-feature/openfeature.dev/edit/main/docs/tutorials/getting-started/dotnet.mdx","tags":[],"version":"current","frontMatter":{"title":".NET SDK and ASP.NET Core","description":"Getting Started with the OpenFeature .NET SDK"},"sidebar":"tutorials","previous":{"title":"Spring Boot","permalink":"/docs/tutorials/getting-started/java/spring-boot"},"next":{"title":"Go SDK and Go Gin","permalink":"/docs/tutorials/getting-started/go"}}');var a=t(74848),i=t(28453),o=t(65735),l=t(68066);const s={title:".NET SDK and ASP.NET Core",description:"Getting Started with the OpenFeature .NET SDK"},d="Getting Started with the OpenFeature .NET SDK",c={},h=[{value:"Introduction",id:"introduction",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Walk-through",id:"walk-through",level:2},{value:"Step 1: Create a .NET 8 Web application",id:"step-1-create-a-net-8-web-application",level:3},{value:"Step 2: Add dependencies",id:"step-2-add-dependencies",level:3},{value:"Step 3: Add code",id:"step-3-add-code",level:3},{value:"Step 4: Run the initial application",id:"step-4-run-the-initial-application",level:3},{value:"Step 5: Configure a provider (flagd)",id:"step-5-configure-a-provider-flagd",level:3},...o.RM,{value:"Step 6: Rerun the application",id:"step-6-rerun-the-application",level:3},...l.RM,{value:"Conclusion",id:"conclusion",level:2}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"getting-started-with-the-openfeature-net-sdk",children:"Getting Started with the OpenFeature .NET SDK"})}),"\n",(0,a.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,a.jsx)(n.p,{children:"This walk-through teaches you the basics of using OpenFeature in .NET within a ASP.NET Core Web application."}),"\n",(0,a.jsx)(n.p,{children:"You'll learn how to:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Integrate the OpenFeature .NET SDK"}),"\n",(0,a.jsx)(n.li,{children:"Install and configure the OpenFeature provider"}),"\n",(0,a.jsx)(n.li,{children:"Perform basic feature flagging"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,a.jsx)(n.p,{children:"This walk-through assumes that:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"You have a basic knowledge of C# and .
1NET"}),"\n",(0,a.jsxs)(n.li,{children:["You have installed the ",(0,a.jsx)(n.a,{href:"https://dotnet.microsoft.com/en-us/",children:".NET 8"})," or later SDK"]}),"\n",(0,a.jsx)(n.li,{children:"You have Docker installed and running on the host system"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"walk-through",children:"Walk-through"}),"\n",(0,a.jsx)(n.h3,{id:"step-1-create-a-net-8-web-application",children:"Step 1: Create a .NET 8 Web application"}),"\n",(0,a.jsxs)(n.p,{children:["To get started you can use the .NET SDK to initialise a web application.\nOpen a terminal (",(0,a.jsx)(n.strong,{children:"shell"}),", ",(0,a.jsx)(n.strong,{children:"Command Prompt"}),", or ",(0,a.jsx)(n.strong,{children:"bash"}),") and paste the following commands:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"dotnet new webapi -o openfeature-dotnet-sample\ncd openfeature-dotnet-sample\ndotnet run\n"})}),"\n",(0,a.jsx)(n.h3,{id:"step-2-add-dependencies",children:"Step 2: Add dependencies"}),"\n",(0,a.jsxs)(n.p,{children:["With NuGet you can install the latest ",(0,a.jsx)(n.a,{href:"https://www.nuget.org/packages/OpenFeature",children:"OpenFeature"})," package into your .NET web application."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"dotnet add package OpenFeature\ndotnet add package OpenFeature.Hosting\n"})}),"\n",(0,a.jsx)(n.h3,{id:"step-3-add-code",children:"Step 3: Add code"}),"\n",(0,a.jsxs)(n.p,{children:["The following will initialise an ",(0,a.jsx)(n.code,{children:"InMemoryProvider"})," for use within the web application.\nOpen a code editor and add the C# code below to the Program.cs."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-csharp",children:'// diff-add-block-start\nusing Microsoft.AspNetCore.Mvc;\nusing OpenFeature;\nusing OpenFeature.Hosting.Providers.Memory;\nusing OpenFeature.Providers.Memory;\n// diff-add-block-end\n\nvar builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\n// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi\nbuilder.Services.AddOpenApi();\n\n// diff-add-block-start\n// Register your feature flag provider\nbuilder.Services.AddOpenFeature(featureBuilder =>\n{\n    featureBuilder\n        .AddInMemoryProvider(_ => new Dictionary<string, Flag>()\n        {\n            {\n                "welcome-message", new Flag<bool>(\n                    new Dictionary<string, bool> { { "show", true }, { "hide", false } }, "show")\n            }\n        });\n});\n// diff-add-block-end\n\nvar app = builder.Build();\n\n// Configure the HTTP request pipeline.\nif (app.Environment.IsDevelopment())\n{\n    app.MapOpenApi();\n}\n\napp.UseHttpsRedirection();\n\n//diff-remove-block-start\nvar summaries = new[]\n{\n    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"\n};\n//diff-remove-block-end\n\n//diff-remove-block-start\napp.MapGet("/weatherforecast", () =>\n{\n    var forecast = Enumerable.Range(1, 5).Select(index =>
1\n        new WeatherForecast\n        (\n            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),\n            Random.Shared.Next(-20, 55),\n            summaries[Random.Shared.Next(summaries.Length)]\n        ))\n        .ToArray();\n    return forecast;\n})\n.WithName("GetWeatherForecast");\n//diff-remove-block-end\n//diff-add-block-start\napp.MapGet("/hello", async ([FromServices] IFeatureClient featureClient) =>\n{\n    if (await featureClient.GetBooleanValueAsync("welcome-message", false))\n    {\n        return "Hello, welcome to this OpenFeature-enabled website!";\n    }\n\n    return "Hello!";\n})\n.WithName("GetHello");\n//diff-add-block-end\n\napp.Run();\n\n//diff-remove-block-start\nrecord WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)\n{\n    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);\n}\n//diff-remove-block-end\n'})}),"\n",(0,a.jsx)(n.p,{children:"At this point, we are ready to run the initial version of our application."}),"\n",(0,a.jsx)(n.h3,{id:"step-4-run-the-initial-application",children:"Step 4: Run the initial application"}),"\n",(0,a.jsx)(n.p,{children:"Let's compile and run the application."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"dotnet build\ndotnet run\n"})}),"\n",(0,a.jsxs)(n.p,{children:["In the logs you should see a line with the following ",(0,a.jsx)(n.code,{children:"Now listening on: http://localhost:5251"}),", although the port number may differ.\nYou can visit the following URL in your browser ",(0,a.jsx)(n.a,{href:"http://localhost:5251/hello",children:"http://localhost:5251/hello"}),' (adjust port number as necessary) to view the hello world message.\nYou should see the message "Hello!".']}),"\n",(0,a.jsx)(n.p,{children:"\"Why I'm I seeing that value?\", you may ask.\nWell, it's because a provider hasn't been configured yet.\nWithout a provider to actually evaluate flags, OpenFeature will return the default value.\nIn the next step, you'll learn how to add a provider."}),"\n",(0,a.jsx)(n.h3,{id:"step-5-configure-a-provider-flagd",children:"Step 5: Configure a provider (flagd)"}),"\n",(0,a.jsx)(o.Ay,{}),"\n",(0,a.jsxs)(n.p,{children:["Before we can use the Flagd provider in .NET we need to install the ",(0,a.jsx)(n.a,{href:"https://www.nuget.org/packages/OpenFeature.Contrib.Providers.Flagd/",children:".NET OpenFeature Flagd"})," package."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"dotnet add package OpenFeature.Contrib.Providers.Flagd\n"})}),"\n",(0,a.jsx)(n.p,{children:"Finally, let's add the required code change to enable the flagd provider in our .NET application."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-csharp",children:'\nusing Microsoft.AspNetCore.Mvc;\nusing OpenFeature;\n//diff-add-block-start\nusing OpenFeature.DependencyInjection.Providers.Flagd;\n//diff-add-block-end\n//diff-remove-block-start\nusing OpenFeature.Providers.Memory;\nusing OpenFeature.Hosting.Providers.Memory;\n//diff-remove-block-end\n\nvar builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\n// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi\nbuilder.Services.AddOpenApi();\n\nvar app = builder.Build();\n\n// Register your feature flag provider\nbuilder.Services.AddOpenFeature(featureBuilder =>\n{\n    featureBuilder\n        .AddInMemoryProvider(_ => new Dictionary<string, Flag>()\n        {\n            {\n                "welcome-message", new Flag<bool>(\n                    new Dictionary<string, bool> { { "show", true }, { "hide", false } }, "show")\n            }\n        });\n//diff-add-block-start\n        .AddFlagdProvider();\n//diff-add-block-end\n});\n\n// Configure the HTTP request pipeline.\nif (app.Environment.IsDevelopment())\n{\n    app.MapOpenApi();\n}\n\napp.UseHttpsRedirection();\n\napp.MapGet("/hello", async ([FromServices] IFeatureClient featureClient) =>\n{\n    if (await featureClient.GetBooleanValueAsync("welcome-message", false))\n    {\n        return "Hello, welcome to this OpenFeature-enabled website!";\n    }\n\n    return "Hello!";\n})\n.WithName("GetHello");\n\napp.Run();\n'})}),"\n",(0,a.jsx)(n.h3,{id:"step-6-rerun-the-application",children:"Step 6: Rerun the application"}),"\n",(0,a.jsx)(n.p,{children:"We can use the .NET CLI to build and run our application."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"dotnet build\ndotnet run\n"})}),"\n",(0,a.jsxs)(n.p,{children:["You can visit the following URL in your browser ",(0,a.jsx)(n.a,{href:"http://localhost:5251/hello",children:"http://localhost:5251/hello"}
1),' (adjust port number as necessary) to view the hello world message.\nYou should see the message "Hello!".']}),"\n",(0,a.jsx)(l.Ay,{}),"\n",(0,a.jsxs)(n.p,{children:["Revisit the endpoint ",(0,a.jsx)(n.a,{href:"http://localhost:5251/hello",children:"http://localhost:5251/hello"})," and you will be greeted with ",(0,a.jsx)(n.code,{children:"Hello, welcome to this OpenFeature-enabled website!"})]}),"\n",(0,a.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,a.jsx)(n.p,{children:"This walk-through introduced you to the OpenFeature .NET SDK.\nIt covered how a provider can be configured to perform the flag evaluation and introduced basic feature\nflagging concepts.\nIt also showcased how feature flags can be updated at runtime, without requiring a code change and a redeployment."})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},28453(e,n,t){t.d(n,{R:()=>o,x:()=>l});var r=t(96540);const a={},i=r.createContext(a);function o(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.