Configuration of options from IConfigurationRoot not working? - asp.net-core-1.0

The following code is snipped from the examples at docs.asp.net.
public void ConfigureServices(IServiceCollection services)
{
// Setup options with DI
services.AddOptions();
// Configure MyOptions using config
services.Configure<MyOptions>(Configuration);
// Configure MyOptions using code
services.Configure<MyOptions>(myOptions =>
{
myOptions.Option1 = "value1_from_action";
});
The call to services.Configure<MyOptions>(Configuration);
causes a compilation error:
cannot convert from 'Microsoft.Extensions.Configuration.IConfigurationRoot' to 'System.Action'
Manually setting up the options works fine. Am I missing something really obvious here?

I had the same problem and I found out you need to add this extension to your project :
Microsoft.Extensions.Options.ConfigurationExtensions

You need to add the following nuget package to your ASP Core Project if you want to configure the strongly typed config in that way.
Microsoft.Extensions.Options.ConfigurationExtensions
The extension methods contained in the package will allow you to configure the strongly typed configuration the way you want to and the way most tutorials show.
services.Configure<MyOptions>(Configuration);
Alternatively, you could add another binder package:
Microsoft.Extensions.Configuration.Binder
Configuration would then look something like this:
services.AddOptions();
services.Configure<MyOptions>(x => Configuration.Bind(x));
This is the downside of having so many modular packaged up extensions. It gets easy to lose track of where functionality exists.

Related

Blazor server app cannot download .msg files

I have a Blazor Server 6.0 app where I have links to download .msg files.
I have setup IIS to serve that mime-type trying both application/octet-stream and application/vnd.ms-outlook (and restarting IIS)
I have also tried to put in web.config the staticcontent tag like suggested here:
.msg file gives download error
And obviously in my program.cs I have app.UseStaticFiles();
I try to put the .msg in a non-blazor app and they work ok, so I think is not IIS related
So why I cannot download (or open automatically in outlook) this type of file, while other (docx, pdf, zip, etc.) are Ok ?
ASP.NET Core -- on the server side -- also needs to know about the files it has to serve. You can enable serving all unknown file types (I'd rather not include the relevant code as it is a major security risk), or you can add you own additional mappings like so:
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".msg"] = "application/vnd.ms-outlook";
// app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider
});
More info in the official docs: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-7.0#fileextensioncontenttypeprovider
Additionally, Blazor Server registers custom options for serving static files (like .server.js, which is different from just .js). It's not directly exposed as a public API to configure, but you can look at the source here as to what the AddServerSideBlazor extension method actually does. The solution there relies on you calling UseStaticFiles without explicitly specifying the options, so that it can retrieve the StaticFilesOptions instance from DI.
Armed with this knowledge, you can override an already configured options instance as follows:
builder.Services.PostConfigure<StaticFileOptions>(o =>
{
((FileExtensionContentTypeProvider)o.ContentTypeProvider).Mappings[".msg"] = "application/vnd.ms-outlook";
});
This configures the already initialized options instance registered in the DI (after all other configurations happened on it, thus PostConfigure).
Note that if you would for whatever reason decide to use a different IContentTypeProvider, the unsafe cast above would need to be revised as well.

How do I specify what would normally be in web.config for an Azure Function?

I'm creating an Azure Function, and I need to set this parameter what would normally go in the web.config file:
<entityFramework codeConfigurationType="xxxxxxxx">
But Azure Functions doesn't have a web.config. How do I configure stuff that isn't a simple key/value app setting?
The entity framework code is in a class library used by lots of other things, so I can't really use code based config without major hassle.
You can place it in your code. Microsoft documentation with all options is here: https://learn.microsoft.com/en-us/ef/ef6/fundamentals/configuring/code-based#moving-dbconfiguration
[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}
or
[DbConfigurationType("MyNamespace.MyDbConfiguration, MyAssembly")]
public class MyContextContext : DbContext
{
}

I wrote a Liferay module. How to make it configurable by administrators?

