7

It seems ASP.NET implicitly interprets method named GetX and PostX as GET and POST methods respectively, because of their names are prefixed with HTTP method names. This is also the case for PUT and DELETE.

I have a method unfortunately named Delete but I want it to be interpreted as a POST, so I explicitly specify it's a POST using the [HttpPost] attribute. This works, as long as it's not declared inside an interface...

public interface IFooBarController
{
    [HttpPost]
    void DoSomething();

    [HttpPost]
    void Delete(int id);
}

public class FooBarController : IFooBarController
{
    public void DoSomething()
    {
       // This API method can only be called using POST,
       // as you would expect from the interface.
    }

    public void Delete(int id)
    {
        // This API method can only be called using DELETE,
        // even though the interface specifies [HttpPost].
    }
}

How can I work around this, without having to specify the HttpPostAttribute for each implementation?

Rudey
  • 4,717
  • 4
  • 42
  • 84
  • Will you be using Attribute routing with this web api? – Nkosi Mar 10 '16 at 12:20
  • 1
    It seems to me that http verbs are implementation details and don't belong in an interface. – Big Daddy Mar 10 '16 at 12:39
  • @BigDaddy, I would argue they are a part of the API method signature. – Rudey Mar 10 '16 at 12:55
  • @Nkosi, no, we currently have our routing configured to include the full C# method name in the route. – Rudey Mar 10 '16 at 12:58
  • 1
    I thought you might say that ;) The class is required to provide the implementation of interface methods. Why not convert the interface to an abstract class? – Big Daddy Mar 10 '16 at 13:05

4 Answers4

4

Attributes on interface properties doesn't get inherited to the class, you may make your interface to an Abstract Class.

Found an answer from Microsoft:

The product team does not want to implement this feature, for two main reasons:

  • Consistency with DataAnnotations.Validator
  • Consistency with validation behavior in ASP.Net MVC
  • tricky scenario: a class implements two interfaces that have the same property, but with conflicting attributes on them. Which attribute would take precedence?

SOURCES: Attribute on Interface members does not work

Community
  • 1
  • 1
raoon
  • 124
  • 4
  • I asked this on another question but I'll repeat it here. If attributes aren't inherited, how come an interface method `[HttpPost] DoSomething()` can only be called using POST, even though the implementation of said interface does not repeat the HttpPostAttribute? – Rudey Mar 11 '16 at 10:32
  • you have to bypass an abstract class. – raoon Mar 11 '16 at 10:40
  • wait i can t verify now ;) i ll do it when i m back to home :p – raoon Mar 11 '16 at 10:57
2

Like others have said, attributes are not inherited. DoSomething is not called using POST because of the attribute in your interface but because that is the default. Change it to GET in your interface and you will still notice POST calling it.

You can read more on how action selection is performed here in the section "Action Selection". (Item 3 answers your question regarding why DoSomething is called using POST)

CodingYoshi
  • 25,467
  • 4
  • 62
  • 64
1

Attributes aren't inherited from implemented interfaces, you'll have to declare the attribute on the concrete implementation (FooBarController). This overrides the convention-based binding.

Leon Cullens
  • 12,276
  • 10
  • 51
  • 85
  • 1
    If that's true, how come an interface method `[HttpPost] DoSomething()` can only be called using POST, even though the implementation of said interface does not repeat the HttpPostAttribute? – Rudey Mar 10 '16 at 12:24
-2

use [ActionName] attribue and name it as you want

Varun Vasishtha
  • 461
  • 2
  • 9