Problems Creating a simple WebAPI Service

I've been following these instructions on creating my first WebAPI service:

https://codecloudy.wordpress.com/2014/03/19/asp-net-web-api-101-basics/

I'll post the code below.

According to the article it should not only allow the browser to display results with such urls as:

http://localhost:56315/api/values
and
http://localhost:56315/api/values/1

but it should also be possible to send POST messages via Fiddler:

Post from Fiddler
However I am always getting a 500 error when I do this and no breakpoints get hit:

500 Error
I've tried publishing to my local IIS but I get the same problems - the browser displays ok but posting fails with a 500 error.

What am I doing wrong:

Here is the ValuesController.cs:

using System.Collections.Generic;
using System.Web.Http;

namespace FirstWebAPIService.Controllers
{
    public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        public void Post([FromBody]string value)
        {
        }

        public void Post(object value)
        {
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
    }
}

Open in new window

purplesoupAsked:
Who is Participating?
 
käµfm³d 👽Connect With a Mentor Commented:
The reason is that your default route expects a default parameter named id, but you created an action with a name of value. Model binding in MVC does an excellent job of putting values that the user sends into the appropriate variable or object. The only catch is that you have to set up the initial mapping. That's where the matching names come in. As you noticed, when you modified the default route to expect a variable named value, your action worked when the parameter's name was value.

Now, you can modify your default route, but if you do you'll have to ensure that any other action that would map to the default route maps in the expected way--i.e. however you set up the route. You can also add additional routes, but this can get both unwieldy and can cause issues if you don't list your routes in the correct order. Routing will take the first matching route, and routes are searched in the order they are added to the route table. You might consider using attribute routing. It's a bit more flexible as well as bit easier to understand than the default MVC routing structure.
0
 
käµfm³d 👽Commented:
If you change line 21 to:

public void Post([FromBody]string id)

Open in new window


...does it work? If it does, then I'll explain why.
0
 
purplesoupAuthor Commented:
Yes it does - very interesting... tell me more!!
0
 
purplesoupAuthor Commented:
Interesting - if I change this:

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{value}",
                defaults: new { value = RouteParameter.Optional }
            );

Open in new window


and this:

        // POST api/values
        public void Post([FromBody]string value)
        {
        }

Open in new window


it works again - although I had to change both {value} and value = RouteParameter.Optional - so I guess that is what I needed.

Also I found that Get(int id) stopped working through the browser - it was just returning the default IEnumerable, unless I changed the parameter to

        public string Get(int value)
        {
            return "value";
        }

Open in new window

0
 
purplesoupAuthor Commented:
Thanks for your help - a great explanation too.
0
All Courses

From novice to tech pro — start learning today.