How To Pass formdata parameters into ASP.NET WebAPI without creating a record structure - asp.net-web-api

I have data coming into my form that looks like the image below (sessionsId: 1367,1368).
I've create c# in my webapi controller that works as below. when I've tried ot just make use SessionIds as the parameter (or sessionIds) by saying something like PostChargeForSessions(string SessionIds) either null gets passed in or I get a 404.
What is the proper way to catch a form parameter like in my request without declaring a structure.
(the code below works, but I'm not happy with it)
public class ChargeForSessionRec
{
public string SessionIds { get; set; }
}
[HttpPost]
[ActionName("ChargeForSessions")]
public HttpResponseMessage PostChargeForSessions(ChargeForSessionRec rec)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, new ShirtSizeReturn()
{
Success = true,
//Data = shirtSizeRecs
});
return response;
}

You can declare the action method like this.
public HttpResponseMessage Post(string[] sessionIds) { }
If you don't want to define a class, the above code is the way to go. Having said that, the above code will not work with the request body you have. It must be like this.
=1381&=1380

Related

Update data with Microsoft.AspNet.WebApi

Hey i am having a big trouble updating data in my client side REST application.
I made a Web API controller.
// PUT: api/Contacts/5
[ResponseType(typeof(void))]
public IHttpActionResult PutContact(Contact contact, int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != contact.ContactId)
{
return BadRequest();
}
_contactService.Update(contact);
return StatusCode(HttpStatusCode.NoContent);
}
And also client side service method:
public async Task<T> PutData<T>(T data, int dataId)
{
HttpResponseMessage resp = await this._client.PutAsJsonAsync(_serviceUrl + "/" + dataId, data);
resp.EnsureSuccessStatusCode();
return await resp.Content.ReadAsAsync<T>();
}
Service URL shows in debug mode that i goes to endpoint:
http://localhost:21855/api/Contacts/8
But it does not even go to breakpoint when i debug my server controller PutContact method.
What i am doint wrong? I need to update the data but i cant, because my client-side application won't even go to servers breakpoint on debug mode!!!
It gives me an error response 405 : Method not allowed
You can't have two different body parameters in the same method.
What you need to do is to set the id parameter to come from the URI and the Contact parameter from the body, like this:
public IHttpActionResult PutContact([FromBody]Contact contact, [FromUri]int id)
{
// method code
}
BTW, I suppose you have a GET method in your controller which looks like this:
public IHttpActionResult GetContact(int id)
{
// method code
return Contact; // pseudo-code
}
The error you getting comes from the fact that the system is not really calling your PUT method but the GET one (the system is ignoring the Contact parameter for the reason I expressed before): calling a GET method with a PUT verb results in a 405 Method Not Allowed exception.

Making a Web API method accept an xml

I am new to Web API so if this question sounds trivial or stupid please still give a solution.
I have a requirement where the consumer of my web api wants to post an xml.
I created an empty Web API controller and added a method like so:
public class StudentController : ApiController
{
[HttpPost]
public Student GetStudent(Student studentXml)
{
Student student = new Student() { Id = 502, Course = "Chemistry" };
return student;
}
}
The param is of type Student which is the class that has the same properties as the tags in the xml.
The XML that will be posted is like so:
<StudentStatus>
<AccountID>1231</AccountID>
<Password>2132132</Password>
<Batch/>
<Sequence/>
<Test>0</Test>
<Date>09/25/2014 09:18:24</Date>
<TestNumber>1972</TestNumber>
<StatusCode>3</StatusCode>
<ID>502</ID>
</StudentStatus>
The method is suppose to return an XML in response.
That's easy with the
Accept: application/xml
But how do I make the method accept an XML?
Any help is greatly appreciated.
Regards.
Try this in the controller code...Remove Get Prefix, no need to add [HttpPost]
Put a breakpint to see if it hits there.
public void PostStudent(string studentXml)
{
//Write your logic here
}
Try this in the code from where you are posting data
using (var client = new WebClient())
{
var data = "XML data" //Try HTML.Encode if it does not work
var result = client.UploadString("http://localhost:52996/api/Student", "POST", data);
//Do something with result
}

Execute a simple call to a WebAPI Get using RestRequest and a single string parameter

