github OData/odata.net -, - .
OData JSON. OData: ~/action, ~/entityset/key/action ~/entityset/action.
CustomODataPathHandler.cs
internal class CustomODataPathHandler : DefaultODataPathHandler
{
#region Methods
protected override ODataPathSegment ParseAtEntityCollection(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, string segment)
{
ODataPathSegment customActionPathSegment;
if (TryParseCustomAction(model, previousEdmType, segment, out customActionPathSegment))
{
return customActionPathSegment;
}
return base.ParseAtEntityCollection(model, previous, previousEdmType, segment);
}
protected override ODataPathSegment ParseAtEntity(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, string segment)
{
ODataPathSegment customActionPathSegment;
if (TryParseCustomAction(model, previousEdmType, segment, out customActionPathSegment))
{
return customActionPathSegment;
}
return base.ParseAtEntity(model, previous, previousEdmType, segment);
}
protected override ODataPathSegment ParseEntrySegment(IEdmModel model, string segment)
{
var container = model.EntityContainers().First();
if (CouldBeCustomAction(container, segment))
{
ODataPathSegment customActionPathSegment;
if (TryParseCustomAction(model, segment, out customActionPathSegment))
{
return customActionPathSegment;
}
}
return base.ParseEntrySegment(model, segment);
}
private static bool TryParseCustomAction(IEdmModel model, IEdmType previousEdmType, string segment, out ODataPathSegment pathSegment)
{
var container = model.EntityContainers().First();
if (CouldBeCustomAction(container, segment))
{
var actionName = segment.Split('.').Last();
var action = (from f in container.FindFunctionImports(actionName)
let parameters = f.Parameters
where parameters.Count() >= 1 && parameters.First().Type.Definition.IsEquivalentTo(previousEdmType)
select f).FirstOrDefault();
if (action != null)
{
pathSegment = new ActionPathSegment(action);
return true;
}
}
pathSegment = null;
return false;
}
private static bool TryParseCustomAction(IEdmModel model, string segment, out ODataPathSegment pathSegment)
{
var container = model.EntityContainers().First();
if (CouldBeCustomAction(container, segment))
{
var actionName = segment.Split('.').Last();
var action = (from f in container.FindFunctionImports(actionName)
where f.EntitySet == null && !f.IsBindable
select f).FirstOrDefault();
if (action != null)
{
pathSegment = new ActionPathSegment(action);
return true;
}
}
pathSegment = null;
return false;
}
private static bool CouldBeCustomAction(IEdmEntityContainer container, string segment)
{
return segment.StartsWith(container.Name + ".", StringComparison.OrdinalIgnoreCase);
}
#endregion
}
, JSON ".", web.config( ):
web.config
<system.webServer>
<handlers>
<add name="UrlRoutingHandler" path="odata/*" verb="*" type="System.Web.Routing.UrlRoutingHandler, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</handlers>
</system.webServer>
, WebApiConfig OData:
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.Namespace = "MyNamespace";
modelBuilder.ContainerName = "MyContainer";
modelBuilder.EntitySet<MyEntity>("MyEntities");
var action = modelBuilder.Entity<MyEntity>().Action("MyAction");
action.Returns<string>();
modelBuilder.Action("Test");
foreach (var structuralType in modelBuilder.StructuralTypes)
{
structuralType.GetType().GetProperty("Namespace").SetValue(structuralType, "MyNamespace");
}
var model = modelBuilder.GetEdmModel();
config.Routes.MapODataServiceRoute("OData", "odata", model, new CustomODataPathHandler(), ODataRoutingConventions.CreateDefault());
}
}