Need example for web api post with multiple parameter - asp.net-web-api

In c#, Need example for web api post with multiple parameter ,Below i have attached my sample code.Please look into the InsertLeave method.In my code without CompanyId parameters working fine. When i add the companyid not able to invoke.
namespace AeS.SaaSAPI_2116
{
[RoutePrefix("{CompanyId}/{SecurityKey}")]
public class LeaveController : ApiController
{
[HttpPost]
[Route("{APIName}/x")]
public string InsertLeave(List<LeaveRequest> objList, string CompanyId)
{
foreach (LeaveRequest LR in objList)
{
}
return "Sucess ";
}
}
}
public class LeaveRequest
{
[Required]
public string EMP_STAFFID { get; set; }
[Required]
public string LEAVE_TYPE { get; set; }
}
}

I think you can use send your parameter to the server by request body, You will have to create a single class that wrapping your all parameters.You can use model binding to resolve this kind of issue

Related

Asp.net core 2.2 web api FromForm of complex object contains only null values

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
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);
}
}
[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).

How can I pass object param to get method in web api?

How can I pass object parameter to get method? I searched a lot ,
for example how to pass parameters to asp.net web api get method?
Here It is mentioned that we should use [FromUri] but I could not see [FromUri] in .NET Core 2
[HttpGet]
public IHttpActionResult GetDetails([FromUri] RetrieveDetails eDetails)
{}
following is the class
public class RetrieveDetails
{
public string Name{ get; set; }
public string Type { get; set; }
public List<MoreDetails> MoreDetails { get; set; }
}
public class MoreDetails {
public string DetailName{ get; set; }
}
But FromUri can not be used in .NET Core 2
Generally, we use POST method to pass an complex type.But you could also do it using [FromQuery] for GET method.
Action:
[HttpGet("Test")]
public async Task<IActionResult> GetDetails([FromQuery]RetrieveDetails eDetails)
Url:
.../Test?eDetails.Name=hello&eDetails.Type=world&eDetails.MoreDetails[0].DetailName=size&eDetails.MoreDetails[1].DetailName=price

Can I put a method inside class that is used as entity in Entity Framework?

I have POCO class that is used by Entity Framework. I'm using one field that is not mapped with database because I wanted it to be calculated when I access some data row.
Can I move data processing to some method in that class and expect that Entity Framework will work fine?
public class SomeClass
{
public int Id { get; set; }
public string Variable { get; set; }
[NotMapped]
public string VariableProcessed
{
get
{
return Variable.DoSomethingBlaBla();
}
set {}
}
}
I want to rewrite it like this:
public class SomeClass
{
public int Id { get; set; }
public string Variable { get; set; }
[NotMapped]
public string VariableInverted
{
get
{
return ProcessVariable(Variable);
}
set {}
}
private int ProcessVariable(string variable)
{
return variable.DoSomethingBlaBla();
}
}
Yes you can. But you don't need to pass a parameter to that function as long as it works on a variable in your POCO class

Is there something like [Bind(Exclude="Property")] for asp.net web api?

I'm trying to exclude a property from my Post Action in a web api controller, is there something like [Bind(Exclude="Property")] for asp.net web api?
This is my model:
public class ItemModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
I want to exclude the Id in the Post Action, because it is autogenerated, but I need to return it in my Get Action.
I Know I could have two models, one for my Post action and one for my Get action, but I'm trying to do this with just one model.
I would favour mapping models but this could be achieved by checking if the request is a POST in a ShouldSerialize method:
public class MyModel
{
public string MyProperty1 { get; set; }
public string MyProperty2 { get; set; }
public bool ShouldSerializeMyProperty2()
{
var request = HttpContext.Current.Request;
if (request.RequestType == "POST") return false;
return true;
}
}
Where your method name is the name of the property prefixed with ShouldSerialize.
Note this will work for JSON. For XML, you will need to add the following line to your config:
config.Formatters.XmlFormatter.UseXmlSerializer = true;
You can simply create a DTO for POST.

Json.Net JsonConvert not deserializing properly?

I'm using Json.Net to handle the deserialzing of the response of API calls from the Pipl.com API in my application, and it works fine but for some strange reason it won't deserialize a specific property of the JSON string that I feed to the JsonConvert.DeserializeObject method.
My class is this:
public class Source
{
public string Dsname { get; set; }
public bool IsSponsored { get; set; }
public string Url { get; set; }
public string Domain { get; set; }
public uint ExternalID { get; set; }
public Source()
{
}
}
and everything except the Dsname gets deserialized properly. The Json to be converted is like this:
"source": {
"#is_sponsored": false,
"#ds_name": "Personal Web Space -MySpace",
"url": "http://www.foo.bar"
"domain": "myspace.com"
}
Any idea how to go about this problem? Thank you in advance.
I added a wrapper class and specified the property name as attributes, like this:
public class Source
{
[JsonProperty(PropertyName = "#ds_name")]
public string Dsname { get; set; }
[JsonProperty(PropertyName = "#is_sponsored")]
public bool IsSponsored { get; set; }
public string Url { get; set; }
public string Domain { get; set; }
public uint ExternalID { get; set; }
}
public class RootObject
{
public Source source { get; set; }
}
Then I was able to deserialize fine:
var json = "{\"source\": { \"#is_sponsored\": true, \"#ds_name\": \"Personal Web Space -MySpace\", \"url\": \"http://www.foo.bar\", \"domain\": \"myspace.com\"}}";
var des = JsonConvert.DeserializeObject<RootObject>(json);
Note that I:
- wrapped your sample in a curly braces to make it valid JSON
- added a missing comma
- changed the value of "#is_sponsored" to not be the default value to verify it is desearialized correctly.
Ok I realize, this is a pretty old thread. But I ran into a similar issue earlier and came across this thread.
In my case the class I was trying to se/deserialize had a List<ClassName> public property in it. Which serialized fine, but wont deserialize. I switched it to ClassName[] and the fixed the deserialization problem.
Hope it helps someone else who comes across this thread, or at least gives them something else to look for.

Resources