سؤال

I am just starting to use web API2 controllers and and have some difficulty. I am using attribute routing as well

UPDATED: My Controller is set up as follows;

Namespace TraderProductData
<RoutePrefix("api/symbols")>
Public Class SymbolsController
    Inherits ApiController

    Private db As New SymbolsEntities
    'GET api/Symbols
    <HttpGet> _
    Function Getsymbols() As IQueryable(Of symbol)
        Return db.symbols
    End Function
    'GET api/Symbols/20  ....20 is for equities, so get equity symbols
    <HttpGet> _
    <Route("{symbolType}", Name:="getsymbolsfortype")> _
    Function GetSymbolsForType(ByVal symbolType As Integer) As IQueryable(Of symbol)
        Dim symbols As IQueryable(Of symbol) = From d In db.symbols
                                               Where d.SymbolType = symbolType
                                               Select d

        Return symbols
    End Function
    'GET api/symbols/SymbolExistsId/1922
    <HttpGet> _
    <Route("SymbolExistsId/{id}", Name:="symbolexistsid")> _
    Function SymbolExistsId(ByVal id As Integer) As Boolean
        Return db.symbols.Count(Function(e) e.Id = id) > 0
    End Function
    'GET api/symbols/SymbolExists/AAPL
    <HttpGet> _
    <Route("SymbolExists/{symbol}", Name:="symbolexistssymbol")> _
    Function SymbolExists(ByVal symbol As String) As Boolean
        Return db.symbols.Count(Function(e) e.Symbol1 = symbol) > 0
    End Function
    'GET api/symbols/GetNameIfSymbolExists/AAPL
    <HttpGet> _
    <Route("GetNameIfSymbolExists/{symbol}", Name:="getnameifsymbolexists")> _
    Function GetNameIfSymbolExists(ByVal symbol As String) As String
        Dim symbolName As String = (From d In db.symbols
                                    Where d.Symbol1 = symbol
                                    Select d.Name).FirstOrDefault()
        Return symbolName
    End Function
    'GET api/symbols/GetNameIfSymbolIdExists/1922
    <HttpGet> _
    <Route("GetNameIfSymbolIdExists/{id}", Name:="getnameifsymbolidexists")> _
    Function GetNameIfSymbolIdExists(ByVal id As Integer) As String
        Dim symbolName As String = (From d In db.symbols
                                    Where d.Id = id
                                    Select d.Name).FirstOrDefault()
        Return symbolName
    End Function
    'GET api/symbols/GetSymbolIdIfSymbolExists/AAPL
    <HttpGet> _
    <Route("GetSymbolIdIfSymbolExists/{symbol}", Name:="getsymbolidifsymbolexists")> _
    Function GetSymbolIdIfSymbolExists(ByVal symbol As String) As Integer
        Dim symbolId As Integer = (From d In db.symbols Where d.Symbol1 = symbol Select d.Id).FirstOrDefault()
        Return symbolId
    End Function

    <HttpGet> _
    <Route("GetSymbolById/{id}", Name:="getsymbolbyid")> _
    <ResponseType(GetType(symbol))> _
    Async Function GetSymbolById(ByVal id As Integer) As Task(Of IHttpActionResult)
        Dim symbol As symbol = Await db.symbols.FindAsync(id)
        If IsNothing(symbol) Then
            Return NotFound()
        End If

        Return Ok(symbol)
    End Function

    ' POST api/Symbols
    <HttpPost> _
    <Route("{symbol}", Name:="postsymbol")> _
    <ResponseType(GetType(symbol))> _
    Async Function Postsymbol(ByVal symbol As symbol) As Task(Of IHttpActionResult)
        If Not ModelState.IsValid Then
            Return BadRequest(ModelState)
        End If

        db.symbols.Add(symbol)
        Await db.SaveChangesAsync()

        Return CreatedAtRoute("DefaultApi", New With {.id = symbol.Id}, symbol)
    End Function



    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If (disposing) Then
            db.Dispose()
        End If
        MyBase.Dispose(disposing)
    End Sub
End Class
End Namespace

The above now works as expected

هل كانت مفيدة؟

المحلول

You actually want to add <HttpGet> to the SymbolExists method as well as adding to the GetSymbols method.

The reason is that your GetSymbols() works because your <RoutePrefix> and the controller name matches the global route. You shouldn't rely on that, as it's fragile and will break you unexpectedly.

The rule of thumb here: If you have many of your actions AttributeRouted make all of them so. It's probably ok to use AttributeRoute to replace the URL for one or two actions on your controller.

نصائح أخرى

You don't need the other routes. Your function name is the child route. You need to replace it with HttpGet or HttpPost or HttpPut etc..

Try:

<HttpGet>
Function SymbolExists(ByVal symbol As String) As Boolean
    Return db.symbols.Count(Function(e) e.Symbol1 = symbol) > 0
End Function
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top