ASP.NET Core multi attribute routing - asp.net-core

In my ASP.NET Core Web API application, I have declared a route with multiple attributes like following
[HttpGet]
[Route("{tenantId?}/user/getsettings/{id?}")]
When I made a request from swagger, the server is returning 404 not found.
http://localhost:5163/api/1/user/getsettings/2
Is this possible with .NET Core?

Because your url actually not contains api. You can call url by using http://localhost:5163/1/user/getsettings/2. If you want to add api to your url you can add attribute to controller class by using [Route("api/v{version:apiVersion}/[controller]")].
Tip: You can achive same config with only one HttpGet("{tenantId?}/user/getsettings/{id?}") attribute.

Related

Asp.Net Core Web Api hide controllers and actions by api-key authorization

I am converting an Asp.Net Web Api project to Asp.Net Core with .net6.
This project uses a custom Api-Key authentication and authorization method to give access to some of the controllers and actions.
In the old project, when opening the swagger documentation, the only controllers and actions displayed are the ones that do not require authentication.
Once the user inserts the api key and clicks on Explore button, the authorized controllers and actions shows up in documentation.
To do this, in the legacy project, I used IOperationFilter and IDocumentFilter to hide controllers and actions if not authorized.
This is working because when you click on Explore button after providing the api key, the page is refreshed and, at every refresh of the page, the IOperationFilter and IDocumentFilter are applied.
In Asp.Net Core, it seems that the IOperationFilter and IDocumentFilter are applied only at startup, and, in addition, the new Authorize button does not reload the page, and works only client side to provide authorization to the subsequent user interactions with the Try it out button present on every action.
Is it possibile to do something similar in Asp.Net Core, or should I drop that feature in the new version?
I found something may help you :
In asp.net core Swagger construct the UI page with a json file as below :
app.UseSwaggerUI(c=>
{                    
c.SwaggerEndpoint("/swagger/v1/swagger.json","SwaggerFilterv1"); 
});
This json file is constructed with the options you configured when you registed the service
Then I tried to copy the content of json file to the static file in the project ,deleted part of the path(you could also apply the filters and copy the json file directly ),and replaced the json file constructed by .net core
It worked as excepted : Some of the Api was missing
and you may inject your js file to control it(Add a request header you if auth succeeded and refresh the page and check request header with middleware):
app.UseSwaggerUI(c=>
{                    
......
c.InjectJavascript("")
});
I tried to branch the pipeline(I omitted the Authentication process just tried to check the query para):
app.UseWhen(x =>x.Request.Query.ContainsKey("Key"),
app =>app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/somejson.json", "SwaggerFilter v1");
}));
app.UseWhen(......)
The Result:

Any alternatives to aspnet-request:serverVariable when using NLog with .Net Core?

As stated on the NLog GitHub the ${aspnet-request:serverVariable=String} layout renderer is not supported in .Net Core.
The documentation doesn't provide alternatives to many of the variables available under serverVariable.
My question is, are there any alternatives? Like to access remote address, server name, port etc? Or do I just have to write a bunch of custom layout renderers documented here and dependency inject all the stuff by hand?
For ASP.NET Core there as many new layout renders. The reason is that the API of ASP.NET Core is very different and the server variables can't be read like in ASP.NET (so non-core)
There are currently 13 layout renders for ASP.NET Core that renders a part of the request.
${aspnet-request} - ASP.NET Request variable.
${aspnet-request-contenttype} - ASP.NET Content-Type header (Ex. application/json)
${aspnet-request-cookie} - ASP.NET Request cookie content.
${aspnet-request-form} - ASP.NET Request form content.
${aspnet-request-headers} - ASP.NET Header key/value pairs.
${aspnet-request-host} - ASP.NET Request host
${aspnet-request-ip} - Client IP.
${aspnet-request-method} - ASP.NET Request method (GET, POST etc).
${aspnet-request-posted-body} - ASP.NET posted body / payload
${aspnet-request-querystring} - ASP.NET Request querystring.
${aspnet-request-referrer} - ASP.NET Request referrer.
${aspnet-request-url} - ASP.NET Request URL.
${aspnet-request-useragent} - ASP.NET Request useragent.
See also https://nlog-project.org/config/?tab=layout-renderers&search=package:nlog.web.aspnetcore
If you need something else, you could indeed create a custom renderer. If you need the http request you could use:
AspNetLayoutRendererBase.Register("aspnet-request-myrenderer", (logevent, httpcontext, config) => ... );
You need to reference the NLog.Web.AspNetCore package for that.

WebApi Core 2.2 OData resource/path not found

I'm using WebApi Core 2.2. The Microsoft OData Client is adding a new parent record plus a subrecord (Deal+DealFee) from a WPF application. I'm hosting in IIS on Windows 10.
When I call container.SaveChanges(), it successfully calls the service to add the parent Deal record, but then it does a SECOND POST operation to this url (this is generated by the MS odata client lib):
POST http://localhost/mysite/odata/Deals(14)/DealFees
(note this includes the ID 14 which was just generated when adding the Deal)
This is two separate POSTs from the MS odata client lib, not a "deep insert" apparently. However, this results in a 404 (NotFound), which I can observe in Fiddler. The following urls DO work perfectly:
/odata/Deals
/odata/Deals(14)
/odata/DealFees
It seems like either the WebApi Core 2.2 service is not handling the POST to /Deals(14)/DealFees path, OR /Deals(14)/DealFees isn't a valid odata Uri? Is this kind of path generally supported in OData?
I don't know. Can anyone shed some light on what's going on?
Deep insert is not supported in WebAPI OData as of now. To me, it seems like the client is updating the resource set and the resource set for the navigation with two separate post requests and the reason you are getting a 404 is that there is no action mapped to the second request URI in the service.
The service can support this either by introducing a PostToDealFeesFromDeals controller action with default OData routing convention or use attribute routing to map the action for such requests.
If the action already exists then it might be that the first request did not finish creating the new record and the second request was fired, hence 404.

How to ignore ResponseWrapper in ASP.NET Core Web API response

I have an web api project in .net core and in Startup there is configured to use a response wrapper "
app.UseResponseWrapper();"
But this format is applied for all the api methods in my project...
I want an api method in my solution that sends another format response , for example a simple xml. I want to know how to ignore that Response wrapper that is applied for all methods? Is there any decorator for that method ?
I solved my issue.
I had built a custom decorator for methods that is able to modify header response.
In the Response wrapper I succeded to manage and to modify the response

ServiceStack not URL decoding route parameter in RESTful route

I'm using self hosted ServiceStack to provide an API to integrate with a ticketing system, and have defined the following routes:
Routes
.Add<TicketsWithStatus>("tickets/{Status}")
.Add<TicketStatusCounts>("tickets");
I'm having URL encoding problems with the first route when the status contains a space. If I browse to http://myservicebase/json/syncreply/TicketsWithStatus?Status=On%20Hold I get the response I'm expecting. However, if I use the RESTful route http://mysevicebase/tickets/On%20Hold I don't get any results.
Debugging my application, I can see that the On%20Hold is being URL decoded to On Hold in the case of the json/syncreply call, but is not decoded when using the RESTful route.
How can I ensure that the status property is properly decoded when calling my service via the RESTful route?
ServiceStack doesn't UrlDecode the PathInfo, it uses the same HttpRequest.PathInfo that the ASP.NET Request object returns. You might have better success if you change it to On+Hold.