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) { if (odataPath == null) { throw new ArgumentNullException("odataPath"); } if (controllerContext == null) { throw new ArgumentNullException("controllerContext"); } if (actionMap == null) { throw new ArgumentNullException("actionMap"); } HttpMethod requestMethod = controllerContext.Request.Method; if (odataPath.PathTemplate == "~/entityset/key/$links/navigation" && requestMethod == HttpMethod.Get) { KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; controllerContext.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; NavigationPathSegment navigationSegment = odataPath.Segments[3] as NavigationPathSegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaredType = navigationProperty.DeclaringType as IEdmEntityType; string action = requestMethod + "LinksFor" + navigationProperty.Name + "From" + declaredType.Name; return(actionMap.Contains(action) ? action : requestMethod + "LinksFor" + navigationProperty.Name); } return(base.SelectAction(odataPath, controllerContext, actionMap)); }
private static void ValidateCount(ODataPathSegment segment, IEdmModel model) { Contract.Assert(segment != null); Contract.Assert(model != null); NavigationPathSegment navigationPathSegment = segment as NavigationPathSegment; if (navigationPathSegment != null) { if (EdmLibHelpers.IsNotCountable(navigationPathSegment.NavigationProperty, model)) { throw new InvalidOperationException(Error.Format( SRResources.NotCountablePropertyUsedForCount, navigationPathSegment.NavigationPropertyName)); } return; } PropertyAccessPathSegment propertyAccessPathSegment = segment as PropertyAccessPathSegment; if (propertyAccessPathSegment != null) { if (EdmLibHelpers.IsNotCountable(propertyAccessPathSegment.Property, model)) { throw new InvalidOperationException(Error.Format( SRResources.NotCountablePropertyUsedForCount, propertyAccessPathSegment.PropertyName)); } } }
public override string SelectAction(ODataPath odataPath, HttpControllerContext context, ILookup <string, HttpActionDescriptor> actionMap) { if (context.Request.Method == HttpMethod.Get && odataPath.PathTemplate == "~/entityset/key/navigation/key") { NavigationPathSegment navigationSegment = odataPath.Segments[2] as NavigationPathSegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty.Partner; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; string actionName = "Get" + declaringType.Name; if (actionMap.Contains(actionName)) { // Add keys to route data, so they will bind to action parameters. KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; KeyValuePathSegment relatedKeySegment = odataPath.Segments[3] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.RelatedKey] = relatedKeySegment.Value; return(actionName); } } // Not a match. return(null); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (controllerContext.Request.Method != HttpMethod.Get || odataPath.PathTemplate != "~/entityset/key/navigation") { return(null); } NavigationPathSegment navigationSegment = odataPath.Segments.Last() as NavigationPathSegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; if (declaringType == null) { return(null); } string actionName = navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many ? "GetRelatedEntityCollection" : "GetRelatedSingleEntity"; if (!actionMap.Contains(actionName)) { return(null); } KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; controllerContext.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; // Add information about the specific navigation property. If you need // more than just the name, add additional items to RouteData.Values. controllerContext.RouteData.Values["navigationProperty"] = navigationProperty.Name; return(actionName); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { HttpMethod httpMethod = controllerContext.Request.Method; if (httpMethod != HttpMethod.Get) { return(null); } if (odataPath.PathTemplate == "~/entityset/key/navigation/key") { KeyValuePathSegment segment = (KeyValuePathSegment)odataPath.Segments[1]; object value = ODataUriUtils.ConvertFromUriLiteral(segment.Value, ODataVersion.V4); controllerContext.RouteData.Values.Add("key", value); segment = (KeyValuePathSegment)odataPath.Segments[3]; value = ODataUriUtils.ConvertFromUriLiteral(segment.Value, ODataVersion.V4); controllerContext.RouteData.Values.Add("relatedKey", value); NavigationPathSegment property = odataPath.Segments[2] as NavigationPathSegment; // controllerContext.RouteData.Values.Add("propertyName", property.NavigationProperty.Name); return("Get" + property.NavigationProperty.Name); } return(null); }
private static HttpStatusCode?GetChangedStatusCodeForNavigationProperty(NavigationPathSegment navigation) { EdmMultiplicity multiplicity = navigation.NavigationProperty.TargetMultiplicity(); return(multiplicity == EdmMultiplicity.ZeroOrOne || multiplicity == EdmMultiplicity.One ? HttpStatusCode.NoContent : (HttpStatusCode?)null); }
private static void AddLinkInfoToRouteData(IHttpRouteData routeData, ODataPath odataPath) { KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; routeData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; NavigationPathSegment navigationSegment = odataPath.Segments[3] as NavigationPathSegment; routeData.Values[ODataRouteConstants.NavigationProperty] = navigationSegment.NavigationProperty.Name; }
private IQueryable DrillIntoNavigationProperty(IQueryable queryable, NavigationPathSegment navigationPath) { // make sure we found the key and entity if (navigationPath == null) { throw new WebAPIDataServiceException("Missing navigation key"); } return ProjectionInto(queryable, navigationPath.NavigationPropertyName); }
/// <summary> /// Selects the action. /// </summary> /// <param name="odataPath">The odata path.</param> /// <param name="controllerContext">The controller context.</param> /// <param name="actionMap">The action map.</param> /// <returns></returns> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } HttpMethod requestMethod = controllerContext.Request.Method; IHttpRouteData routeData = controllerContext.RouteData; if (odataPath.PathTemplate == "~/entityset/key/$links/navigation" || odataPath.PathTemplate == "~/entityset/key/cast/$links/navigation") { NavigationPathSegment navigationSegment = odataPath.Segments.Last() as NavigationPathSegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; string linksActionName = FindLinksActionName(actionMap, navigationProperty, declaringType, requestMethod); if (linksActionName != null) { routeData.Values[ODataRouteConstants.Key] = (odataPath.Segments[1] as KeyValuePathSegment).Value; routeData.Values[ODataRouteConstants.NavigationProperty] = navigationSegment.NavigationProperty.Name; return(linksActionName); } } else if ((odataPath.PathTemplate == "~/entityset/key/$links/navigation/key" || odataPath.PathTemplate == "~/entityset/key/cast/$links/navigation/key") && requestMethod == HttpMethod.Delete) { NavigationPathSegment navigationSegment = odataPath.Segments[odataPath.Segments.Count - 2] as NavigationPathSegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; string linksActionName = FindLinksActionName(actionMap, navigationProperty, declaringType, requestMethod); if (linksActionName != null) { routeData.Values[ODataRouteConstants.Key] = (odataPath.Segments[1] as KeyValuePathSegment).Value; routeData.Values[ODataRouteConstants.NavigationProperty] = navigationSegment.NavigationProperty.Name; routeData.Values[ODataRouteConstants.RelatedKey] = (odataPath.Segments.Last() as KeyValuePathSegment).Value; return(linksActionName); } } return(null); }
/// <inheritdoc/> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } HttpMethod requestMethod = controllerContext.Request.Method; IHttpRouteData routeData = controllerContext.RouteData; if (odataPath.PathTemplate == EntitysetKeyNavigationRef || odataPath.PathTemplate == EntitysetKeyCastNavigationRef) { NavigationPathSegment navigationSegment = (NavigationPathSegment)odataPath.Segments[odataPath.Segments.Count - 2]; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringEntityType(); string refActionName = FindRefActionName(actionMap, navigationProperty, declaringType, requestMethod); if (refActionName != null) { routeData.Values[ODataRouteConstants.Key] = ((KeyValuePathSegment)odataPath.Segments[1]).Value; routeData.Values[ODataRouteConstants.NavigationProperty] = navigationSegment.NavigationProperty.Name; return(refActionName); } } else if ((odataPath.PathTemplate == EntitysetKeyNavigationKeyRef || odataPath.PathTemplate == EntitysetKeyCastNavigationKeyRef) && requestMethod == HttpMethod.Delete) { NavigationPathSegment navigationSegment = (NavigationPathSegment)odataPath.Segments[odataPath.Segments.Count - 3]; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringEntityType(); string refActionName = FindRefActionName(actionMap, navigationProperty, declaringType, requestMethod); if (refActionName != null) { routeData.Values[ODataRouteConstants.Key] = ((KeyValuePathSegment)odataPath.Segments[1]).Value; routeData.Values[ODataRouteConstants.NavigationProperty] = navigationSegment.NavigationProperty.Name; routeData.Values[ODataRouteConstants.RelatedKey] = ((KeyValuePathSegment)odataPath.Segments[odataPath.Segments.Count - 2]).Value; return(refActionName); } } return(null); }
private static IEdmNavigationProperty GetNavigationProperty(ODataPath path) { if (path == null) { throw new ArgumentNullException("path"); } NavigationPathSegment navigationSegment = (NavigationPathSegment)path.Segments.FirstOrDefault( s => s is NavigationPathSegment); if (navigationSegment == null) { return(null); } return(navigationSegment.NavigationProperty); }
/// <summary> /// Selects the action. /// </summary> /// <param name="odataPath">The OData path.</param> /// <param name="controllerContext">The controller context.</param> /// <param name="actionMap">The action map.</param> /// <returns></returns> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } HttpMethod method = controllerContext.Request.Method; if ((method == HttpMethod.Get || method == HttpMethod.Post) && (odataPath.PathTemplate == "~/entityset/key/navigation" || odataPath.PathTemplate == "~/entityset/key/cast/navigation")) { NavigationPathSegment navigationSegment = odataPath.Segments.Last() as NavigationPathSegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; if (declaringType != null) { string actionNamePrefix = (method == HttpMethod.Get) ? "Get" : "PostTo"; // e.g. Try GetNavigationPropertyFromDeclaringType first, then fallback on GetNavigationProperty action name string actionName = actionMap.FindMatchingAction( actionNamePrefix + navigationProperty.Name + "From" + declaringType.Name, actionNamePrefix + navigationProperty.Name); if (actionName != null) { KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; controllerContext.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; return(actionName); } } } return(null); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { //if (controllerContext.Request.Method == System.Net.Http.HttpMethod.Put) controllerContext.Request.Content.ReadAsStreamAsync().ContinueWith((t) => A(t.Result)); if (odataPath == null) { throw new ArgumentNullException("odataPath"); } if (controllerContext == null) { throw new ArgumentNullException("controllerContext"); } if (actionMap == null) { throw new ArgumentNullException("actionMap"); } string prefix = GetHttpPrefix(controllerContext.Request.Method.ToString()); if (string.IsNullOrEmpty(prefix)) { return(null); } //~/entityset/key/$links/navigation if ((odataPath.PathTemplate == "~/entityset/key/navigation") || (odataPath.PathTemplate == "~/entityset/key/cast/navigation") || (odataPath.PathTemplate == "~/entityset/key/$links/navigation")) { NavigationPathSegment segment = odataPath.Segments.Last() as NavigationPathSegment; IEdmNavigationProperty navigationProperty = segment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; if (declaringType != null) { KeyValuePathSegment keySegment = odataPath.Segments[1] as KeyValuePathSegment; controllerContext.RouteData.Values[ODataRouteConstants.Key] = keySegment.Value; string actionName = prefix + navigationProperty.Name + "From" + declaringType.Name; return(actionMap.Contains(actionName) ? actionName : (prefix + navigationProperty.Name)); } } return(null); }
// Retrieves the IEdmEntityType from the path only in the case that we are addressing a single entity. // We iterate the path backwards and we return as soon as we realize we are referencing a single entity. // That is, as soon as we find a singleton segment, a key segment or a navigation segment with target // multiplicity 0..1 or 1. internal static IEdmEntityType GetSingleEntityEntityType(ODataPath path) { if (path == null || path.Segments.Count == 0) { return(null); } int currentSegmentIndex = path.Segments.Count - 1; // Skip a possible sequence of casts at the end of the path. while (currentSegmentIndex >= 0 && path.Segments[currentSegmentIndex].SegmentKind == ODataSegmentKinds._Cast) { currentSegmentIndex--; } if (currentSegmentIndex < 0) { return(null); } ODataPathSegment currentSegment = path.Segments[currentSegmentIndex]; switch (currentSegment.SegmentKind) { case ODataSegmentKinds._Singleton: case ODataSegmentKinds._Key: return((IEdmEntityType)path.EdmType); case ODataSegmentKinds._Navigation: NavigationPathSegment navigation = (NavigationPathSegment)currentSegment; if (navigation.NavigationProperty.TargetMultiplicity() == EdmMultiplicity.ZeroOrOne || navigation.NavigationProperty.TargetMultiplicity() == EdmMultiplicity.One) { return((IEdmEntityType)path.EdmType); } break; default: break; } return(null); }
private static void CheckNavigableProperty(ODataPath path, IEdmModel model) { Contract.Assert(path != null); Contract.Assert(model != null); foreach (ODataPathSegment segment in path.Segments) { NavigationPathSegment navigationPathSegment = segment as NavigationPathSegment; if (navigationPathSegment != null) { if (EdmLibHelpers.IsNotNavigable(navigationPathSegment.NavigationProperty, model)) { throw new ODataException(Error.Format( SRResources.NotNavigablePropertyUsedInNavigation, navigationPathSegment.NavigationProperty.Name)); } } } }
public string SelectAction( ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath.PathTemplate == "~/entityset/key/navigation") { if (controllerContext.Request.Method == HttpMethod.Get) { NavigationPathSegment navigationPathSegment = (NavigationPathSegment)odataPath.Segments.Last(); controllerContext.RouteData.Values["navigation"] = navigationPathSegment.NavigationProperty.Name; KeyValuePathSegment keyValueSegment = (KeyValuePathSegment)odataPath.Segments[1]; controllerContext.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; return("GetNavigation"); } } return(null); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if ((odataPath.PathTemplate == "~/entityset/key/navigation") || (odataPath.PathTemplate == "~/entityset/key/cast/navigation")) { NavigationPathSegment segment = odataPath.Segments.Last <ODataPathSegment>() as NavigationPathSegment; IEdmNavigationProperty navigationProperty = segment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; if (declaringType != null) { string prefix = ODataHelper.GetHttpPrefix(controllerContext.Request.Method.ToString()); if (string.IsNullOrEmpty(prefix)) { return(null); } KeyValuePathSegment segment2 = odataPath.Segments[1] as KeyValuePathSegment; controllerContext.RouteData.Values.Add(ODataRouteConstants.Key, segment2.Value); string key = prefix + navigationProperty.Name + "On" + declaringType.Name; return(actionMap.Contains(key) ? key : (prefix + navigationProperty.Name)); } } return(null); }
/// <summary> /// Selects the action. /// </summary> /// <param name="odataPath">The odata path.</param> /// <param name="controllerContext">The controller context.</param> /// <param name="actionMap">The action map.</param> /// <returns></returns> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } if (controllerContext.Request.Method == HttpMethod.Get && (odataPath.PathTemplate == "~/entityset/key/navigation" || odataPath.PathTemplate == "~/entityset/key/cast/navigation")) { NavigationPathSegment navigationSegment = odataPath.Segments.Last() as NavigationPathSegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; if (declaringType != null) { KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; controllerContext.RouteData.Values.Add(ODataRouteConstants.Key, keyValueSegment.Value); // e.g. Try GetNavigationPropertyFromDeclaringType first, then fallback on GetNavigationProperty action name string propertyFromDeclaringTypeActionName = "Get" + navigationProperty.Name + "From" + declaringType.Name; return(actionMap.Contains(propertyFromDeclaringTypeActionName) ? propertyFromDeclaringTypeActionName : "Get" + navigationProperty.Name); } } return(null); }
public IHttpActionResult GetNavigation(string key, string navigation) { ODataPath path = Request.ODataProperties().Path; if (path.PathTemplate != "~/entityset/key/navigation") { return(BadRequest("Not the correct navigation property access request!")); } NavigationPathSegment property = path.Segments.Last() as NavigationPathSegment; if (property == null) { return(BadRequest("Not the correct navigation property access request!")); } IEdmEntityType entityType = property.NavigationProperty.DeclaringType as IEdmEntityType; EdmEntityObject entity = new EdmEntityObject(entityType); DataSourceProvider.Get((string)Request.Properties[Constants.ODataDataSource], key, entity); object value = DataSourceProvider.GetProperty((string)Request.Properties[Constants.ODataDataSource], navigation, entity); if (value == null) { return(NotFound()); } IEdmEntityObject nav = value as IEdmEntityObject; if (nav == null) { return(NotFound()); } return(Ok(nav)); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext context, ILookup <string, HttpActionDescriptor> actionMap) { /* * if (context.Request.Method == HttpMethod.Get && * odataPath.PathTemplate == "~/entityset/key") * { * string navigationPropertyName = odataPath.NavigationSource.Name; * string actionName = "Get" + navigationPropertyName; * * KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; * * System.Guid key; * * if (System.Guid.TryParse(keyValueSegment.Value, out key)) * { * actionName += "ById"; * context.RouteData.Values[ODataRouteConstants.Key] = key; * } * else * { * actionName += "ByKey"; * context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; * } * * if (actionMap.Contains(actionName)) * { * return actionName; * } * } */ if (context.Request.Method == HttpMethod.Get && odataPath.PathTemplate == "~/entityset/key/navigation/key") { string navigationEntityName = model.FindDeclaredEntitySet((odataPath.Segments[2] as NavigationPathSegment).NavigationPropertyName).EntityType().Name; //NavigationPathSegment navigationSegment = odataPath.Segments[2] as NavigationPathSegment; //var declaringType = model.FindDeclaredEntitySet(navigationSegment.NavigationPropertyName); //IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty.Partner; //IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; //string actionName = "Get" + declaringType.Name; string actionName = "Get" + navigationEntityName + "ByRelatedKey"; if (actionMap.Contains(actionName)) { // Add keys to route data, so they will bind to action parameters. KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; KeyValuePathSegment relatedKeySegment = odataPath.Segments[3] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.RelatedKey] = relatedKeySegment.Value; return(actionName); } } /* * if (context.Request.Method == HttpMethod.Post && * odataPath.PathTemplate == "~/entityset/key/navigation") * { * string entityName = ((EntitySetPathSegment)(odataPath.Segments[0])).EntitySetName; * string navigationPropertyName = (odataPath.Segments[2] as NavigationPathSegment).NavigationPropertyName; * //string navigationEntityName = model.FindDeclaredEntitySet((odataPath.Segments[2] as NavigationPathSegment).NavigationPropertyName).Name; * * var navigationPropertyBinding = * ((Microsoft.OData.Edm.Library.EdmNavigationPropertyBinding) * (model.FindDeclaredEntitySet(entityName) * .NavigationPropertyBindings * .FirstOrDefault(r => r.NavigationProperty.Name == navigationPropertyName))); * * var navigationPropertyType = navigationPropertyBinding * .Target * .EntityType(); * * string actionName = "Post" + navigationPropertyName + "To" + entityName; * if (actionMap.Contains(actionName)) * { * KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; * context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; * * var content = context.Request.Content.ReadAsStringAsync().Result; * var entity = Newtonsoft.Json.JsonConvert.DeserializeObject(content, Type.GetType(navigationPropertyType.FullTypeName())); * context.RouteData.Values["entity"] = entity; * * return actionName; * } * } */ /* * if (context.Request.Method == HttpMethod.Put && * odataPath.PathTemplate == "~/entityset/key/navigation/key") * { * string entityName = ((EntitySetPathSegment)(odataPath.Segments[0])).EntitySetName; * string navigationEntityName = model.FindDeclaredEntitySet((odataPath.Segments[2] as NavigationPathSegment).NavigationPropertyName).EntityType().Name; * string navigationPropertyName = (odataPath.Segments[2] as NavigationPathSegment).NavigationPropertyName; * * //string entityName = model.FindDeclaredEntitySet(((EntitySetPathSegment)(odataPath.Segments[0])).EntitySetName).EntityType().Name; * //NavigationPathSegment navigationSegment = odataPath.Segments[2] as NavigationPathSegment; * //IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; * * //var declaringType = model.FindDeclaredEntitySet(navigationSegment.NavigationPropertyName); * //var entityType = declaringType.EntityType(); * //IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; * //string actionName = "Put" + declaringType.Name; * * var navigationPropertyBinding = * ((Microsoft.OData.Edm.Library.EdmNavigationPropertyBinding) * (model.FindDeclaredEntitySet(entityName) * .NavigationPropertyBindings * .FirstOrDefault(r => r.NavigationProperty.Name == navigationPropertyName))); * * var navigationPropertyType = navigationPropertyBinding * .Target * .EntityType(); * * string actionName = "Update" + navigationEntityName; * //string actionName = "Put" + navigationEntityName + "To" + entityName; * * if (actionMap.Contains(actionName)) * { * // Add keys to route data, so they will bind to action parameters. * KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; * context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; * * KeyValuePathSegment relatedKeySegment = odataPath.Segments[3] as KeyValuePathSegment; * context.RouteData.Values[ODataRouteConstants.RelatedKey] = relatedKeySegment.Value; * * var content = context.Request.Content.ReadAsStringAsync().Result; * var entity = Newtonsoft.Json.JsonConvert.DeserializeObject(content, Type.GetType(navigationPropertyType.FullTypeName())); * context.RouteData.Values["entity"] = entity; * * return actionName; * } * } */ if (context.Request.Method == HttpMethod.Put && odataPath.PathTemplate == "~/entityset/key/navigation/key") { string navigationPropertyName = (odataPath.Segments[2] as NavigationPathSegment).NavigationPropertyName; string actionName = "Update" + navigationPropertyName; if (actionMap.Contains(actionName)) { // Add keys to route data, so they will bind to action parameters. KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; KeyValuePathSegment relatedKeySegment = odataPath.Segments[3] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.RelatedKey] = relatedKeySegment.Value; return(actionName); } } if (context.Request.Method == HttpMethod.Put && odataPath.PathTemplate == "~/entityset/key/navigation") { string navigationPropertyName = (odataPath.Segments[2] as NavigationPathSegment).NavigationPropertyName; string actionName = "Update" + navigationPropertyName; if (actionMap.Contains(actionName)) { // Add keys to route data, so they will bind to action parameters. KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; return(actionName); } } if (context.Request.Method == HttpMethod.Post && odataPath.PathTemplate == "~/entityset/key/navigation") { NavigationPathSegment segment = (odataPath.Segments[2] as NavigationPathSegment); string navigationPropertyName = segment.NavigationPropertyName; string actionPrefix = "Create"; var type = segment.NavigationProperty.Type.Definition.TypeKind; if (type == EdmTypeKind.Collection) { actionPrefix = "AddTo"; } string actionName = actionPrefix + navigationPropertyName; if (actionMap.Contains(actionName)) { // Add keys to route data, so they will bind to action parameters. KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; return(actionName); } } // Not a match. return(null); }
// Determines if a status code needs to be changed based on the path of the request and returns the new // status code or null if no change is required. internal static HttpStatusCode?GetUpdatedResponseStatusCodeOrNull(ODataPath oDataPath) { if (oDataPath == null || oDataPath.Segments == null || oDataPath.Segments.Count == 0) { return(null); } // Skip any sequence of cast segments at the end of the path. int currentIndex = oDataPath.Segments.Count - 1; ReadOnlyCollection <ODataPathSegment> segments = oDataPath.Segments; while (currentIndex >= 0 && segments[currentIndex].SegmentKind == ODataSegmentKinds.Cast) { currentIndex--; } // Null value properties should be treated in the same way independent of whether the user asked for the // raw value of the property or a specific format, so we skip the $value segment as it can only be // preceeded by a property access segment. if (currentIndex >= 0 && segments[currentIndex].SegmentKind == ODataSegmentKinds.Value) { currentIndex--; } // Protect ourselves against malformed path segments. if (currentIndex < 0) { return(null); } switch (segments[currentIndex].SegmentKind) { case ODataSegmentKinds._Key: // Look at the previous segment to decide, but skip any possible sequence of cast segments in // between. currentIndex--; while (currentIndex >= 0 && segments[currentIndex].SegmentKind == ODataSegmentKinds.Cast) { currentIndex--; } if (currentIndex < 0) { return(null); } switch (segments[currentIndex].SegmentKind) { case ODataSegmentKinds._EntitySet: // Return 404 if we were trying to retrieve a specific entity from an entity set. return(HttpStatusCode.NotFound); case ODataSegmentKinds._Navigation: // Return 204 if we were trying to retrieve a related entity via a navigation property. return(HttpStatusCode.NoContent); default: break; } return(null); case ODataSegmentKinds._Property: // Return 204 only if the property is single valued (not a collection of values). PropertyAccessPathSegment property = (PropertyAccessPathSegment)segments[currentIndex]; return(GetChangedStatusCodeForProperty(property)); case ODataSegmentKinds._Navigation: // Return 204 only if the navigation property is a single related entity and not a collection // of entities. NavigationPathSegment navigation = (NavigationPathSegment)segments[currentIndex]; return(GetChangedStatusCodeForNavigationProperty(navigation)); case ODataSegmentKinds._Singleton: // Return 404 for a singleton with a null value. return(HttpStatusCode.NotFound); default: return(null); } }
/// <inheritdoc/> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } HttpMethod method = controllerContext.Request.Method; string actionNamePrefix = GetActionMethodPrefix(method); if (actionNamePrefix == null) { return(null); } if (odataPath.PathTemplate == "~/entityset/key/navigation" || odataPath.PathTemplate == "~/entityset/key/navigation/$count" || odataPath.PathTemplate == "~/entityset/key/cast/navigation" || odataPath.PathTemplate == "~/entityset/key/cast/navigation/$count" || odataPath.PathTemplate == "~/singleton/navigation" || odataPath.PathTemplate == "~/singleton/navigation/$count" || odataPath.PathTemplate == "~/singleton/cast/navigation" || odataPath.PathTemplate == "~/singleton/cast/navigation/$count") { NavigationPathSegment navigationSegment = (odataPath.Segments.Last() as NavigationPathSegment) ?? odataPath.Segments[odataPath.Segments.Count - 2] as NavigationPathSegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; // It is not valid to *Post* to any non-collection valued navigation property. if (navigationProperty.TargetMultiplicity() != EdmMultiplicity.Many && method == HttpMethod.Post) { return(null); } // It is not valid to *Put/Patch" to any collection-valued navigation property. if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many && (method == HttpMethod.Put || "PATCH" == method.Method.ToUpperInvariant())) { return(null); } // *Get* is the only supported method for $count request. if (odataPath.Segments.Last() is CountPathSegment && method != HttpMethod.Get) { return(null); } if (declaringType != null) { // e.g. Try GetNavigationPropertyFromDeclaringType first, then fallback on GetNavigationProperty action name string actionName = actionMap.FindMatchingAction( actionNamePrefix + navigationProperty.Name + "From" + declaringType.Name, actionNamePrefix + navigationProperty.Name); if (actionName != null) { if (odataPath.PathTemplate.StartsWith("~/entityset/key", StringComparison.Ordinal)) { KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; controllerContext.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; } return(actionName); } } } return(null); }
/// <inheritdoc/> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } HttpMethod requestMethod = controllerContext.Request.Method; IHttpRouteData routeData = controllerContext.RouteData; if (!IsSupportedRequestMethod(requestMethod)) { return(null); } if (odataPath.PathTemplate == "~/entityset/key/navigation/$ref" || odataPath.PathTemplate == "~/entityset/key/cast/navigation/$ref" || odataPath.PathTemplate == "~/singleton/navigation/$ref" || odataPath.PathTemplate == "~/singleton/cast/navigation/$ref") { NavigationPathSegment navigationSegment = (NavigationPathSegment)odataPath.Segments[odataPath.Segments.Count - 2]; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringEntityType(); string refActionName = FindRefActionName(actionMap, navigationProperty, declaringType, requestMethod); if (refActionName != null) { if (odataPath.PathTemplate.StartsWith("~/entityset/key", StringComparison.Ordinal)) { routeData.Values[ODataRouteConstants.Key] = ((KeyValuePathSegment)odataPath.Segments[1]).Value; } routeData.Values[ODataRouteConstants.NavigationProperty] = navigationSegment.NavigationProperty.Name; return(refActionName); } } else if ((requestMethod == HttpMethod.Delete) && ( odataPath.PathTemplate == "~/entityset/key/navigation/key/$ref" || odataPath.PathTemplate == "~/entityset/key/cast/navigation/key/$ref" || odataPath.PathTemplate == "~/singleton/navigation/key/$ref" || odataPath.PathTemplate == "~/singleton/cast/navigation/key/$ref")) { NavigationPathSegment navigationSegment = (NavigationPathSegment)odataPath.Segments[odataPath.Segments.Count - 3]; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; IEdmEntityType declaringType = navigationProperty.DeclaringEntityType(); string refActionName = FindRefActionName(actionMap, navigationProperty, declaringType, requestMethod); if (refActionName != null) { if (odataPath.PathTemplate.StartsWith("~/entityset/key", StringComparison.Ordinal)) { routeData.Values[ODataRouteConstants.Key] = ((KeyValuePathSegment)odataPath.Segments[1]).Value; } routeData.Values[ODataRouteConstants.NavigationProperty] = navigationSegment.NavigationProperty.Name; routeData.Values[ODataRouteConstants.RelatedKey] = ((KeyValuePathSegment)odataPath.Segments[odataPath.Segments.Count - 2]).Value; return(refActionName); } } return(null); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext context, ILookup <string, HttpActionDescriptor> actionMap) { if (context.Request.Method == HttpMethod.Get && odataPath.PathTemplate == "~/entityset/key/navigation/key") { string navigationEntityName = model.FindDeclaredEntitySet((odataPath.Segments[2] as NavigationPathSegment).NavigationPropertyName).EntityType().Name; string actionName = "Get" + navigationEntityName + "ByRelatedKey"; if (actionMap.Contains(actionName)) { // Add keys to route data, so they will bind to action parameters. KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; KeyValuePathSegment relatedKeySegment = odataPath.Segments[3] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.RelatedKey] = relatedKeySegment.Value; return(actionName); } } if (context.Request.Method == HttpMethod.Put && odataPath.PathTemplate == "~/entityset/key/navigation/key") { string navigationPropertyName = (odataPath.Segments[2] as NavigationPathSegment).NavigationPropertyName; string actionName = "Update" + navigationPropertyName; if (actionMap.Contains(actionName)) { // Add keys to route data, so they will bind to action parameters. KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; KeyValuePathSegment relatedKeySegment = odataPath.Segments[3] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.RelatedKey] = relatedKeySegment.Value; return(actionName); } } if (context.Request.Method == HttpMethod.Put && odataPath.PathTemplate == "~/entityset/key/navigation") { string navigationPropertyName = (odataPath.Segments[2] as NavigationPathSegment).NavigationPropertyName; string actionName = "Update" + navigationPropertyName; if (actionMap.Contains(actionName)) { // Add keys to route data, so they will bind to action parameters. KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; return(actionName); } } if (context.Request.Method == HttpMethod.Post && odataPath.PathTemplate == "~/entityset/key/navigation") { NavigationPathSegment segment = (odataPath.Segments[2] as NavigationPathSegment); string navigationPropertyName = segment.NavigationPropertyName; string actionPrefix = "Create"; var type = segment.NavigationProperty.Type.Definition.TypeKind; if (type == EdmTypeKind.Collection) { actionPrefix = "AddTo"; } string actionName = actionPrefix + navigationPropertyName; if (actionMap.Contains(actionName)) { // Add keys to route data, so they will bind to action parameters. KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; return(actionName); } } // Not a match. return(null); }
public static IEdmNavigationProperty GetNavigationProperty(ODataPath odataPath) { NavigationPathSegment segment = odataPath.Segments.OfType <NavigationPathSegment>().SingleOrDefault(); return(segment == null ? null : segment.NavigationProperty); }