Problems passing parameters with $http.post to API Controller
Hi Guys,
I'm having problems getting $http.post to wortk with an UmbracoAPIController. Does this work differently to MVC? Here is my API Controller:
[PluginController("ImageGallery")]
public class ImageGalleryApiController : UmbracoApiController
{
[HttpGet]
public GalleryImage[] GetImages()
{
List<GalleryImage> Images = new List<GalleryImage>();
Images.Add(new GalleryImage() { ID = 0, Url = "localhost/image001.jpg", Caption = "First Image" });
Images.Add(new GalleryImage() { ID = 1, Url = "localhost/image002.jpg", Caption = "Second Image" });
return Images.ToArray();
}
[HttpPost]
public void SaveChanges(int GalleryID)
{
}
}
Javascript calling code:
$http.post("/umbraco/ImageGallery/ImageGalleryApi/SaveChanges", { GalleryID: 1 }).
then(function (response) {
// this callback will be called asynchronously
// when the response is available
}, function (response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
alert("failed");
});
When I call the SaveChanges method with the GalleryID parameter, I get a 404 failure from the client end. If I remove the parameter from both the Javascript code and the APIController, the method is called correctly, so the problem would seem to be with passing parameters. The same type of approach works just fine in asp.NET MVC, so does Umbraco do things differently or am I doing something wrong?
I've noticed that if I change the APIController SaveChanges method to:
public void SaveChanges(object GalleryID)
the parameter will be passed and is received but it isn't deserialised instead the object comes over as type Newtonsoft.Json.Linq.JObject. In MVC4, the objects are automatically mapped to the .Net equivalents, but it looks like for some reason this is not happening here.
I'm not sure why this is not working since exactly the same code works just fine in MVC 5? Am I missing something very obvious here or does Umbraco need to do things differently?
I've never been sure if this is an Umbraco issue or the WebAPI MVC stuff that Umbraco inherits from.
Basically it doesn't match to the method when you pass basic data types (string, int etc) - create a really simple model / class for the data (even if it only contains a single int) and pass that.
That's exactly what I did earlier this morning in order to fix it, it's the way I used to pass parameters via post. I wonder if Umbraco isn't using all of the features in later versions of MVC yet? I'm definitely getting the desired behaviour in those projects so I guess there's just something a little different going on under the covers.
From what I can tell it's basically wrapping my parameters into a JSON object and as you say because that object does not match the parameters it is never deserialised properly.
Oh well, it's no biggie, I was just interested in why it's not working in the same way as MVC.
But you shouldn't strive for builtin types anyway in my opinion. Having a DTO is good coding practice, and it makes everything a lot more readable when you start adding other parameters. ('Cause you will. Promise! ;) )
Thanks for explaining why Lars-Erik. This has been annoying me for a while!
Whilst I agree we should all strive for good coding practice if it's sending an Int and an Int is all that's needed why oh why must we use a DTO?
I dislike MVC "rules" of "purity" (even if Angular is to blame here). Simple is usually best?! That all said I respect others opinions here and am risking a code purity argument I'm likely to lose!. Thanks for explaining it :)
I'm using a custom route for this so it doesn't exactly adhere to the documentation. There isn't actually any problem calling the service, the issue is that the way in which parameters are interpreted differs slightly between Umbraco and the latest version of MVC.
Problems passing parameters with $http.post to API Controller
Hi Guys,
I'm having problems getting $http.post to wortk with an UmbracoAPIController. Does this work differently to MVC? Here is my API Controller:
Javascript calling code:
When I call the SaveChanges method with the GalleryID parameter, I get a 404 failure from the client end. If I remove the parameter from both the Javascript code and the APIController, the method is called correctly, so the problem would seem to be with passing parameters. The same type of approach works just fine in asp.NET MVC, so does Umbraco do things differently or am I doing something wrong?
I've noticed that if I change the APIController SaveChanges method to:
public void SaveChanges(object GalleryID)
the parameter will be passed and is received but it isn't deserialised instead the object comes over as type Newtonsoft.Json.Linq.JObject. In MVC4, the objects are automatically mapped to the .Net equivalents, but it looks like for some reason this is not happening here.
I'm not sure why this is not working since exactly the same code works just fine in MVC 5? Am I missing something very obvious here or does Umbraco need to do things differently?
Many thanks,
Damien
Hi Damien,
I've never been sure if this is an Umbraco issue or the WebAPI MVC stuff that Umbraco inherits from.
Basically it doesn't match to the method when you pass basic data types (string, int etc) - create a really simple model / class for the data (even if it only contains a single int) and pass that.
Similar issue here: https://our.umbraco.org/forum/umbraco-7/using-umbraco-7/70235-surfacecontroller-not-working-with-jquery-ajax-post#comment-226559
Hope that helps
Steve
Cheers Steve,
That's exactly what I did earlier this morning in order to fix it, it's the way I used to pass parameters via post. I wonder if Umbraco isn't using all of the features in later versions of MVC yet? I'm definitely getting the desired behaviour in those projects so I guess there's just something a little different going on under the covers.
From what I can tell it's basically wrapping my parameters into a JSON object and as you say because that object does not match the parameters it is never deserialised properly.
Oh well, it's no biggie, I was just interested in why it's not working in the same way as MVC.
Thanks for the reply.
Cheers,
Damien
This is an angular vs MVC "feature". It is possible to bake an url-encoded form post with angular, but you have to do some tricks. Here's a stack overflow post describing it:
http://stackoverflow.com/questions/11442632/how-can-i-post-data-as-form-data-instead-of-a-request-payload
But you shouldn't strive for builtin types anyway in my opinion. Having a DTO is good coding practice, and it makes everything a lot more readable when you start adding other parameters. ('Cause you will. Promise! ;) )
Thanks for explaining why Lars-Erik. This has been annoying me for a while!
Whilst I agree we should all strive for good coding practice if it's sending an Int and an Int is all that's needed why oh why must we use a DTO?
I dislike MVC "rules" of "purity" (even if Angular is to blame here). Simple is usually best?! That all said I respect others opinions here and am risking a code purity argument I'm likely to lose!. Thanks for explaining it :)
It isn't mvc purity,just purity. But I'll let it rest. 😊
Hi Damien,
I think the url you are posting to is not correct. I think your missing a "api" slug.
See the routing docs for more info : https://our.umbraco.org/documentation/Implementation/Routing/Routing/
Dave
Hi Dave,
I'm using a custom route for this so it doesn't exactly adhere to the documentation. There isn't actually any problem calling the service, the issue is that the way in which parameters are interpreted differs slightly between Umbraco and the latest version of MVC.
Thanks,
Damien
is working on a reply...