I have created a Liferay 7 module, and it works well.
Problem: In the Java source code I hard-coded something that administrators need to modify.
Question: What is the Liferay way to externalize settings? I don't mind if the server has to be restarted, but of course the ability to modify settings on a live running server (via Gogo Shell?) could be cool provided that these settings then survive server restarts.
More specifically, I have a module for which I would like to be able to configure an API key that looks like "3g9828hf928rf98" and another module for which I would like to configure a list of allowed structures that looks like "BASIC-WEB-CONTENT","EVENTS","INVENTORY".
Liferay is utilizing the standard OSGi configuration. It's quite a task documenting it here, but it's well laid out in the documentation.
In short:
#Meta.OCD(id = "com.foo.bar.MyAppConfiguration")
public interface MyAppConfiguration {
#Meta.AD(
deflt = "blue",
required = false
)
public String favoriteColor();
#Meta.AD(
deflt = "red|green|blue",
required = false
)
public String[] validLanguages();
#Meta.AD(required = false)
public int itemsPerPage();
}
OCD stands for ObjectClassDefinition. It ties this configuration class/object to the configurable object through the id/pid.
AD is for AttributeDefinition and provides some hints for the configuration interface, which is auto-generated with the help of this meta type.
And when you don't like the appearance of the autogenerated UI, you "only" have to add localization keys for the labels that you see on screen (standard Liferay translation).
You'll find a lot more details on OSGi configuration for example on enroute, though the examples I found are always a bit more complex than just going after the configuration.

Setting release configuration for SPA / webpack

I'm developing a Single Page Application and using Webpack for bundling up the modules.
One of my source files (I'm using TypeScript) has settings and configuration used in the application e.g.
// app-settings.ts
export class AppSettings {
public static ApiUrlPrefix: string = "//localhost/myapi/";
}
Which I then use in my code like:
//some-class.ts
import {AppSettings} from "./app-settings"
export class SomeClass {
contructor() {
var something = AppSettings.ApiUrlPrefix;
}
}
When release time comes, I'm going to want the settings to match the live environment.
What's a good way with either gulp, npm or webpack configs to update the settings file? I've seen the HtmlWebpackPlugin which can take a template and plug in some options, so I guess I'm looking for something similar.
You can also use the webpack.DefinePlugin. The Define plugin allows you to pass "Free Global" or "macro-like" variables into your project that you can use. To use webpack.DefinePlugin simply require() webpack into your project.
Here's the documentation and an example on how to use it.

How to use Restrict attribute in service stack

Is there any documentation on use of [Restrict] attribute with service stack?
Not finding any documentation, I started trying to figure this out. I discovered you have to enable restrictions in AppHost.cs Configure event with
var endpointHostConfig = new EndpointHostConfig
{
EnableAccessRestrictions = true,
};
Then I added attributes to my request DTO:
[Route("Hello/World", "GET")]
[Restrict(EndpointAttributes.InternalNetworkAccess)]
This does not work...looks like that removes all 'default' restrictions and replaces it with just that one restriction? Using this instead seems to work:
[Restrict(InternalOnly = true)]
When I do a GET from the local lan it works, but from remote it does not. Interesting, the 'detailed stack error' it gives from remote is:
The following restrictions were not met: '\n -[InternalNetworkAccess, Secure, HttpHead, HttpPost, HttpPut, HttpDelete,
HttpOther, OneWay, Soap11, Soap12, Xml, Jsv, ProtoBuf, Csv, Html, Yaml, MsgPack, FormatOther, AnyEndpoint]'
Note, it does not even list HttpGet as one of the possiblities - which does work. Also mentions Secure and not InSecure...neither of which I am specifically requiring.
Can we get some clarification on exactly how this is supposed to work? What if I wanted to require SSL - how would I specify that?
What if I wanted to require SSL in production, but not staging on all services for this endpoint? (Realizing this may be a completely different way to configure).
The [Restrict] attribute feature is in the latest version of ServiceStack. Currently the only documentation for this exists in the Security wiki page.
Here are some EndpointAttributes restrictions tests that test the validation of the restriction attributes, and some different service configurations you can use.
The way it works is that it's restricted to anything that's specified, so if you want to enable SSL and leave everything else as unrestricted, you would only add:
[Restrict(EndpointAttributes.Secure)]
public class SslOnly { }
It also supports specifying multiple combinations of environments that are allowed, e.g. You can enforce HTTP internally, but HTTPS externally with:
[Restrict(EndpointAttributes.Secure | EndpointAttributes.External,
EndpointAttributes.InSecure | EndpointAttributes.InternalNetworkAccess)]
public class SslExternalAndInsecureInternal { }
Note: each environment is combined with Enum flags and delimited with a ,.
But it doesn't let you distinguish between debug and release builds, to enable this you would need to use C# conditional compilation symbols.
E.g only allow HTTP for Debug builds and HTTPS for production Release builds:
#if DEBUG
[Restrict(EndpointAttributes.InSecure)]
#else
[Restrict(EndpointAttributes.Secure)]
#endif
public class MyRequestDto { ... }

Resources