我正在嘗試使用ASP.Net OData v4(例如ODataController)來允許訪問鍵是字符串的位置。 95%的示例使用整數作爲關鍵字,我發現的幾篇文章討論使用字符串作爲關鍵字的步驟對我來說並不合適。ASP.Net使用字符串鍵的OData
在任何情況下,我想用下面的URL來訪問我的資源:
/API/ContactTypes(「局」)
樂觀,我開始從只是改變了密鑰的類型int to key:
public SingleResult<ContactType> Get([FromODataUri] string key)
但是我得到了404響應。將URL更改爲一個整數,/ api/ContactTypes(1)會「工作」,因爲它將路由到正確的方法,並且該鍵是一個字符串類型,但很明顯,這對我沒有幫助。這是這篇文章中描述的場景:How to get ASP.Net Web API and OData to bind a string value as a key?,但該帖子意味着以我應該的方式訪問URL(也適用於OData v3)。
經過進一步搜索,我發現這篇文章:https://blogs.msdn.microsoft.com/davidhardin/2014/12/17/web-api-odata-v4-lessons-learned/這基本上是說你有一個顯式路由來裝點Get方法:
[ODataRoute("({key})")]
public SingleResult<ContactType> Get([FromODataUri] string key)
如果我這樣做,獨自一人,不過,我得到「的路徑模板'({key})'在控制器'GetType'中的操作'ContactTypes'不是有效的OData路徑模板。請求URL中遇到空白段。請確保指定了有效的請求URL。
在這個崗位(https://damienbod.com/2014/06/16/web-api-and-odata-v4-crud-and-actions-part-3/)的言論表明,我需要與ODataRoutePrefix裝飾控制器:
[ODataRoutePrefix("ContactTypes")]
public class ContactTypesController : ODataController
這似乎是違反直覺的,因爲我沒有什麼ASP.Net應該是混亂。我的控制器名稱已經遵循慣例,並且我沒有Web API控制器可能會混淆它。無論如何,它似乎「解決」了錯誤消失的問題,但是我回到了第一個問題(例如,只有整數值可以在URL中傳遞)。
我錯過了什麼?
全部控制器代碼:
[Authorize]
[ODataRoutePrefix("ContactTypes")]
public class ContactTypesController : ODataController
{
PolicyContext _Db;
public ContactTypesController(PolicyContext db)
{
if (db == null)
throw new ArgumentNullException("db");
this._Db = db;
}
public ContactTypesController() : this(new PolicyContext())
{
}
protected override void Dispose(bool disposing)
{
_Db.Dispose();
base.Dispose(disposing);
}
[EnableQuery]
[ODataRoute()]
public IQueryable<ContactType> Get(ODataQueryOptions options)
{
return _Db.ContactType;
}
[EnableQuery]
[ODataRoute("({key})")]
public SingleResult<ContactType> Get([FromODataUri] string key)
{
IQueryable<ContactType> result = _Db.ContactType.Where(p => p.ContactTypeKey == key);
return SingleResult.Create(result);
}
完全WebApiConfig:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
builder.EntitySet<ContactType>("ContactTypes");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "api",
model: builder.GetEdmModel()
);
}
是的,好吧,就這樣。我實際上有一個名爲ContactTypeId的屬性,還有一個名爲ContactTypeKey的屬性(在我們的數據庫中,它們都是唯一的)。出於性能原因,表格上的實際主鍵是ContactTypeId。我不得不將Key屬性添加到ContactTypeKey屬性中,以使OData識別應該用作其用途的關鍵點,但這會混淆實體框架,因此最終還要添加以下代碼以覆蓋其關鍵數據註釋用途:modelBuilder.Entity().HasKey(p => p.ContactTypeID) –