Reputation: 731
Hi I am trying to build an endpoint for slack commands in asp.net core 2.2. I have a data structure representing a commandrequest from slack like so:
public class SlackCommandDTO
{
[FromForm(Name = "token")]
public string Token { get; set; }
[FromForm(Name = "team_id")]
public string TeamId { get; set; }
[FromForm(Name = "team_domain")]
public string TeamDomain { get; set; }
[FromForm(Name = "channel_id")]
public string ChannelId { get; set; }
[FromForm(Name = "channel_name")]
public string ChannelName { get; set; }
[FromForm(Name = "user_id")]
public string UserId { get; set; }
[FromForm(Name = "user_name")]
public string UserName { get; set; }
[FromForm(Name = "command")]
public string Command { get; set; }
[FromForm(Name = "text")]
public string Text { get; set; }
[FromForm(Name = "response_url")]
public string ResponseUrl { get; set; }
[FromForm(Name = "trigger_id")]
public string TriggerId { get; set; }
}
My controller to receive data looks like this:
[Route("api/[controller]")]
[ApiController]
public class CustomerServiceController : ControllerBase
{
// POST api/customerservice
[HttpPost]
public void Post([FromForm] SlackCommandDTO command)
{
Console.Write(command.Token);
}
}
my startup.cs looks like this
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}
I have tried setting the compatability settings in startup.cs to 2.1 and 2.2.
The result is always an instance of the object that contain null in all properties.
I have tried setting the decorator to [FromBody] (not that that is supposed to work) but in that case I get 415 unsupported media type (as it should).
I have tried sending the requests with content-type x-www-form-urlencoded and form-data as well as text/plain and application/json. the latter two return 415.
I have also tried sending the request through swagger with the same result and curl both using -d keyword and -F keyword for each pair of data.
If I am missing some information please let me know, I am drawing a blank here on how to solve it so please help.
The data I am receiving is from Slack according to this article about implementing slash commands in slack. https://api.slack.com/slash-commands#responding_to_commands
Upvotes: 1
Views: 5741
Reputation: 731
I have solved my problem. My issue was the fundamental misunderstanding that the parameters would be bound as a single object when using the FromForm attribute when actually I was supposed to parameterize each field as a string input in the post method like so:
[Route("api/[controller]")]
[ApiController]
public class CustomerServiceController : ControllerBase
{
// POST api/customerservice
[HttpPost]
public void Post([FromForm] string token,
[FromForm] string team_id,
[FromForm] string team_domain,
[FromForm] string channel_id,
[FromForm] string channel_name,
[FromForm] string user_id,
[FromForm] string user_name,
[FromForm] string command,
[FromForm] string text,
[FromForm] string response_url,
[FromForm] string trigger_id)
{
Console.Write(token);
}
}
Upvotes: 1
Reputation: 239430
[FromForm]
is not for annotating properties on your model. It's for indicating how an action param will be bound. If you were accepting JSON, you could achieve this via [JsonProperty]
, but there's no way to change the property names for binding from form. They need to match, i.e. you'll either need to change your properties to stuff like Team_Id
(with the underscore) or change your field names to stuff like teamId
(without the underscore).
Upvotes: 0