控制器:
public class PhaseController: ODataController
{
[EnableQuery]
[System.Web.Http.HttpGet]
public IQueryable < Phase > CustomPhases(CustomPhaseRequest request = null)
{
if (request == null) //default values
request = new CustomPhaseRequest()
{
Duration = 3,
PhaseFilters = new List < CustomPhaseFilter > ()
{
new CustomPhaseFilter()
{
Name = "sp500", DisplayName = "SP500", GreaterThanValue = 10, Method = "returns", FieldName = "BLAH"
},
//new CustomPhaseFilter() { Name= "yr10", DisplayName= "10YR", GreaterThanValue= 0, Method= "delta", FieldName= "BAR", Unit= "bp" },
//new CustomPhaseFilter() { Name= "em", DisplayName= "EM", GreaterThanValue= 0, Method= "returns", FieldName= "FOO" }
}
};
var provider = DrawDownController.YadiYadahDataProvider;
var data = provider.GetCustomPhases(provider.GetCachedData(), request);
return data.AsQueryable();
}
}
控制器动作参数:
public class CustomPhaseRequest
{
public int Duration { get; set; }
public List<CustomPhaseFilter> PhaseFilters { get; set; }
}
public class CustomPhaseFilter
{
public string Name { get; set; } // maps to str
public string DisplayName { get; set; } // maps to display
public double? SmallerThanValue { get; set; } // maps to value
public double? GreaterThanValue { get; set; } // maps to value
public string Method { get; set; } // maps to method
public string FieldName { get; set; } // maps to dataStr
public string Unit { get; set; } // maps to unit
}
模型构建器代码:
ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder();
EntitySetConfiguration < Phase > phaseConfig = modelBuilder.EntitySet < Phase > ("Phase");
phaseConfig.EntityType.HasKey(p => p.Key);
var phaseType = modelBuilder.EntityType < Phase > ();
var customPhasesFunction = phaseType.Collection.Function("CustomPhases");
customPhasesFunction.ReturnsCollection < Phase > ().Parameter < CustomPhaseRequest > ("request");
IEdmModel model = modelBuilder.GetEdmModel();
config.MapODataServiceRoute("odata", "odata", model);
从javascript如何调用此odata函数并传入复杂的参数?
http://example.com/odata/Phase/Default.CustomPhases(@param)
尝试在典型的odata函数url中传递复杂类型时存在许多问题。 首先是它是基本URL的一部分,而不是params的一部分(在?之后),所以如果你采用json有效载荷,如:
{
"Duration": 3,
"PhaseFilters": [
{
"Name": "sp500",
"DisplayName": "SP500",
"GreaterThanValue": 10,
"Method": "returns",
"FieldName": "BLAH"
},
{
"Name": "yr10",
"DisplayName": "10YR",
"GreaterThanValue": 0,
"Method": "delta",
"FieldName": "BAR",
"Unit": "bp"
},
{
"Name": "em",
"DisplayName": "EM",
"GreaterThanValue": 0,
"Method": "returns",
"FieldName": "FOO"
}
]
}
将它字符串化并对其进行urlencoded,即使我告诉asp.net忽略某些字符,当我手动构建url时,它仍然没有参数绑定到实际的odata控制器操作。它给出了404。
其次是我不知道是否可以使用http GET应用程序/ json内容类型和数据参数,并在执行jquery ajax调用时将其放在url的非参数位置。
从语义上讲,这是一个odata函数(不是动作),因为它不会修改任何东西 - 只需使用自定义参数检索数据,因此它使用GET spec-wise(如果我错了请纠正我)...
这是怎么做到的?
答案 0 :(得分:3)
函数和动作的参数只能是webapi 2.2中的原始类型或枚举类型。
如果需要复杂类型,可以将参数类型定义为字符串,然后将参数作为字符串文字传递。
然后在您的控制器中,您可以获取参数的字符串值并将其反序列化为CustomPhaseRequest对象。
public IQueryable<Phase> CustomPhases(string requestString)
{
// Deserialize the requestString to requestObject
}
然而,网址的长度有限制。因此,如果参数字符串太长,您必须将其定义为操作并在主体中传递参数,尽管它不会修改任何内容。