CS1022 : Type or namespace definition, or end-of-file expected for program.cs file in ASP.NET Core MVC project - asp.net-core-mvc

Creating an ASP.NET Core MVC application in VS2022.
The build throws the error shown here, for program.cs file. But I'm not seeing any red indication in the class file.
This is the code of program.cs:
using Fluent.Infrastructure.FluentModel;
using System.Net;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
//var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
And I'm getting this error message on 'RUN'
Can anyone help me resolve this issue? I've been struggling with this error for a long time.

Please follow below steps, I think you could fix the issue.
1. Move you code here like the picture below.
2. Delete .vs, bin, obj folder.
3. Expand the Denpendencies to check the warning.

Related

Configuration doesn't pick connection string from secrets.json file in ASP NET Core MVC 6.0 lts

I created ASP NET Core MVC 6 lts app with individual user accounts with Visual Studio 2022 preview 6.0. I moved connection string from appsettings.json to secrets.json. I start the app with IIS Express and apply migrations from exception page that opens. It works.
But when I try to apply additional migrations from Package Manager Console I get an error "connectionString can't be null".
Add services to the container. This is from Program.cs:
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
This is appsettings.json, connection string value removed:
"ConnectionStrings": {
"DefaultConnection": ""
},
This is Secrets.json:
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=DESKTOP-HIPPIDT;Initial Catalog=KehittajaLocalDb;Integrated Security=True;MultipleActiveResultSets=True"
}
}
In .NET 6,
You do not need to specify AddUserSecrets<>.
As mentioned here ,
WebApplication.CreateBuilder initializes a new instance of the
WebApplicationBuilder class with preconfigured defaults. The
initialized WebApplicationBuilder (builder) provides default
configuration and calls AddUserSecrets when the EnvironmentName is
Development
All you need to do is get the connection string from the builder.Configuration like below:
var dbConnectionString = builder.Configuration["ConnectionStrings:DevelopmentConnection"];
Then, you can specify the connection with AddDbContext<>:
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(dbConnectionString);
});
I added this to the Program.cs, now it works as expected. I don't know how come it worked when migrations were applied from exception page "Apply Migrations" button anyway.
// Add services to the container
if(builder.Enviroment.IsDevelopment())
{
builder.Configuration.AddUserSecrets<Program>();
}
..other code

Protecting webapi with IdentityServer and Autofac - can't get claims

