Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

OData Versioned Controllers

Chris Martinez edited this pageDec 29, 2022 ·9 revisions

Creating an OData controller that supports API versioning isn't much different from creating a regular OData controller. The following controller depicts a service that support API version1.0 and2.0.

[ApiVersion(1.0)][ApiVersion(2.0)]publicclassPeopleController:ODataController{// GET ~/people?api-version=[1.0|2.0]publicasyncTask<IActionResult>Get()=>Ok(new[]{newPerson()});// GET ~/people/1?api-version=[1.0|2.0]publicasyncTask<IActionResult>Get(intkey)=>Ok(newPerson());// PATCH ~/people/1?api-version=2.0[MapToApiVersion(2.0)]publicasyncTask<IActionResult>Patch(intkey,Delta<Person>delta){if(!ModelState.IsValid){returnBadRequest(ModelState);}varperson=newPerson();delta.Patch(person);returnUpdated(person);}}

ThePATCH method is only supported in API version2.0 of the service. To be truly OData compliant, this service should define an action mapped to API version1.0 that always returns HTTP status code501 (Not Implemented) instead of falling back to HTTP status code400 (Bad Request) or404 (Not Found).

If you reviewed thePerson model and configuration example for theIModelConfiguration, you'll know what we configured a singlePerson object with different properties available in different API versions. The default OData model validation does some automatic heavy lifting for us using the defined EDM model. In addition to the other normal validation you might have fromData Annotations, the current EDM model will provide further validation. For example, even though thePerson object has aPhone property, it was not defined until API version3.0. If you try to send aPATCH request like this:

PATCH /people/1?api-version=2.0 HTTP/2Content-Type: application/jsonContent-Length: 27{"Phone":"555-555-5555" }

the built-in OData model validation will fail. The response will end up being HTTP status code400 (Bad Request) with an error message that indicates thePhone property does not exist. In version2.0 of the service, that is true and the correct behavior.

Splitting Versions Across Multiple OData Controllers

Service authors can choose to split service API versions across multiple controller types. In fact, for all but the simplest of version variations, this is the recommended approach. You may, however, notice something extra and a little unusual about the attribution for this controller.

Under the hood, the OData implementation still uses convention-based routing. When we split services across multiple controller types, the new service implementation cannot have the same name. The only exception to this rule is if you create version-specific namespaces for each version of the service. If the name of the controller cannot be the same as the original controller type and we're stuck with convention-based routing, how to do indicate what the name of the controller should be? Enter theControllerNameAttribute.

TheControllerNameAttribute allows you to specify an arbitrary name for a controller. In the strictest sense, this is not convention-based; however, short of using different namespaces, there isn't a way to define the correct name of the controller. Without theControllerNameAttribute, this controller would be namedPeople2, which won't match any routes. In OData, the controller route is paired with the corresponding entity set name. The API version services honor this attribute and will use the controller name defined by the attribute over the default convention name when present.

[ApiVersion(3.0)][ControllerName("People")]publicclassPeople2Controller:ODataController{// GET ~/people?api-version=3.0publicIActionResultGet()=>Ok(new[]{newPerson()});// GET ~/people/1?api-version=3.0publicIActionResultGet(intkey)=>Ok(newPerson());// PATCH ~/people/1?api-version=3.0publicIActionResultPatch(intkey,Delta<Person>delta){if(!ModelState.IsValid){returnBadRequest(ModelState);}varperson=newPerson();delta.Patch(person);returnUpdated(person);}}
Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp