Reputation: 68
I'm trying to add OAuth 2.0 to my .NET Core 3.0 Web Api using this tutorial. The following is the content of WebApiConfig class.
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute( // HERE IS THE ERROR
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// WebAPI when dealing with JSON & JavaScript!
// Setup json serialization to serialize classes to camel (std. Json format)
var formatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
formatter.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
// Adding JSON type web api formatting.
config.Formatters.Clear();
config.Formatters.Add(formatter);
}
I'm guessing it has to do with dependencies so here is csproj:
<ItemGroup>
<PackageReference Include="EntityFramework" Version="6.4.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.7" />
<PackageReference Include="Microsoft.AspNet.WebApi.Owin" Version="5.2.7" />
<PackageReference Include="Microsoft.AspNet.WebApi.WebHost" Version="5.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
<PackageReference Include="Microsoft.Owin.Cors" Version="4.1.0" />
<PackageReference Include="Microsoft.Owin.Security.OAuth" Version="4.1.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
I've seen a similar question with an answer suggesting to use app.UseMvc to map routes, but he was using a different .NET version(2.0). Also I tried using app.UseMvc but it doesn't do anything because I use EndpointRouting.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentity<AppUser, AppRole>(options =>
{
options.User.RequireUniqueEmail = true;
}).AddEntityFrameworkStores<AppDbContext>();
services.AddControllers();
//+adding database and service/repository
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
So I'm not really sure what to do. I tried closing Visual Studio and deleting every obj, bin and vs folder in the project (as weird as these sound, some people suggested it works) but with no succes.
Any suggestions please?
Upvotes: 1
Views: 5112
Reputation: 11
This was a tricky problem that I also experienced, but when I searched for resolutions to this error message nobody seemed to have an elegant solution ... so I found one myself.
There are several issues at play here:
As pointed out by the error message, the method MapHttpRoute is defined but can't be found
So, that solves the problem of implementing the MapHttpRoute method ... but this doesn't necessarily mean that your restful service call will work!
That's because the HttpDelete service that's being implemented here has calling parameters, which must be defined via the [Route] and [HttpDelete] attributes ... which leads us to step 2.
We need to explicitly declare the calling parameters via the [Route] and [HttpDelete] attributes
routeTemplate = "api/{controller}/{userID}/{userName}";
[Route("[controller]/{userID}/{userName}")]
[HttpDelete("{userID}/{userName}")]
public bool Delete(string userID, string userName) => this.DeleteUser(userID, userName);
[Route("[controller]")]
public bool DeleteUser(string userIDParam, string userNameParam)
{
int? userID = 0; string userName = "";
if (userIDParam != null) userID = Int16.Parse(userIDParam);
if (userNameParam != null) userName = userNameParam;
return DeleteSpecifiedUser(userID, userName);
}
Upvotes: 1