Using Steeltoe DiscoveryHttpMessageHandler with FlurlClient
I am looking to switch our HttpClients to use Flurl. However, our HttpClient is currently configured to use Service Discovery via Steeltoe. Basically it's doing this in ConfigureServices:
services.AddHttpClient<IMyClass, MyClass>().AddHttpMessageHandler<DiscoveryHttpMessageHandler>();
DiscoveryHttpMessageHandler is a custom http message handler in the Steeltoe library (https://github.com/SteeltoeOSS)
How do I access the IHttpClientBuilder with Flurl so I can add this same message hander? Or is there another clean way with Flurl to add a custom message handler for every HttpClient/FlurlClient created?
1 answer
-
answered 2021-03-09 14:22
Todd Menier
There's a few ways to add a custom message handler with Flurl (such as with a custom factory), but since you're already using
IHttpClientFactory
, I think the easiest path to get what you want (and the one I'd recommend) is to continue injectingHttpClient
into your services as you're doing and wrap them with Flurl inside the service:public class MyClass : IMyClass { private readonly IFlurlClient _flurlClient; public MyService(HttpClient httpClient) { _flurlClient = new FlurlClient(httpClient); } }
See also questions close to this topic
-
SqlDataReader can only check for one of (Null or non null value)
I am writing a program (for personal use) that stores card names into a database. I want to implement a way to see if a name already exists and if it does it will go in a "Do_have_in_db_listbox" else it will go in a "do_not_have_list_box". This is my original method for doing so:
while (retrieve.Read()) { if(retrieve["Card"] != DBNull.Value) { listBox_haveInDB.Items.Add(word_for_query); } else if (retrieve["Card"] == DBNull.Value) { listBox_notINDb.Items.Add(word_for_query); } }
I've tried this without the While loop, I've tried variations of if, else, else if and conditions. But for whatever reason the else statement NEVER executes no mater what the first condition is. I've been looking and trying to trouble shoot but the only thing that worked for me was an exception handler:
retrieve.Read(); try { if(retrieve["Card"] != DBNull.Value) { listBox_haveInDB.Items.Add(word_for_query); } } catch { listBox_notINDb.Items.Add(word_for_query); }
This is my way of getting around it. What am I doing wrong?
-
I want it to close when it opens the exe file separately
I have two exe files coded in C# and C++. What I want to do is to download and run the exe coded with C++ from C#. When the C++ application is not brought from the C# application, I do not want it to be launched directly from the downloaded folder. How can I do this?
-
How to filter DataGrid with SelectedItem from ItemsView using WPF?
Quick Summary
I have managed to code up this output so far
XAML
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <StackPanel Grid.Column="0"> <DataGrid ItemsSource="{Binding AddressView}"> </DataGrid> </StackPanel> <StackPanel Grid.Column="1"> <ListView ItemsSource="{Binding PersonView}"> <ListView.View> <GridView> <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}" /> <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Name}" /> </GridView> </ListView.View> </ListView> </StackPanel> </Grid>
PersonModel
public class PersonModel { public int Id { get; set; } public string Name { get; set; } public ObservableCollection<PersonModel> GetPersonModels() { ObservableCollection<PersonModel> people = new ObservableCollection<PersonModel>(); people.Add(new PersonModel { Id = 1, Name = "John" }); people.Add(new PersonModel { Id = 2, Name = "Max" }); people.Add(new PersonModel { Id = 3, Name = "Ed" }); return people; } }
AddressModel
public class AddressModel { public int Id { get; set; } public string Address { get; set; } public int PersonId { get; set; } public ObservableCollection<AddressModel> GetAddressModels() { ObservableCollection<AddressModel> addresses = new ObservableCollection<AddressModel>(); addresses.Add(new AddressModel { Id = 1, Address = "Address 1", PersonId = 1 }); addresses.Add(new AddressModel { Id = 2, Address = "Address 1", PersonId = 2 }); addresses.Add(new AddressModel { Id = 3, Address = "Address 2", PersonId = 3 }); return addresses; } }
ViewModel
public class ViewModel : BaseViewModel { // Initializer public ViewModel() { CopyOfPersonModel = new PersonModel(); CopyOfAddressModel = new AddressModel(); RefreshData(); } // Person Models properties private ObservableCollection<PersonModel> _personModels; public ObservableCollection<PersonModel> PersonModels { get { return _personModels; } set { _personModels = value; OnPropertyChanged(); } } public PersonModel CopyOfPersonModel { get; set; } // Person View - Used by the View private ICollectionView _personView; public ICollectionView PersonView { get { return _personView; } set { _personView = value; OnPropertyChanged(); } } // Address Models properties private ObservableCollection<AddressModel> _addressModels; public ObservableCollection<AddressModel> AddressModels { get { return _addressModels; } set { _addressModels = value; OnPropertyChanged(); } } public AddressModel CopyOfAddressModel { get; set; } // Address View - Used by the View private ICollectionView _addressView; public ICollectionView AddressView { get { return _addressView; } set { _addressView = value; OnPropertyChanged(); } } // Method to refresh the data public void RefreshData() { // Refresh the collections from the Model method PersonModels = CopyOfPersonModel.GetPersonModels(); AddressModels = CopyOfAddressModel.GetAddressModels(); // Refresh the views PersonView = CollectionViewSource.GetDefaultView(PersonModels); AddressView = CollectionViewSource.GetDefaultView(AddressModels); } }
Goal
My current goal is to filter the Address View on the left hand side of the MainWindow via the the ListView on the right hand side.
For example: Selected
Id
from the ListView is1
. Then filter the Address View in the DataGrid where PersonId =1
.What I have tried
I added a Filter method and a Search property:
// Filtering private bool Filter(AddressModel address) { return Search == address.PersonId; } private int search; public int Search { get { return search; } set { search = value; OnPropertyChanged(); AddressView.Refresh(); } }
and within my
RefreshData()
at the bottom I have added this line of code to enable filtering.// Filter AddressView.Filter = new Predicate<object>(o => Filter(o as AddressModel));
Problem
This fully works if I bind the
Search
property to a TextBox<TextBox Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}" />
And the DataGrid filters as intended.
But if I try to filter via selected item from ListView like so.. it does not work.
<ListView ItemsSource="{Binding PersonView}" SelectedItem="{Binding Search}" SelectedValue="{Binding Id}"> <ListView.View> <GridView> <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}" /> <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Name}" /> </GridView> </ListView.View> </ListView>
-
Problem with bootstrap carousel with razor
I need help for a boostrap/razor project in school. I'm totaly new with those technologies. I've listen to youtube videos for help. I learn how to add bootstrap's libraires with libman in visual studio and i also copied the code from a video that show how the bootstrap' carousel is done. It doesnt work as expected the 3 pictures in my images folder are show one under of each other and there are show all the 3 at the same time instead of one picture slide each 2 seconds.
@page @model IndexModel @{ ViewData["Title"] = "Home page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p> <div class="container"> <div class="row"> <div class="col-md-12"> <div id="imageCarousel" class="carousel slide" data-interval="2000" data="ride-carousel"> <div class="carousel-inner"> <div class="item-active"> <img src="~/images/page1.jpg" class="img-responsive" /> </div> <div class="item"> <img src="~/images/entraide-696x367.jpg" class="img-responsive" /> </div> <div class="item"> <img src="~/images/page0AI.jpg" class="img-responsive" /> </div> </div> </div> </div> </div> </div> </div>
-
Copy to output directory doesn't work for anything else than content in asp.net
I noticed that when I build using publish, the files I mark as "copy always" for "copy to output directory" and with the "build action" "embedded resources", don't get copied to the output directory when I publish, is there a reason why? It works when it's "build action: content" I am using Visual Studio 2015.
-
What are the file extension asp or aspx?
Hi I've seen some webpages have their filename extension .asp or .aspx. I already know what they stand for but how do I code it? Also is asp just HTML?
-
Possible to dynamically join a related model in Entity Framework Core?
Say there's a project that involves a lot of tables, all of which reference a single table that holds a field called
group ID
. However, not all of the tables reference this single table directly.For example, the db contains a
garages
table, and each garage is referenced by rows in acars
table, and each car is referenced by rows in atire
table. I want to organize the data into two groups,group1
andgroup2
. Each garage has agroup ID
, however the cars and tires do not.Is there a way to dynamically call an EF query that can get the
group ID
from the related garage, given EITHER a child car, tire, hub cap, and so on? -
EF Core exclude certain property in query, many-to-many relationship
How do I query certain properties only in a database that has many-to-many relationship?
So I have a book that can have multiple authors
public class Book { public Book() { Authors = new List<BookAuthor>(); } public string Id { get; set; } public string Description { get; set; } public List<BookAuthor> Authors { get; set; } }
Joined table for Book and Author
public class BookAuthor { public string BookId{ get; set; } public string AuthorId{ get; set; } public Book book{ get; set; } public Author author{ get; set; } }
Finally, the Author can write multiple books
public class Author { public string Id { get; set; } public string Name { get; set; } public List<BookAuthor> books { get; set; } }
Now, when I want to query a book and return the book id and description NOT the List of authors of that book
return await _context.Book.Select(x => new Book { Id = x.Id, Description = x.Description, }).ToListAsync();
When I do this I got
{ "id": "BOOK123", "description": "Stack Overflow 101", "Authors": [] }
I want to exclude the property Author from Book class in my query's return. How do I achieve this?
-
How to Style Blazor InputFile Component
I have a Blazor Web Assembly app on dotnet 5. I've added a Microsoft.AspNetCore.Components.Forms.InputFile control to a component. This causes a "Choose Files" button to be rendered.
How can I apply a style to the button?
I'd like the style to be the same as for a bootstrap btn-primary class.
Here's what I tried:
Copied the style from bootstrap.min.css and created a new style in app.css as follows:
input { color: #fff; background-color: #007bff; border-color: #007bff }
The html is:
<button class="btn btn-primary" @onclick="LoadSamples">Load Samples</button> <InputFile multiple OnChange="HandleFileSelected" />
The result was not what I'd hoped for:
-
With Flurl, what are the important concepts to understand about lifetime management?
HttpClient
from Microsoft has some documented best practices regarding lifetime management. In that you should not justnew
them up as you need them as this will have an adverse effect on socket consumption.They recommend using
IHttpClientFactory
to create anHttpClient
as you need them, and the factory will manage lifetimes for you. Or they recommend DI'ing anHttpClient
into your ctor. -
Stream HttpConnection.ChunkedEncodingReadStream as PDF to browser
How can a HttpConnection.ChunkedEncodingReadStream be stream directly to browser as PDF ?? PDF file can be as large as 200MB.
In snippet below, ChunkedEncodingReadStream is saved to temp file first, and then it will be returned to user in FileStreamResult.
FlurlRequest request = new (endpoint.Url); using var response = await request.SendAsync(HttpMethod.Get, null, default(CancellationToken), HttpCompletionOption.ResponseHeadersRead) .ConfigureAwait(false); // HttpConnection.ChunkedEncodingReadStream using Stream httpStream = await response.GetStreamAsync().ConfigureAwait(false); int bufferSize = 4096; // Save to temp file first, and serve that, // will use Flurl DownloadFile instead. var filePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); using FileStream fileStream = new (filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, useAsync: true); await httpStream.CopyToAsync(fileStream, bufferSize, new CancellationToken()).ConfigureAwait(false); // will use FileStreamResult to "stream" filePath return filePath;
-
Steeltoe Postgres connector on CloudFoundry .NET 5.0
I am using Steeltoe.CloudFoundry.Connector.EFCore with Npgsql.EntityFrameworkCore.PostgreSQL. I want to migrate the application to .NET 5.0. After updating Npgsql to 5.0.2 I am getting the error 'Unable to find DbContextOptionsBuilder, are you missing a PostgreSql EntityFramework Core assembly?' when adding DBContext.
I tried to look at the available versions of Steeltoe, but the highest NuGet I see is 2.5.2, which gives me this error as well as the older I had (2.4.4).
Is there any version combination of those libraries that works?
-
Steeltoe3.0 AddCloudFoundryConfiguration throws exception
I have upgraded my app to .net 5 and hence upgraded steeltoe also to 3.0, but when i run the app I get an exception as "could not load type 'steeltoe.extensions.configuration.cloudfoundry.service' from assembly 'steeltoe.extensions.configuration.cloudfoundry base", I am using Steeltoe.Extensions.Configuration.CloudFoundry, I am using serilog too so should I upgrade serilog even, from the past two days I am unable to find the solution for the same.
here is the code snippet
WebHost.CreateDefaultBuilder(args) .UseEnvironment($"{_environment}") .AddCloudFoundryConfiguration() .UseStartup<Startup>();