Maison > Article > développement back-end > Prise en charge de la clé composite dans l'API Web ASP.NET OData
本文转自:
Le EntitySetController par défaut ne prend pas en charge les clés composites. Donc, si vous disposez de modèles de clés composites, vous avez besoin d’un travail supplémentaire. Voici un exemple sur la façon de procéder.
Le modèle est simple :
<code>public class Person { [Key] public string FirstName { get; set; } [Key] public string LastName { get; set; } public int Age { get; set; } } </code>
L'URL odata de ce modèle ressemblera à :
<code>GET http://localhost:33051/People(FirstName='Kate',LastName='Jones') HTTP/1.1 </code>
Et nous souhaitons avoir des paramètres typés forts dans les actions de l'API Web vers cette URL.
<code> public Person Get([FromODataUri] string firstName, [FromODataUri] string lastName) </code>
Notez que l'attribut de classeur de modèle FromODataUri est utilisé pour analyser la représentation odata uri en type clr. Dans odata, la valeur de la chaîne est "'xxx'" et nous voulons qu'elle soit "xxx".
Afin de faire fonctionner l'itinéraire, vous pouvez ajouter une convention de routage personnalisée pour analyser le chemin clé. Voici un exemple de mise en œuvre :
<code>public class CompositeKeyRoutingConvention : EntityRoutingConvention { public override string SelectAction(System.Web.Http.OData.Routing.ODataPath odataPath, System.Web.Http.Controllers.HttpControllerContext controllerContext, ILookup<string, System.Web.Http.Controllers.HttpActionDescriptor> actionMap) { var action = base.SelectAction(odataPath, controllerContext, actionMap); if (action != null) { var routeValues = controllerContext.RouteData.Values; if (routeValues.ContainsKey(ODataRouteConstants.Key)) { var keyRaw = routeValues[ODataRouteConstants.Key] as string; IEnumerable<string> compoundKeyPairs = keyRaw.Split(','); if (compoundKeyPairs == null || compoundKeyPairs.Count() == 0) { return action; } foreach (var compoundKeyPair in compoundKeyPairs) { string[] pair = compoundKeyPair.Split('='); if (pair == null || pair.Length != 2) { continue; } var keyName = pair[0].Trim(); var keyValue = pair[1].Trim(); routeValues.Add(keyName, keyValue); } } } return action; } } </code>
La convention est héritée de EntityRoutingConvention, qui est la convention par défaut pour gérer la clé d'entité. En appelant base.SelectAction, il ajoutera le chemin complet de la clé dans routeValues. La nouvelle convention vérifiera si elle contient ",", la séparera en plusieurs clés et définira chacune d'elles dans routeValues. Ainsi, lorsque l'API Web sélectionnera des actions, elle utilisera ces valeurs pour déterminer quelle action choisir. S'il n'y a pas de "," trouvé, il se comporte de la même manière que la convection de base.
Pour enregistrer la convection, vous devez la définir lors du mappage de l'itinéraire odata :
<code>public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.EnableQuerySupport(); var mb = new ODataConventionModelBuilder(config); mb.EntitySet<Person>("People"); var conventions = ODataRoutingConventions.CreateDefault(); conventions.Insert(0, new CompositeKeyRoutingConvention()); config.Routes.MapODataRoute( routeName: "OData", routePrefix: null, model: mb.GetEdmModel(), pathHandler: new DefaultODataPathHandler(), routingConventions: conventions); } } </code>
Enregistrer la route à la position 0, c'est la faire exécuter avant les autres conventions de routage par défaut. Ainsi, la EntityRoutingConvetion par défaut ne sera pas exécutée avant elle. Après cela, vous devriez pouvoir obtenir un travail de routage.
Alors, comment créer une URL pour les clés composites ?
Vous n'avez pas besoin de faire cela pour les liens odata qui incluent un lien d'édition et un lien automatique lorsque vous utilisez ODataConventionModelBuilder. Il identifiera automatiquement les clés composites et créera l'uri pour vous.
Cependant, vous devez créer le lien pour l'en-tête d'emplacement. Voici un exemple de code de PeopleController.cs pour gérer les demandes de publication :
<code>public HttpResponseMessage PostPerson(Person person) { if (ModelState.IsValid) { _repo.UpdateOrAdd(person); HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, person); string key = string.Format( "{0}={1},{2}={3}", "FirstName", ODataUriUtils.ConvertToUriLiteral(person.FirstName, Microsoft.Data.OData.ODataVersion.V3), "LastName", ODataUriUtils.ConvertToUriLiteral(person.LastName, Microsoft.Data.OData.ODataVersion.V3)); response.Headers.Location = new Uri(Url.ODataLink( new EntitySetPathSegment("People"), new KeyValuePathSegment(key))); return response; } else { return Request.CreateResponse(HttpStatusCode.BadRequest); } } </code>
J'espère que cela aide.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!