Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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>
share|improve this question
 
what FromBody does? you havent provided action parameter which is must in route config –  vishal sharma Nov 24 at 13:24
2  
try to remove "erp/" part from "localhost:52216/erp/api/customers"; –  ebram tharwat Nov 24 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. –  Andrus Nov 24 at 13:32
add comment

1 Answer

up vote 2 down vote accepted

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.

share|improve this answer
 
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? –  Andrus Nov 24 at 13:59
 
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. –  Darin Dimitrov Nov 24 at 14:10
 
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 ? –  Andrus Nov 24 at 14:14
 
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. –  Darin Dimitrov Nov 24 at 14:14
 
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 ? –  Andrus Nov 24 at 14:19
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.