I am pretty new to Umbraco and am using Umbraco 12. I have a surface controller that has a couple of Get endpoints which when sending requests to via Postman work, and a Post endpoint that I continually get a 400 Bad Request from.
The code below is a cut down version of the controller
[Controller]
public class EventsController : SurfaceController
{
private readonly IPublishedContentQuery _contentQuery;
public EventsController(
IUmbracoContextAccessor umbracoContextAccessor,
IUmbracoDatabaseFactory databaseFactory,
ServiceContext services, AppCaches appCaches,
IProfilingLogger profilingLogger,
IPublishedUrlProvider publishedUrlProvider,
IPublishedContentQuery contentQuery)
: base(umbracoContextAccessor,
databaseFactory,
services,
appCaches,
profilingLogger,
publishedUrlProvider)
{
_contentQuery = contentQuery;
}
[HttpGet]
public IActionResult GetPlacements(int year, string titleEvent)
{
// Redacted - Can hit when going to its url
https://localhost:44322/umbraco/surface/events/GetPlacements
}
[HttpPost]
public IActionResult PostPlacement(string teamName, string iso3, string finalPlacement, string titleEvent, string eventYear)
{
var rootContent = _contentQuery.ContentAtRoot().ToList();
var placementItems = rootContent.FirstOrDefault(x => x.Name == "Data")!.Children.FirstOrDefault(x => x.Name == "Event Placements");
// redacted - Cannot hit when going to its url
// https://localhost:44322/umbraco/surface/events/PostPlacement
return Ok();
}
}
I have looked around and see that I need to send it as either form-data or x-www-form-urlencoded
The problems as I see it
- I dont have a lot of experience with Umbraco so its possible I have missed something pretty obvious.
- I havent added a validator so not sure why I am getting a 400 bad request
- I have tried adding [FromForm] in the method to the parameters and still not working
- I have not yet tried binding it to a model
- I have tried adding a route but then I get a 404
- I have also seen this Umbraco surface controller not submitting to backend with POST and am trying this at the same time, but still no luck.
The need for this is that this endpoint will be send data from external systems and then I have a View that is being hit, that will then present the data (That bit does work).
Different points to consider
[Http, IgnoreAntiforgeryToken]
attributes and it should work (keep me posted).WHY
SurfaceControllers
are very special controllers deeply linked to Umbraco's behaviors. Therefore, they have special behaviors. A lot of things are done for you behind the scene. And in this case, by default,SurfaceControllers
are designed to work with an HTML FORM containg an Antiforgery Token.In Umbraco documentation (https://docs.umbraco.com/umbraco-cms/reference/routing/surface-controllers/) when you read :
You must anderstand : "Is used for interacting with A PAGE (CONTENT) THAT HAS BEEN GENERATED BY UMBRACO AND USE SOME UMBRACO'S FEATURES (not the backoffice)"
In that context, your controller has a
this.UmbracoContext.PublishedRequest
property containing theIPublishedContent
of the calling page.The documentation should contains
SurfaceControllers
are not designed to create API (Application 2 Application). They are designed for Page (content) 2SurfaceController
API.When you use a surface controller for A2A API, then
this.UmbracoContext.PublishedRequest
property isnull
(and many other things are not working).To create real A2A API (REST or not) :