I have an Azure Function App ver4 (net6) with HttpTrigger using OpenAPI and it raises exception 'The host has not yet started'.
Does the following error let me know to remove the character '/' that precedes my Route string value /blog/{blogId}/post/{postId}:
A host error has occurred during startup operation '2397a6d1-fa1c-4895-b062-f7e4faf57970'.
[2022-12-31T08:12:29.716Z] Microsoft.AspNetCore.Routing: An error occurred while creating the route with name 'GetBlogPost' and template 'api//blog/{blogId}/post/{postId}'. Microsoft.AspNetCore.Routing: The route template separator character '/' cannot appear consecutively. It must be separated by either a parameter or a literal value. (Parameter 'routeTemplate'). Microsoft.AspNetCore.Routing: The route template separator character '/' cannot appear consecutively. It must be separated by either a parameter or a literal value.
Yes / No ?
Thanks!
I tried to reproduce this scenario in my environment and was able to resolve the error:-
The route template separator character ‘/’ cannot appear consecutively. It must be separated by either a parameter or a literal value
Yes / No ?
Yes,
When I tried to remove the appending first “/” in my azure function Open API Http trigger route
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "blog/{blogId}/post/{postId}")] HttpRequest req)
My function app ran successfully like below :-
And when I tried to append the “/” before blog in the
route> I was able to get the same error code as yours while running the function app :-
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "/blog/{blogId}/post/{postId}")] HttpRequest req)
Error :-
Kindly, Remove the appending “/” while routing your api with the function app.
Reference :-
Azure Function app down due to wrong routing template in http
trigger binding of a functions - Stack
Overflow
c# - The route template separator character ‘/’ cannot appear
consecutively - Attribute routing issue - Stack
Overflow
I resolved this by removing the preceding / in the Route parameter value string. Therefore, this
/blog/{blogId}/post/{postId}
change to
blog/{blogId}/post/{postId}
Related
I have the following function in an Azure Functions application:
[FunctionName("MyFunction")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "x/{my-guid}/y")] HttpRequest httpRequest,
Guid myGuid,
ILogger logger
)
The problem is that I can't use the string "my-guid" as a parameter name because it contains a hyphen, and when I use "myGuid" instead I get a "cannot bind parameter" error message.
Is there a way to do this, perhaps by somehow explicitly stating the mapping from "my-guid" to "myGuid"?
I have tried using attributes such as [FromRoute(Name = "my-guid")] to decorate the myGuid parameter, but this didn't work.
So you have basically two issues:
Dashes in route
The first one is "mapping" my-guid to myGuid which I am unfortunately not being able to help with - I can not recall anything that could achieve that, besides "hiding" your functions behind some sort of API Gateway (like API Management).
Parameter binding
The second one though is your "cannot bind parameter" error, which I assume you would get even if the first issue would be resolved. Apparently functions are unable cast parameter to Guid type, change it to string and then convert to Guid inside the body of your function method:
[FunctionName("MyFunction")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "x/{myGuid}/y")]
HttpRequest httpRequest,
string myGuid,
ILogger logger
)
{
if (Guid.TryParse(myGuid, out var guid))
{
return new OkObjectResult(guid.ToString());
}
return new BadRequestResult();
}
Side note:
It's a bit painful with this additional logic, but I think it might be simplified with use of Azure Functions in isolated process rather than in-process and benefiting from middleware that handles that logic. It would make it a bit more future-proof as well:
Source of the image
I created an PublicController.cs that will returns list of agents. I then build and run the project and open Postman change the mode to get and call http://localhost:50159/api/public/Agents the message I get back is
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:50159/api/public/Agents'.",
"MessageDetail": "No action was found on the controller 'Public' that matches the request."
}
Is there something I am missing?
[HttpGet]
public IHttpActionResult Agents(string key, string diseaseId)
{
GuardKey(key);
var result = AgentsDataService.GetAgents();
return Json(result);
}
By default, WebApi 2 controllers' names are registered by convention i.e. PublicController gives us /api/Public during runtime.
you try to access api/public/Agents, however your controller may lie at api/Public.
You need to specify a Route in RouteConfig.cs or apply a Route as an attribute for a method.
There is a good Microsoft article that describes routes more precisely.
I have an OData controller with standard verbs for CRUD. Everything is working fine. Now I need to add a custom action to perform file upload. I try to add a method to my existing controller like this:
[HttpPost]
[Route("UploadFile")]
public async Task<HttpResponseMessage> UploadFile()
{
//handle uploaded content logic here...
}
But when I try to invoke it by doing a POST:
http://localhost/UploadFile
I get this error:
System.InvalidOperationException: No non-OData HTTP route registered.
What should I do for this custom action to allow file upload?
You need to declare the Action as part of the EdmModel, in the following example I am assuming that your Entity Type is Attachment, and your controller class name is AttachmentsController. By convention, your EntitySet name must then be Attachments
var attachments = builder.EntitySet<Attachment>("Attachments");
attachments.Action(nameof(AttachmentsController.UploadFile))
.Returns<System.Net.Http.HttpResponseMessage>();
The important part of the above statement is the return type, if you do not declare the return type correctly in your EdmModel then you will find your endpoints returning 406 errors - Unacceptable, even though your method executes correctly, which is really confusing the first time you run into it. This is because OData will still try to parse your response to match the Accept header from the request before completing the response.
Try to use 'nameof' when mapping functions and actions instead of 'magic strings' or constants so that the compiler can pickup basic issues like wrongly defined route.
With this approach you do not need the Route attribute on the method header and the action will be included in the metadata document and therefore swagger outputs.
My application is an ASP.NET Core 1.0 Web API.
[HttpGet("{someData:MinLength(5):MaxLength(5)}")]
[Produces("application/json")]
public async Task<IActionResult> GetSomeData(string someData)
{
return this.Ok(JsonConvert.SerializeObject("Data is: " + someData));
}
So when i pass a parameter with the length 6, the controller returns the Response Code 404 and the Response body no content because the parameter doesnt have the length 5.
This information is pretty useless for me, is there a way to return a more usefull error message?
I know i could just hardcode the error message in every controller like that:
[HttpGet("{someData}")]
[Produces("application/json")]
public async Task<IActionResult> GetSomeData(string someData)
{
if (someData.Length != 5)
{
return this.StatusCode(404, JsonConvert.SerializeObject("The data has to be 5 digits long."));
}
return this.Ok(JsonConvert.SerializeObject("Data is: " + someData));
}
The problem about this is, I have many controllers in my application and I dont want to validate the parameters everytime.
Is there a way the controller returns a more usefull Responsebody by itself? Or do I really have to add a validation method in each controller and forget about the [HttpGet] parameters and its error return?
Thank you very much
Route constraints are used to restrict which requested paths make it to a given action / route destination. They're not meant to perform model validation - that's done later and through a separate mechanism. If the request doesn't conform to your route constraints, it simply won't match that route. If it doesn't match any route, you'll get a 404.
As you noted in your own answer, this is covered in the routing docs: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing#route-template-reference
Alright I found an answer:
It's not possible to get better error messages.
Warning
Avoid using constraints for input validation, because doing so means
that invalid input will result in a 404 (Not Found) instead of a 400
with an appropriate error message. Route constraints should be used to
disambiguate between similar routes, not to validate the inputs for a
particular route.
found here
I just started using ASP.NET Web API 2.1 and have encountered a limitation. Using Attribute Routing, I can do the following:
[Route("item/{id:int}")]
public IHttpActionResult GetItem(int id)
{
...
}
The URL /item/5 will be routed to this action, but the URL /item/abc will not, because of the int constraint in {id:int}.
I tried changing my URL so that the id parameter was in the query string along with its constraint, despite the use of route constraints on query parameters never being mentioned or demonstrated in the documentation.
[Route("item?{id:int}")]
public IHttpActionResult GetItem(int id)
{
...
}
If I try to run now, I get an error on the Configure method call in Application_Start.
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
The message is as follows.
ArgumentException was unhandled by user code
The route template cannot start with a '/' or '~' character and it cannot contain a '?' character.
Two things bother me about this.
First, the section documenting Route Prefixes on MSDN makes clear that placing a ~ character at the start of the route template is completely acceptable. I tried it, and it works as documented.
Second, if not like this, how can I place a route constraint on a query parameter? Consider the following, with the route constraint removed.
[Route("item")]
public IHttpActionResult GetItem(int id)
{
...
}
The URL /item/5 will be routed to this action, with id set to 5 - but so will the URL /item/abc, with id set to 0.
Is there no way to place a route constraint on a query parameter?
According to http://attributerouting.net/#asp-net-web-api (†), this is not possible:
"Beware! Due to integration issues with the Web API WebHost framework, the following features will not work: …
querystring parameter constraints, …"
†) Note that this answer was written for a previous version of Web API where attribute routing was done using a separate AttributeRouting.WebApi NuGet package. Attribute routing has since been incorporated into the Web API core. Nevertheless, it appears that constraints on query string parameters are still not supported out of the box.