2016-04-07 9 views
0

Ich habe Probleme beim Wechseln meiner OData-Methode, um eine Zeichenfolge als Schlüssel anstelle einer Ganzzahl als Schlüssel zu verwenden. Es scheint sich wie eine ganze Zahl zu verhalten, egal was ??Ändern Sie den OData-Methodenschlüssel von Integer in String

Die alte Methode (man beachte die integer):

[EnableQuery] 
public SingleResult<Order> Get([FromODataUri] int key) 
{ 
    IQueryable<Order> result = db.Orders.Where(o => o.OrderId == key); 
    return SingleResult.Create(result); 
} 

Die alte URL (arbeitete gut):

api/orders(250)/ 

Die neue Methode (die Zeichenfolge bemerken):

[EnableQuery] 
public SingleResult<Order> Get([FromODataUri] string key) 
{ 
    IQueryable<Order> result = db.Orders.Where(o => o.MyCustomId == key); 
    return SingleResult.Create(result); 
} 

Die neue URL sollte letztlich wie sein:

api/orders('13-Abc.56.77.Blah.Blah')/ 

Meine Web-API-Routing sieht wie folgt aus:

public static void Register(HttpConfiguration config) 
{ 
    // Web API configuration and routes 
    config.MapHttpAttributeRoutes(); 

    //OData configuration 
    ODataModelBuilder builder = new ODataConventionModelBuilder(); 
    builder.EntitySet<Order>("orders"); 
    builder.EntityType<Order>().Function("getordersummary").Returns<OrderSummary>(); 

    var _model = builder.GetEdmModel(); 
    var defaultConventions = ODataRoutingConventions.CreateDefaultWithAttributeRouting(config, _model); 
    var conventions = defaultConventions.Except(defaultConventions.OfType<MetadataRoutingConvention>()); 

    config.MapODataServiceRoute(
     routeName: "ODataRoute", 
     routePrefix: "api", 
     routingConventions: conventions, 
     pathHandler: new DefaultODataPathHandler(), 
     model: _model); 

    //make uri calls much easier 
    config.EnableUnqualifiedNameCall(true); 

    //ensure JSON responses 
    var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml"); 
    config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType); 
} 

Die neue URL funktioniert nicht für:

/api/orders('13-2011.01')/ 
/api/orders(13-2011.01)/ 
/api/orders('ABC')/ 
/api/orders(ABC)/ 

Aber die neue URL funktioniert für:

/api/orders(13201101)/ 
/api/orders(123)/ 

Wenn ich beim Debuggen einen Breakpoint auf meiner neuen "Get" -Controller-Methode setze, geht es weiter ly getroffen wird, wenn die neue URL sieht wie folgt aus:

/api/orders(13201101)/ 

Der Haltepunkt erreicht wird, nicht, wenn die neue URL sieht wie folgt aus:

/api/orders('13-2011.01')/ 
/api/orders(13-2011.01)/ 

In meiner SQL Server-Datenbanktabelle, machte ich die primäre Schlüssel [MyCustomId] Feld. Ich habe dann mein EntityFramework-Modell (.edmx) aktualisiert und den Entity-Schlüssel dem Feld [MyCustomId] in meiner Klasse [Order] zugewiesen. Die URLs funktionieren immer noch nicht korrekt.

Was ist falsch an meinem Routing? Warum akzeptiert die neue URL nur ganze Zahlen, wenn sie eindeutig als "[FromODataUri] string key" definiert ist?

** Update: Ich habe bereits den Umschreib-Handler hinzugefügt, um "Punkte" in meiner URL zuzulassen. Ich sollte das erwähnen. Das funktioniert gut und hat vor dieser Migration gearbeitet. Zum Beispiel haben wir URLs wie diese funktioniert:

http://www.mywebsite.com/MyApplication/OrderInfo/OrderSummary/13-2011.01/ 

Es ist einfach die OData-Methode, die nicht funktioniert.

+0

BTW, Sie brauchen (und sollten nicht) diese Schrägstriche auf Ihren URIs haben. Sie sind harmlos (weil der OData-URI-Parser sie ignoriert), aber technisch inkorrekt. – lencharest

Antwort

2

Sie haben die Schlüsseleigenschaft des Entitätstyps Order im Datenmodell nicht geändert. Die Konvention ODataConventionModelBuilder verwendet, um die Schlüsseleigenschaft einer Klasse Foo zu finden, ist nach einer Eigenschaft mit dem Namen FooId oder Id (beide Groß- und Kleinschreibung beachten) suchen. Die Schlüsseleigenschaft Ihrer Klasse Order ist also immer noch OrderId, was ganzzahlig ist. (Wenn Sie die MetadataRoutingConvention aktivieren und /api/$metadata abrufen, sehen Sie, dass dies der Fall ist.)

Da das Datenmodell angibt, dass der Entitätstyp Order einen ganzzahligen Schlüssel hat, sucht das Routingmodul im Ressourcenpfad /api/orders(key) nach einem Wert mit Ganzzahlsyntax. Die Modellbindungs-Engine konvertiert dann die Ganzzahl in eine Zeichenfolge, die als Parameter in Ihrer Get-Methode verwendet wird.

Sie können das Problem in eine von zwei Arten beheben:

  • MyCustomId zu OrderId Umbenennen, und benennen Sie OrderId, um etwas anderes
  • Beschriften MyCustomId mit dem Key Attribut, wodurch die Namenskonvention von ODataConventionModelBuilder verwendet zwingende
+0

Wow, danke !! Es scheint mich zu zwingen, das Attribut [Key] auf dem Feld zu verwenden, egal was passiert, auch wenn ich mein .edmx/EF-Modell aktualisiert habe, um den neuen Primärschlüssel zu verwenden. Sehr eigenartig. Ich hatte auch viele Probleme mit meiner edmx und aktualisiere sie. Große Schmerzen. – AussieJoe