Core problem: GET works, POST doesn't. I'm new to WebAPI so I'm probably doing something stupid, but I've poked around quite a bit on the 'net trying to figure out why this isn't working.
Fairly simple WebAPI C# app. I've tried to get this down to very simple routes:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Add a route where action is supplied, i.e. api/csv/LoadToSQL
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}"
);
Controller class:
public class CsvController : ApiController
{
// GET api/csv
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/csv/name
public string Get(string csvName)
{
return "value";
}
// POST - api/csv/LoadToSQL
// Load a CSV to SQL
[HttpPost]
[ActionName("LoadToSQL")]
public HttpResponseMessage LoadToSQL(
string storageAccount,
string accessKey,
string containerName,
string csvFileName,
string connectionString,
string targetDatabaseName,
string targetTableName)
{
try
{
// Retrieve storage account from connection string.
CloudStorageAccount blobStorage = CloudStorageAccount.Parse(storageAccount);
Start it up locally and connect Fiddler. Try a GET; works:
Try a POST - fails:
My original implementation had just
// POST - api/csv
// Load a CSV to SQL
public HttpResponseMessage Post(
but that didn't work so I started trying to add specific routes and verb decorations.
It just doesn't seem to see the POST action against this controller no matter what I do.
Any thoughts?
UPDATE - per answer below, the correct route to make this work is:
// Add a route where action is supplied, i.e. api/csv/LoadToSQL
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{storageAccount}/{accessKey}/{containerName}/{csvFileName}/{connectionString}/{targetDatabaseName}/{targetTableName}"
);
This shows all the parameters to the POST request.
You can replace your method to be more clear and clean if you like so
1- declare a class with your options
public class LoadToSqlData
{
public string storageAccount {get; set;}
public string accessKey {get; set;}
public string containerName {get; set;}
public string csvFileName {get; set;}
public string connectionString {get; set;}
public string targetDatabaseName {get; set;}
public string targetTableName {get; set;}
}
2- Declare your method to be :
[HttpPost]
[ActionName("ActionApi")]
[Route("api/Csv/LoadToSQL")]
public HttpResponseMessage LoadToSQL([FromBody]LoadToSqlData data)
Notice the usage of the [Route],[ActionName]
and the [FromBody]
attributes.
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With