2016-08-17 4 views
0

ASP.Net OData v4(例:ODataController)を使用して、キーが文字列の場合のアクセスを許可しようとしています。そこの例の95%は整数をキーとして使用しており、キーとして文字列を使用する手順について議論したいくつかの投稿が私のために働いていません。ASP.Net OData with string keys

すべての場合において、私は、次の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) 

が、しかし、私が手に「パス

はさらに、検索した後、私はこの記事を見つけましたコントローラ 'ContactTypes'のアクション 'Get'のテンプレート '({key})'が有効なODataパステンプレートではありません。リクエストURLで空のセグメントが見つかりました。有効なリクエストURLが指定されていることを確認してください。私はASP.Netが混乱するべきでは何も持っていないので、直感的と思われる

[ODataRoutePrefix("ContactTypes")] 
public class ContactTypesController : ODataController 

この記事のコメント(https://damienbod.com/2014/06/16/web-api-and-odata-v4-crud-and-actions-part-3/は)私がODataRoutePrefixとコントローラを飾るために必要があることを示唆しています。私のコントローラー名はすでに規約に従っており、私はそれを混乱させる可能性のある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:あなたのEdmModel

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() 
     ); 
    } 

答えて

1

1.If、文字列のプロパティが鍵であり、そして何ODataRouteには、例えば、必要ではありません:

public class Product 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public double Price { get; set; } 
} 

ConventionModelBuilderは "Id"という名前のプロパティをキーとして使用するか、それはのようなキーだY:

public class Product 
{ 
    [Key] 
    public string StringKey { get; set; } 
    public string Name { get; set; } 
    public double Price { get; set; } 
} 

その後localhost\api\Products('test')のようなコールはちょうど

public SingleResult<Product> GetProduct([FromODataUri]string key) 

2に行く必要があります。すでにintをキーとして使用していて、文字列を別のキーとして使用したい場合は、http://odata.github.io/WebApi/#04-17-Alternate-Keyのように呼び出すことができます。 localhost\api\Products(StringKey='test')

+0

ええ、そうでした。私は実際にContactTypeIdという名前のプロパティとContactTypeKeyというプロパティを持っていました(私たちのデータベースでは、どちらも一意です)。パフォーマンス上の理由から、表の実際の主キーはContactTypeIdです。 ContactTypeKeyプロパティにKey属性を追加して、その目的のキーとして使用する必要があることをODataに認識させる必要がありましたが、Entity Frameworkを混乱させるため、次のコードを追加してKeyデータアノテーションをオーバーライドしました目的:modelBuilder.Entity ().HasKey(p => p.ContactTypeID) –