我对Web API 2和OData v3有一个奇怪的问题,特别是ODataConventionModelBuilder
。我在 WebApiConfig.cs 中有以下代码:
// Web API configuration and services
var builder = new ODataConventionModelBuilder();
// Adding all the entity sets here, then complex types, custom actions, ...
builder.EntitySet<Address>("Addresses");
/* ... */
builder.AddComplexType(typeof(CustomerSearchResultDto));
/* ... */
var customerSearchAction = builder.Entity<Customer>().Collection.Action("Search");
patientSearchAction.Parameter<string>("pattern");
patientSearchAction.Parameter<bool>("searchDeactivated");
// These are the interfaces that some entities implement. These MUST NOT be put into the model
var interfaces = typeof(ICustomer).Assembly.GetTypes().Where(t => t.IsInterface).ToArray();
builder.Ignore(interfaces);
// Building models
var model = builder.GetEdmModel();
config.Routes.MapODataServiceRoute("odata", "odata", model);
模型构建良好,没有例外。但是某些实体实现的接口会转换为复杂类型,这当然是荒谬的,并且会在客户端引起一些命名空间混淆。以下是生成的元数据(服务:1111 / $元数据)
的摘录<ComplexType Name="IAddress">
<Property Name="Street1" Type="Edm.String" />
<Property Name="Street2" Type="Edm.String" />
<Property Name="Zip" Type="Edm.String" />
<Property Name="City" Type="Edm.String" />
<Property Name="Country" Type="Edm.String" />
</ComplexType>
我也尝试使用builder.Ignore<IAddress>
,但无济于事。我做错了什么?
答案 0 :(得分:2)
我找到了更好的解决方案。在WebApiConfig.cs中,我为每个实体做了:
builder.EntitySet<Address>("Addresses").EntityType.DerivesFromNothing();
如果实体派生自另一个,我使用DerivesFrom()方法。为了避免命名空间与我的复杂类型冲突,我使用DTO。由于我有很多,我只是像这样批量添加它们(使用反射):
var builderMethod = builder.GetType().GetMethod("ComplexType");
foreach (var type in typeof (WebApiConfig).Assembly.GetTypes().Where(x => x.Name.EndsWith("Dto")))
{
var genericMethod = builderMethod.MakeGenericMethod(type);
genericMethod.Invoke(builder, null);
}
这非常有效。
答案 1 :(得分:1)
我猜你有一个定义为IAddress的属性,例如:
public class Customer
{
public int CustomerId { get; set; }
public IAddress Address { get; set; }
...
}
因此,builder.Ignore(interfaces);
desen不起作用。
如果是这样,你可以:
Ignore
财产。