I'm trying to protect my webapi with IdentityServer and OpenID Connect using Autofac. I'm using OWIN. But for some reason I can't get claims of the user. It seems that AccessTokenValidation is not triggered at all. That makes me think there is something wrong in the order of my declarations at my startup. Here is my startup.
public class Startup {
public void Configuration(IAppBuilder appBuilder) {
// Add authentication
this.AddAuthentication(appBuilder);
HttpConfiguration config = new HttpConfiguration();
var container = CreateAutofacContainer();
var resolver = new AutofacWebApiDependencyResolver(container);
config.DependencyResolver = resolver;
WebApiConfig.Register(config);
config.EnsureInitialized();
// Register config - you can't add anything to pipeline after this
appBuilder.UseAutofacMiddleware(container);
appBuilder.UseAutofacWebApi(config);
appBuilder.UseWebApi(config);
}
private static IContainer CreateAutofacContainer() {
var autofacBuilder = new ContainerBuilder();
var assembly = Assembly.GetExecutingAssembly();
// Register your Web API controllers.
autofacBuilder.RegisterApiControllers(assembly);
// For general logging implementation
autofacBuilder.RegisterType<ConsoleLogger>().As<ILogger>();
// Create empty usage context to be filled in OWIN pipeline
IUsageContext usageContext = new RuntimeUsageContext();
autofacBuilder.RegisterInstance(usageContext).As<IUsageContext>().SingleInstance();
// We need to get usage context builded
autofacBuilder.RegisterType<OIDCUsageContextProvider>().InstancePerRequest();
var container = autofacBuilder.Build();
return container;
}
private void AddAuthentication(IAppBuilder app) {
var options = new IdentityServerBearerTokenAuthenticationOptions();
options.Authority = "MYAUTHORITY";
options.RequiredScopes = new[] { "openid", "profile", "email", "api" };
options.ValidationMode = ValidationMode.ValidationEndpoint;
app.UseIdentityServerBearerTokenAuthentication(options);
// Add local claims if needed
app.UseClaimsTransformation(incoming => {
// either add claims to incoming, or create new principal
var appPrincipal = new ClaimsPrincipal(incoming);
// incoming.Identities.First().AddClaim(new Claim("appSpecific", "some_value"));
return Task.FromResult(appPrincipal);
});
}
I'm using hybrid flow and api is called from SPA-application. I've verified (by calling my identity server's endpoint directly) that access token is valid and there are claims available. I also downloaded IdentityServer.AccessTokenValidation project and attached it as a reference. When I set some breakpoints to methods in that project, they never get called. That is why I think there is something wrong with my startup and OWIN pipeline.
I've declared UsageContext in my startup. It is a class I'm using to collect claims and some configuration settings - to be injected to actual controllers. I think it would be nice way to handle this, so in controllers there is always valid UsageContext available.
I've read a lot of samples and examples but still haven't found exactly same situation. I'll appreciate any attempts to point me into right direction.
Regards,
Borre
Could it be your registration of UsageContext as a Singleton? You mention this class contains claims, so this object should be resolved once pr http request - shouldn't it?
It turned out that there was some mysterious line in AccessTokenValidation - library that didn't work. I use that library to get claims. After changing the line everything seemed to work.
So basically my question is closed now and stuff works. But I'm still not totally convinced this is the right way to do this.
Thanks John for your comments!

Can't get ASP.NET Web API 2 Help pages working when using Owin

I've installed the correct package for Web Api 2
Install-Package Microsoft.AspNet.WebApi.HelpPage -Pre
But the help area is not being mapped and is returning 404 (Web Api working fine). I'm using Microsoft.Owin.Host.SystemWeb as the host. Below is my Startup code.
public class Startup
{
public void Configuration(IAppBuilder app)
{
//Required for MVC areas new HttpConfiguration() doesn't work with MVC
var config = GlobalConfiguration.Configuration;
AreaRegistration.RegisterAllAreas();
WepApiStartup.Configure(config);
app.UseWebApi(config);
}
}
GlobalConfiguration.Configuration is web host specific HttpConfiguraiton, which should only be used with web host scenario. Use it with OWIN host will cause unexpected issues.
Please use the following code instead:
public class Startup
{
public static HttpConfiguration HttpConfiguration { get; private set; }
public void Configuration(IAppBuilder app)
{
HttpConfiguration = new HttpConfiguration();
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(HttpConfiguration);
app.UseWebApi(HttpConfiguration);
}
}
Replace all GlobalConfiguration.Configuration with Startup.HttpConfiguration in the project include help page files.
Found the solution after a lot of digging/trial and error. The issue is well described here: http://aspnetwebstack.codeplex.com/discussions/453068
UseWebApi and UseHttpMessageHandler don't call Next OWIN's middleware other than for 404. This means if you use UseWebApi that's it, Next is never called therefore you can't use it with any other middleware (Nancy or Web Api Help pages for example).
Thanks to #aliostad patch:
https://github.com/aliostad/CacheCow/blob/master/samples/UsingCacheCowWithNancyAndOwin/HttpMessageHandlerAdapterModified.cs#L43
You can get it working as expected. I hope the team merge the pull request for this as UseWebApi breaks the Owin design goals IMO.
Update 13 Feb 2014
I've written an Owin extension to workaround this:
internal static void UseWebApiAndHelp(this IAppBuilder app, HttpConfiguration config)
{
WepApiStartup.Configure(config);
app.UseHandlerAsync((request, response, next) =>
{
if (request.Path == "/") //app.Map using a regex exclude list would be better here so it doesn't fire for every request
{
response.StatusCode = 301;
response.SetHeader("Location", "/Help");
return Task.FromResult(0);
}
return next();
});
// Map the help path and force next to be invoked
app.Map("/help", appbuilder => appbuilder.UseHandlerAsync((request, response, next) => next()));
app.UseWebApi(config);
}
Update 01 July 2015
You can also host the help pages using WebApi instead of MVC, which is great for self host http://blogs.msdn.com/b/yaohuang1/archive/2012/12/20/making-asp-net-web-api-help-page-work-on-self-hosted-services.aspx
Update 10 September 2015
For Web Api I tried #hongye-sun answer and it works too, follow what #gspatel says by changing HelpPageAreaRegistration.RegisterArea and the HelpController's constructor. My workaround works as well so pick whatever one works best for your situation.
However I'm still getting the issue when using UseWebApi with other middleware and it not invoking Next() (seems to only happen when using IIS not self host). I've found my workaround of mapping the path and forcing next to be invoked is a valid workaround for all Owin middleware Nancy, Simple.Web etc.
Update 13 Jan 2016
I've developed Owin middleware to generate the ASP.NET Web API Help pages we know and love that completely solves this problem. My blog post explains the background to this issue in detail

SelfHosted AspNet WebAPI With Controller Classes In Different Project

I have created a SelfHosted AspNet WebAPI with Visual Studio 2012 (.NET Framework 4.5). I enabled SSL for the WebAPI. It works fine when the controller is defined in the same project.
But when I add a reference of another project, containing controllers, it gives me the following error:
No HTTP resource was found that matches the request URI 'https://xxx.xxx.xxx.xxx:xxxx/hellowebapi/tests/'.
I have created custom classes for HttpSelfHostConfiguration and MessageHandler.
Any help to resolve this problem would be a great time-savor for me.
Thanking in advance.
You can write a simple custom assemblies resolver which makes sure that your referenced assembly is loaded for the controller probing to work.
Following is a nice post from Filip regarding this:
http://www.strathweb.com/2012/06/using-controllers-from-an-external-assembly-in-asp-net-web-api/
Sample:
class Program
{
static HttpSelfHostServer CreateHost(string address)
{
// Create normal config
HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(address);
// Set our own assembly resolver where we add the assemblies we need
CustomAssembliesResolver assemblyResolver = new CustomAssembliesResolver();
config.Services.Replace(typeof(IAssembliesResolver), assemblyResolver);
// Add a route
config.Routes.MapHttpRoute(
name: "default",
routeTemplate: "api/{controller}/{id}",
defaults: new { controller = "Home", id = RouteParameter.Optional });
HttpSelfHostServer server = new HttpSelfHostServer(config);
server.OpenAsync().Wait();
Console.WriteLine("Listening on " + address);
return server;
}
static void Main(string[] args)
{
// Create and open our host
HttpSelfHostServer server = CreateHost("http://localhost:8080");
Console.WriteLine("Hit ENTER to exit...");
Console.ReadLine();
}
}
public class CustomAssembliesResolver : DefaultAssembliesResolver
{
public override ICollection<Assembly> GetAssemblies()
{
ICollection<Assembly> baseAssemblies = base.GetAssemblies();
List<Assembly> assemblies = new List<Assembly>(baseAssemblies);
var controllersAssembly = Assembly.LoadFrom(#"C:\libs\controllers\ControllersLibrary.dll");
baseAssemblies.Add(controllersAssembly);
return assemblies;
}
}

In Memory HTTP server Asp.net WebAPI

I am trying to understand how the self host configuration based Integration Tests are running.
In the code below, Should I be registering my config with the WebApiConfig. Registering or not seems to make no difference.
Is the full pipeline really being tested or is this an illusion? Since, If I am not using the config and the routes defined in my API instead declaring my own as I have done here, I am probably just not testing the full pipleine.
Is there any othere way of testing the api completely. The code below is testing a lot of things besides just my pipeline(like the client, SelfHosting etc..). This seems like an overkill to me. Any ideas ?
var config = new HttpSelfHostConfiguration("http://localhost:9090/");
config.Routes.MapHttpRoute("Default", "{api}/{controller}/{id}", new { id = RouteParameter.Optional });
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
MyApiProject.WebApiConfig.Register(config);
using (var server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
using (var client = new HttpClient())
{
using (var response = client.PostAsync("http://localhost:9090/api/login",
new FormUrlEncodedContent(new List<KeyValuePair<string,string>> { new KeyValuePair<string, strin("Foo","Bar)}), CancellationToken.None).Result)
{
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
using (var response = client.GetAsync("http://localhost:9090/api/login").Result)
{
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}
server.CloseAsync().Wait();
}
If you just want to test your controllers, you can write more targeted unit tests to test them. If you want to test the full pipeline your code looks fine except that instead of using a selfhost, you can just use HttpServer saving the network overhead. Also, if you are testing the full pipeline it is better to use the routes that you have in your actual app rather than adding a new route as that would be testing routing as well.
Also, refer to this blog post by Youssef for some ideas on testing your web APIs.

Resources