0
votes

I am writing an authentication provider in .Net as a REST service to make it easier to call from PHP and iOS. I've used the MVC Web API libraries and it all works fine, I can call methods from the browser etc.

BUT when I try and call my POST method from cURL using curl -d "something=something" hxxp://myendpoint/api the data passed in the message body with -d is not interpreted to match methods in my Web API class and I cannot see how to gain access to this form type fields.

I cannot change the curl call because it is coming from a 3rd-party library and seems to be correct but although I understand that Web API by design only matches uri parameters to actions, I don't understand why I can't access the form data from the Request object (or maybe I can?)

[HttpPost] public AccessToken Post() {} // Matches but can't access form data
[HttpPost] public AccessToken Post2(string something) {} // Doesn't match, no parameter in curl uri querystring
[HttpPost] public AccessToken Post3(ModelWithOnePropertyCalledSomething data) {} //Matches but can't access form data

Is this really something that is not possible with the Web API? Do I have to write custom action selector classes?

2
You have access to both the .NET code and PHP code? - Cameron Tinker
I can see the PHP code but it is not my code to change. I own the .Net code. - Lukos

2 Answers

0
votes

This is what I use for manipulating cURL in PHP:

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, "http://url/"); 
curl_setopt($ch, CURLOPT_USERAGENT, "Useragent"); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml; charset=UTF-8')); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_USERPWD, "username:password"); 
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_TIMEOUT, 10); 
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); 
curl_setopt($ch, CURLOPT_POSTFIELDS, "postdata"); 
$data = curl_exec($ch); 
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 

I understand that you might not be able to modify the PHP code, but if you have access to a server with PHP, you could try this code to see if anything returns from your ASP.NET MVC 3 authentication service. Then make the appropriate edits in your .NET code to make it play nice in PHP.

Here's some example ASP.NET MVC 3 code:

[HttpGet]
public ActionResult SomeAction(string someParam)
{
   return View();
}

You will need to edit your routing definitions in your Global.asax.cs code to accept querystring-less urls. For example you could setup a route like this:

routes.MapRoute(
            "API/SomeAction/SomeParam",
            "api/someaction/{someParam}",
            new { controller = "API", action = "SomeAction" }
            );

As far as processing post data from cURL, you'll need to see the content type that is being sent from cURL and handle the data appropriately.

0
votes

I've found what I needed, it is something like this:

[HttpPost]
    public AccessToken Post2()
    {
        var data = Request.Content.ReadAsFormDataAsync();
        data.Wait();
        var form = data.Result;

        return new AccessToken() { Value = "" };
    }

Basically, the request and apparently all of the web api framework is asynchronous which is fine but it requires a few more lines of code to make it work. I'm guessing I need to wait for data since ReadAsFormDataAsync might not have completed by the time I reach the next line of code. I also need to check for the posted type etc. to avoid exceptions where I don't want them.