1

In ASP.NEt MVC4 application Json Web api needs to be created to serve requests which can expressed using the urls like:

  1. http://localhost:52216/erp/api/customers return all customers

  2. http://localhost:52216/erp/api/customers?term=soft return list of customers whose same contains "soft". Used for autocomplete.

Result from those requests must be json object which contains single property , customers which contain array of customers found.

3. post request to http://localhost:52216/erp/api/customers should add new customer which is specified in request body as json

Result from this method must be json object which contains single property, customer which contain saved customer with some properties changed.

For this API controller below is tried to use. Typing browser http://localhost:52216/erp/api/customers returns error in xml format

<Error><Message>No HTTP resource was found that matches the request URI 'http://localhost:52216/erp/api/customers'.</Message>
<MessageDetail>No action was found on the controller 'Customers' that matches the request.</MessageDetail>
</Error>

How to fix this ? Which is propery way to crete API class for such request?

Request return data format cannot changed. Class method names can changed and separate methods with different names can created if required.

using Erp.Models;
using System.Web.Http;

namespace Erp.Controllers
{
    [Authorize]
    public class CustomersController : ApiController
    {
        public object Get(string term)
        { 
            Customer[] res = CustomerRepository.GetAllOrForTerm(term);
            return new { customers = res };
        }

        public object Post([FromBody]Customer customer)
        {
            Customer res = CustomerRepository.Save(customer);
            return new { customer = res };
        }
    }
}

default routing is used:

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

Update

Application is running from erp virtual directory so removing it does not help.

I tried also in browser

http://localhost:52216/erp/api/customers/get

and

http://localhost:52216/erp/api/customers/Get

but got error

<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:52216/erp/api/customers/get'.
</Message>
<MessageDetail>
No action was found on the controller 'Customers' that matches the request.
</MessageDetail>
</Error>
3
  • what FromBody does? you havent provided action parameter which is must in route config Commented Nov 24, 2013 at 13:24
  • 2
    try to remove "erp/" part from "localhost:52216/erp/api/customers" Commented Nov 24, 2013 at 13:25
  • @Vishal Sharma: FromBody should get customer from POST message body. I tried to add get action but problem persists. Application is running from erp virtual directory from VS2013 Express for web. If erp is removed 404.0 error from iis is returned. I updated question. Commented Nov 24, 2013 at 13:32

1 Answer 1

2

The following controller should work fine with the default routes configuration:

public class CustomersController : ApiController
{
    // This will match GET /api/customers
    public HttpResponseMessage Get()
    {
        Customer[] res = CustomerRepository.GetAllCustomers();
        return Request.CreateResponse(HttpStatusCode.OK, result);
    }

    // This will match GET /api/customers?term=foo_bar
    public HttpResponseMessage Get(string term)
    {
        Customer[] res = CustomerRepository.GetAllOrForTerm(term);
        return Request.CreateResponse(HttpStatusCode.OK, res);
    }

    // This should match POST /api/customers
    public HttpResponseMessage Post(Customer customer)
    {
        ...
        return Request.CreateResponse(HttpStatusCode.Created, customer);
    }
}

Also in your code you seem to have decorated your CustomersController with the [Authorize] attribute without actually explaining what kind of authorization mechanism you are using. But anyway, if you are using authorization, make sure you provide valid credentials with the request.

And while you are on it, checkout ServiceStack as an alternative to the Web API. You will be mesmerized by how much easier it is to write RESTful web services in .NET. In Web API v2 they did a step closer to ServiceStack by introducing attribute based routing (which simplified routing) but they have yet another step to make which is message based services. Then the Web API will really be useful. Until they make this final step, personally I will continue using ServiceStack which offers such a simplicity to write RESTfule services.

Sign up to request clarification or add additional context in comments.

8 Comments

thank you, it worked. Why you are using CreateResponse ? This requires additional dll to be referenced. VS2013 Web API template and all samples which I found simply return object like code in my question?
I am using CreateResponse as this, IMHO, is the correct way to return responses in a Web API. And no, it doesn't require any additional DLL to be referenced. The Request.CreateResponse method is part of the core. Controller actions should return HttpResponseMessage instances. It allows you to specify the correct status code and content type.
I'm using Forms authorization and browser passes proper cookies. This is first api added to existing mvc4 Mono application to move json returned methods out of controllorw which also return html views as responses. I cannot move to Web API v2 since application must run in Windows 2003 server and in Mono also. Is it reasonable to move to Servicestack ?
Yes, ServiceStack runs PERFECTLY fine on Mono. Personally I am using it in lots of projects in production. It incorporates faster JSON serializers than the Web API (which is relying on JSON.NET) and is so much more natural to do routing and write RESTful services. Maybe Microsoft will finally do it right in Web API v3, but until then, ServiceStack is the best.
After adding CreateRespons compile error Error 77 The type 'System.Net.Http.Formatting.MediaTypeFormatter' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' occurs. Is it OK to add it and will it work in Mono also ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.