我有一个新的 OData V4 服务,我正在尝试运行该服务,但我看到了意外错误...
“不能在 $expand 查询选项中使用属性 'ProductType'。”
我在另一个 OData 服务中没有遇到这个问题,我一直在比较两者,我找不到两个 WRT 模型中项目的设置和 WebApiConfig 之间的显着差异。我按照文章create-an-odata-v4-endpoint 中列出的示例构建了这个,而另一个是使用脚手架向导创建的。
这是表、控制器和 WebApiConfig 的布局。我还可以在哪里寻找无法联系背后的原因?
// Product.cs
public partial class Product
{
public int ProductId { get; set; }
public int ProductTypeId { get; set; }
public string Size { get; set; }
public string PartNo { get; set; }
public virtual ProductType ProductType { get; set; }
}
// ProductType.cs
public partial class ProductType{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public ProductType()
{
this.Products = new HashSet<Product>();
}
public int ProductTypeId { get; set; }
public string ProductTypeName { get; set; }
public string Image { get; set; }
public string ProductDescription { get; set; }
public string InstallInstructions { get; set; }
public string DataSheet { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Product> Products { get; set; }
}
// WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.SetTimeZoneInfo(TimeZoneInfo.Utc);
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
builder.EntityType<Product>().HasKey(entity => entity.ProductId);
builder.EntityType<Product>().HasRequired(entity => entity.ProductType, (entity, targetEntity) => entity.ProductTypeId == targetEntity.ProductTypeId);
builder.EntitySet<ProductType>("ProductTypes");
builder.EntityType<ProductType>().HasKey(entity => entity.ProductTypeId);
builder.EntityType<ProductType>().HasMany(entity => entity.Products);
config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
// ProductTypesController.cs
public class ProductTypesController : BaseController
{
[EnableQuery]
public IQueryable<ProductType> Get()
{
return db.ProductTypes;
}
[EnableQuery]
public SingleResult<ProductType> Get([FromODataUri] int key)
{
IQueryable<ProductType> result = db.ProductTypes.Where(p => p.ProductTypeId.Equals(key));
return SingleResult.Create(result);
}
....
}
// ProductsController.cs
public class ProductsController : BaseController
{
[EnableQuery]
public IQueryable<Product> Get()
{
return db.Products;
}
[EnableQuery]
public SingleResult<Product> Get([FromODataUri] int key)
{
IQueryable<Product> result = db.Products.Where(p => p.ProductId.Equals(key));
return SingleResult.Create(result);
}
...
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试了两个方向,使用单选和多选来引用相关项目(将这些 url 输入地址栏中):
/ProductTypes?$expand=Products、 和/ProductTypes(3)?$expand=Products、 和/Products?$expand=ProductType,/Products(3)?$expand=ProductType
在每种情况下我都会遇到相同的错误。如果还有其他东西需要确定原因,我很乐意查找,我只需要知道在哪里查找即可。
谢谢,迈克
我在 odata github 问题的帖子中找到了答案。issuecomment-248168536根据此评论,这是 Microsoft.AspNet.OData 包版本 6.0.0 中的新行为,并且是一个重大更改。我回到正在运行的其他服务并检查了 Nuget 包,它安装了 v 5.6.0 而不是最新的(当前是 7.1.0)。
所以解决方法是在映射之前为您想要的功能添加配置行...
config.Expand().Select();
config.MapODataServiceRoute("odata", null, builder.GetEdmModel());
Run Code Online (Sandbox Code Playgroud)
这是全局启用该选项以使其像 < v6.0 版本一样工作的修复程序。该线程中引用了一个文档 ( 13-01-modelbound-attribute ),它演示了通过模型属性对选项进行精细控制的新功能。
HTH,迈克
| 归档时间: |
|
| 查看次数: |
974 次 |
| 最近记录: |