I have the following code in my receiving controller:
[Route("api/StudentUserId/{string}"), HttpGet]
public StudentDto StudentUserId(string userId)
{
StudentModel sm = new StudentModel(userId);
StudentDto dto = sm.ConvertToDto();
return dto;
}
After running this project, I have another project that I use to test the WebAPI controller calls. I use the following code to read a student record form the database using their userId:
protected T SendRequestToReadItemUsingString<T>(string resource, string userId) where T : new()
{
string resourceString = string.Format("{0}/{{userId}}", resource);
RestRequest request = new RestRequest(resourceString, Method.GET);
request.AddUrlSegment("userId", userId);
RestClient restClient = new RestClient(Service.Location);
var response = restClient.Execute<T>(request);
T retVal = response.Data;
return retVal;
}
Comparible code seems to work if I change the userId to an int Id in both the controller and calling code. I can't seem to get it to work with string. If I place a breakpoint in the controller code it never hits it and the calling code just returns a null.
Thanks for your help
Please note that WebApi works based on reflection this means that your curly braces {vars} must match the same name in your methods.
Therefore to match this api/StudentUserId/{string} your method needs to be declare like this:
[Route("api/StudentUserId/{userId}"), HttpGet]
public StudentDto StudentUserId(string userId)
return userId;
}
Where the parameter {string} was replaced by userId.
If you want to read more about this Routing Rules here is similar post on this;
WebApi Routing Configuration

How to pass multiple parameters via query string into a webapi controller

I am working on a legacy system that has been using .Net remoting for its communication.Now I want to write new client and server side web-api code to do the same thing.
Here's a sample code that I am dealing with :
public SearchResult Search(Condition condition,Sort sort,PageInfo pageInfo)
{
......
}
I would like to be able to have a web-api action with the same signature that gets its value form Uri , thus :
[HttpGet()]
public SearchResult Search([FromUri]Condition condition,[FromUri]Sort sort,[FromUri]PageInfo pageInfo)
{
......
}
Here are my questions :
Is it possible to have such an action in a web-api ?
If yes, How can I pass these parameters using HttpClient ?
You can setup your Route attribute to accept as many parameters as you like.
[Route("/api/search/{condition}/{sort}/{pageInfo}")]
[HttpGet]
public HttpResponseMessage Search( string condition, string sort, string pageInfo) {
...
}
This would mean that your url changes from
/Search?condition=test&sort=first&pageInfo=5
to
/Search/test/first/5
Alternatively, bundle the Condition, Sort and PageInfo objects into single Json class, and pass this object to your route:
[Route("/api/search/{SortParams}")]
[HttpGet]
public HttpResponseMessage Search( object sortParams) {
// deserialize sortParams into C# object structure
}
Have a look at this question : C# .net how to deserialize complex object of JSON

ASP.New Web API - Model Binding and Inheritance?

Is it possible for a Controller method to handle all Posted items which derive from a particular base class? The idea is to be able to dispatch Commands by posting them to an endpoint. When I try the following, the "cmd" parameter in the Post method is always null.
Example
//the model:
public abstract class Command{
public int CommandId{get; set;}
}
public class CommandA:Command{
public string StringParam{get; set;}
}
public class CommandB:Command{
public DateTime DateParam{get; set;}
}
//and in the controller:
public HttpResponseMessage Post([FromBody]Command cmd)
{
//cmd parameter is always null when I Post a CommandA or CommandB
//it works if I have separate Post methods for each Command type
if (ModelState.IsValid)
{
if (cmd is CommandA)
{
var cmdA = (CommandA)cmd;
// do whatever
}
if (cmd is CommandB)
{
var cmdB = (CommandB)cmd;
//do whatever
}
//placeholder return stuff
var response = Request.CreateResponse(HttpStatusCode.Created);
var relativePath = "/api/ToDo/" + cmd.TestId.ToString();
response.Headers.Location = new Uri(Request.RequestUri, relativePath);
return response;
}
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
Again, when I try this approach the Post method gets called, but the parameter is always null from the framework. However if I replace it with a Post method with a specific CommandA parameter type, it works.
Is what I'm attempting possible? Or does every message type need a separate handler method in the controller?
If you are sending data in Json format, then following blog gives more details about how hierarchies deserialization can be achieved in json.net:
http://dotnetbyexample.blogspot.com/2012/02/json-deserialization-with-jsonnet-class.html

Resources