我正在尝试使用odata-4(在web api 2.2项目中)创建一个odata api端点,我需要在odata控制器中使用我的一个GET动作来接受多个字符串参数(它们是自定义搜索属性,除了我的实体中为其创建odata控制器的属性)。
但是到目前为止我所做的所有试验中,在访问浏览器中的特定操作时,我总是遇到一个或其他错误。 到目前为止,我还没有能够获得流/语法的工作组合,因此在这里共享查询以获得关于如何在odata-4中实现将多个参数传递给odata动作的建议 OR 如何修复了错误。
代码如下:
package.config:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.Mvc" version="5.1.2" targetFramework="net45" />
<package id="Microsoft.AspNet.OData" version="5.3.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.1.2" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.OData" version="5.1.2" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.1.2" targetFramework="net45" />
<package id="Microsoft.Data.Edm" version="5.6.0" targetFramework="net45" />
<package id="Microsoft.Data.OData" version="5.6.0" targetFramework="net45" />
<package id="Microsoft.OData.Core" version="6.5.0" targetFramework="net45" />
<package id="Microsoft.OData.Edm" version="6.5.0" targetFramework="net45" />
</packages>
WebApiConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<DocumentsModel>("SampleData");
var function = builder.Function("SampleFunction");
function.Parameter<string>("catGUIDOrText");
function.Parameter<string>("type");
function.Parameter<string>("isAutoCompSearch");
function.ReturnsCollectionFromEntitySet<DocumentsModel>("SampleData");
config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Odata控制器:
[ODataRoutePrefix("SampleData")]
public class SampleDataController : ODataController
{
[EnableQuery]
[HttpGet]
[ODataRoute("SampleFunction(catGUIDOrText={catGUIDOrText},type={type},isAutoCompSearch={isAutoCompSearch})")]
public IEnumerable<DocumentsModel> GetSampleData([FromODataUri] string catGUIDOrText, [FromODataUri] string type, [FromODataUri] string isAutoCompSearch)
{
return new List<DocumentsModel>().AsQueryable<DocumentsModel>();
}
}
注意: - DocumentsModel是一个包含所有字符串属性的类。
错误详情
现在,当通过以下网址在浏览器中访问此操作时,我收到错误:
URL: http://localhost/VirtualDirectoryNameInIIS/odata/SampleData/SampleFunction(catGUIDOrText= '752',类型= '230',isAutoCompSearch = '假')
我得到的错误:
路径模板 '的sampleData / SampleFunction(catGUIDOrText = {catGUIDOrText},类型= {}类型,isAutoCompSearch = {isAutoCompSearch})' 在控件'SampleData'中的'GetSampleData'动作不是 有效的OData路径模板。请求URI无效。自从 segment'SampleData'指的是一个集合,这必须是最后一个集合 请求URI中的段,或者必须后跟函数或 可以绑定到它的动作,否则所有中间段 必须引用单一资源。
请帮助我解决您可能遇到的任何输入,无论是代码还是我用来访问给定方法的网址。感谢。
我遵循的一些参考资料用于解决此问题或确保我遵循正确的方向/语法:
答案 0 :(得分:4)
编辑添加显式名称空间的WebApiConfig.cs
builder.Namespace = "MyNamespace";
编辑WebApiConfig.cs,更改功能声明
FunctionConfiguration function = builder.EntityType<DocumentsModel>().Collection.Function("SampleFunction");
function.Parameter<string>("catGUIDOrText");
function.Parameter<string>("type");
function.Parameter<string>("isAutoCompSearch");
function.ReturnsCollectionFromEntitySet<DocumentsModel>("SampleData");
更改Odata控制器
//[ODataRoutePrefix("SampleData")]
public class SampleDataController : ODataController
{
//[ODataRoute("SampleData/MyNamespace.SampleFunction(catGUIDOrText={catGUIDOrText},type={type},isAutoCompSearch={isAutoCompSearch})")]
[EnableQuery]
[HttpGet]
public IHttpActionResult SampleFunction(string catGUIDOrText, string type, string isAutoCompSearch)
{
return new List<DocumentsModel>().AsQueryable<DocumentsModel>();
}
}
更改添加odata名称空间的网址
在您的代码中,您声明了一个未绑定函数,但您调用的是绑定函数
您可以在此tutorial
中找到所需的信息答案 1 :(得分:0)
我正在尝试实现类似的目的,但是我直接使用ODataQueryOptions,所以我的控制器是这样的:
[HttpGet]
public ODataList<DTO> Get(ODataQueryOptions<POCO> options) {
using (var db = new Entities()) {
var param = options.Request.RequestUri.ParseQueryString().Get("CompanyCode");
return _oData.Query<POCO, DTO>(options, db.POCO.AsQueryable());
}
}
如果我尝试在签名中添加其他参数,则会出错,因此试图寻找一种方法来传递CompanyCode和所有OData参数,并且仍然具有所有分页/过滤/排序功能。
这对我来说就像是一种魅力-我只是在请求中添加额外的参数,例如:
api / DTO?CompanyCode = blah&$ skip = 50&$ top = 50
.NET OData东西似乎忽略了我的额外参数,并且没有问题-我只是手动解析该参数,而不是将其放入函数签名中。对我来说足够好!
答案 2 :(得分:0)
我可以通过以下方式解决此问题:-
将以下代码添加到startup.cs
gapi.load('gapi.iframes', function() {
var options = {
'url': 'https://play.google.com/work/embedded/search?token=web_token&mode=SELECT',
'where': document.getElementById('container'),
'attributes': { style: 'width: 600px; height:1000px', scrolling: 'yes'}
}
var iframe = gapi.iframes.getContext().openChild(options);
});
在控制器中
public void ConfigureServices(IServiceCollection services)
{
// your code
services.AddMvc();
services.AddOData();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// your code
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.Select().Filter().OrderBy().Expand().Count().MaxTop(50);
endpoints.MapODataRoute("api", "api", GetEdmModel());
});
}
private IEdmModel GetEdmModel()
{
var edmBuilder = new ODataConventionModelBuilder();
edmBuilder.EntitySet<Student>("Students");
var pullRequestsByProjectByContributor = edmBuilder.EntityType<Student>().Collection
.Function("GetStudents")
.ReturnsCollectionFromEntitySet<Student>("Students");
pullRequestsByProjectByContributor.Parameter<int>("id").Required();
pullRequestsByProjectByContributor.Parameter<int>("classId").Required();
return edmBuilder.GetEdmModel();
}