在OData v4控制器中,是否可以为Get()
和Get([FromIDataUri] key)
返回不同的模型?
我喜欢使用ViewModels,在使用Get()
方法时,我想要返回xxxOverviewViewModel
。使用Get([FromIDataUri] key)
方法时,我想返回xxxViewModel。
这是可能的,如果是的话,怎么样?
我试图返回不同的模型,但我总是得到406 Acceptable
。
Webapi.config:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableCors();
config.MapODataServiceRoute("ODataRoute", "odata", GetEdmModel());
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Filter().Expand().Select().OrderBy().MaxTop(null).Count();
}
private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet<ComplaintViewModel>("ComplaintOData");
return builder.GetEdmModel();
}
}
ComplaintODataController
public class ComplaintODataController : ODataController
{
private readonly QueryProcessor _queryProcessor;
public ComplaintODataController(QueryProcessor queryProcessor)
{
_queryProcessor = queryProcessor;
}
[EnableQuery]
public IQueryable<ComplaintOverviewViewModel> Get()
{
var result = _queryProcessor.Handle(new GetAllComplaintsQuery());
return result;
}
// WHEN CALLING THIS METHOD I GET A 406:
[EnableQuery]
public ComplaintViewModel Get([FromODataUri] int key)
{
var result = _queryProcessor.Handle(new GetComplaintByIdQuery { Id = key });
return result;
}
}
编辑:
我的GetAllComplaintsQuery.Handle
方法如下所示:
public IQueryable<ComplaintOverviewViewModel> Handle(GetAllComplaintsQuery query)
{
// .All is an IQueryable<Complaint>
var result = _unitOfWork.Complaints.All.Select(c => new ComplaintOverviewViewModel
{
ComplaintType = c.ComplaintType.Description,
CreationDate = c.CreationDate,
Customer = c.Customer,
Description = c.Description,
Id = c.Id,
SequenceNumber = c.SequenceNumber,
Creator = c.Creator.Name
});
return result;
}
这是我的ComplaintConfiguration
public class ComplaintConfiguration : EntityTypeConfiguration<Complaint>
{
public ComplaintConfiguration()
{
Property(p => p.SequenceNumber).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
Property(p => p.Description).IsRequired();
}
}
答案 0 :(得分:1)
您没有包含 ViewModel 类的定义,因此,首先请确保我们在同一页面上了解您实际尝试实现的目标。
当客户端从参数较少的Get()
请求投诉记录列表但客户端请求{的特定投诉时,您似乎想要返回一些受限制的字段集{1}}您想要包含其他字段的方法。
我使用以下层次建模了这个假设:
Get([FromODataUri] int key)
Ran测试,public class ComplaintTypeViewModel
{
public int Id { get; set; }
}
public class ComplaintOverviewViewModel : ComplaintTypeViewModel
{
public string Name { get; set; }
}
public class ComplaintViewModel : ComplaintOverviewViewModel
{
public string Details { get; set; }
}
按预期返回了一个只有 Id 和名称的列表,GET /odata/ComplaintOData
返回了一条包含详细信息的记录除了其他两个字段之外,也是预期的。
我从来没有必要更改控制器或GET /odata/ComplaintOData(1)
的代码,但WebApiConfig.cs
中的字符串参数必须与ccontroller匹配(您的代码中有builder.EntitySet<ComplaintTypeViewModel>("ComplaintOData");
)。< / p>
由于它有效,我试图找出如何重现你的406.我已经改变"ComplaintTypeOData"
直接延长ComplaintViewModel
而不是延伸ComplaintTypeViewModel
(注意我和#39;我刚刚复制了ComplaintOverviewViewModel
属性:
Name
这也很好。
我可以重现406的唯一方法是将public class ComplaintTypeViewModel
{
public int Id { get; set; }
}
public class ComplaintOverviewViewModel : ComplaintTypeViewModel
{
public string Name { get; set; }
}
public class ComplaintViewModel : ComplaintTypeViewModel
{
public string Name { get; set; }
public string Details { get; set; }
}
更改为而不是在其继承层次结构中有ComplaintViewModel
:
ComplaintTypeViewModel
这最终给了我来自public class ComplaintTypeViewModel
{
public int Id { get; set; }
}
public class ComplaintOverviewViewModel : ComplaintTypeViewModel
{
public string Name { get; set; }
}
public class ComplaintViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Details { get; set; }
}
的406代码,而GET /odata/ComplaintOData(1)
仍然使用 Id 和名称返回列表就好了。
因此,只要 ViewModel 类的全部从GET /odata/ComplaintOData
延伸相同的T
,您就可以返回其中的任何一个来自控制器中的builder.EntitySet<T>("name")
重载。请检查您如何定义 ViewModels
答案 1 :(得分:0)
为两个模型创建一个伞类,并让你的get方法分别返回你想要的。
public class myMainModel
{
public xxxOverviewViewModel x {get;set;}
public xxxOverviewViewModel y {get;set;}
}
myMainModel Get()
{
....
return myMainModel.x;
}
myMainModel Get( int key)
{
....
return myMainModel.y;
}
答案 2 :(得分:0)
尝试从行动中删除SELECT t1.*
FROM prd_data t1
WHERE t1.id = (SELECT t2.id
FROM prd_data t2
WHERE t2.sub_prd_id= t1.sub_prd_id
ORDER BY t2.created_at DESC
LIMIT 1)
[EnableQuery]
public ComplaintViewModel Get([FromODataUri] int key)
使用OData查询语法启用查询。集合EnableQueryAttribute
是可以接受的。如果要返回单个实体,请不要使用该属性。
<强>更新强>
还尝试将参数IQueryable<>
重命名为int key