2016-11-28 61 views
0

我正在使用ASP.NET OData API版本6.0 我正在使用无类型对象创建EDM模型。 原因是我的数据库中有一个语义数据模型,任何对象类型的crud操作都是使用同一段代码完成的。所以我基本上只需要制作一个解析OData查询字符串的控制器,并将其应用于加载对象的本地方式。差不多所有这些都有效。有什么缺失,以某种方式定义路由动态....ASP.NET OData,将无类型/无类型实体路由到同一控制器

那么如何映射实体x,y和z使用相同的控制器?

我建立模型的代码看起来类似于下面。这将发送到名为IdentitiesController,ResourcesController,SystemsController和OrgunitsController的控制器。但他们都应该路由到相同的控制器“NativeObjectsController”....

下面只是一组可能的实体类型...和最终用户可以创建自己的类型,所以我不能只是制作专门的控制器...

public static void Register(HttpConfiguration config) 
{ 
    IList<IODataRoutingConvention> routingConventions = ODataRoutingConventions.CreateDefault(); 
    IODataPathHandler pathHandler = new DefaultODataPathHandler(); 

    config.MapODataServiceRoute(
    routeName: "ODataRoute", 
    routePrefix: "odata/dataobjects", 
    model: GetEntityModel() 
    // ,pathHandler: pathHandler, 
    //routingConventions: routingConventions 
); 

    var routes = config.Routes; 
    config.AddODataQueryFilter(); 
    config.EnsureInitialized(); 
} 

public static EdmModel GetEntityModel() 
{ 
    if (model != null) 
    return model; 

    model = new EdmModel(); 
    EdmEntityContainer container = new EdmEntityContainer(ns_ois, "OISContainer"); 
    model.AddElement(container); 

    AddDataObjectTypeToModel(model, container, "IDENTITY", "Identities"); 
    AddDataObjectTypeToModel(model, container, "RESOURCE", "Resources"); 
    AddDataObjectTypeToModel(model, container, "SYSTEM", "Systems"); 
    AddDataObjectTypeToModel(model, container, "ORGUNIT", "OrgUnits"); 

    return model; 
} 

private static void AddDataObjectTypeToModel(EdmModel model, EdmEntityContainer container, string dataObjectSystemName, string entitySetName) 
{ 
    DataObjectTypeController dotController = Factory.Default.CreateController<DataObjectTypeController>(); 
    int dotId = dotController.GetId(dataObjectSystemName); 
    DataObjectType dot = dotController.GetDataObjectType(dotId); 

    var entityObject = new EdmEntityType(ns_ois, dataObjectSystemName); 
    model.AddElement(entityObject); 
    entityObject.AddKeys(entityObject.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, false)); 
    entityObject.AddStructuralProperty("UId", EdmPrimitiveTypeKind.Guid, false); 
    entityObject.AddStructuralProperty("DisplayName", EdmPrimitiveTypeKind.String, false); 

    foreach (var property in dot.GetProperties()) 
    { 
    } 

    var entitySet = container.AddEntitySet(entitySetName, entityObject); 
} 

回答

0

现在我已经建立了我IODataRoutingConvention能够选择控制器。

public class DataObjectTypeRoutingConvention : IODataRoutingConvention 
{ 
    public string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) 
    { 
    return null; 
    } 

    public string SelectController(ODataPath odataPath, HttpRequestMessage request) 
    { 
    if (odataPath.PathTemplate.StartsWith("~/entityset",System.StringComparison.InvariantCultureIgnoreCase)) 
     return "DataObjects"; 
    else 
     return null; 
    } 
} 

,然后我加入到作为第一惯例

public static void Register(HttpConfiguration config) 
{ 
    IList<IODataRoutingConvention> routingConventions = ODataRoutingConventions.CreateDefault(); 
    IODataPathHandler pathHandler = new DefaultODataPathHandler(); 

    routingConventions.Insert(0, new Controllers.DataObjectTypeRoutingConvention()); 

    config.MapODataServiceRoute(
    routeName: "ODataRoute", 
    routePrefix: "odata/dataobjects", 
    model: GetEntityModel(), 
    pathHandler: pathHandler, 
    routingConventions: routingConventions 
); 

    config.AddODataQueryFilter(); 

    config.EnsureInitialized(); 
} 
相关问题