为啥调用 webapi 方法会引发错误,即路径无效?

Posted

技术标签:

【中文标题】为啥调用 webapi 方法会引发错误,即路径无效?【英文标题】:Why does calling an webapi method throw error i.e. Invalid path?为什么调用 webapi 方法会引发错误,即路径无效? 【发布时间】:2020-09-17 08:05:34 【问题描述】:

我编写了一个 odata v3 web api 并调用它,但它会引发错误。

OData 路径无效。 检测到无效操作。 'Get' 不是可以绑定到 'Collection([EPICOR.Models.TasksList Nullable=False])' 的操作。 Microsoft.Data.OData.ODataException 在 System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseAtEntityCollection(IEdmModel 模型,ODataPathSegment 以前,IEdmType previousEdmType,String 段)在 System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseAtCollection(IEdmModel 模型,ODataPathSegment 以前,IEdmType previousEdmType , 字符串段)在 System.Web.Http.OData.Routing.DefaultODataPathHandler.Parse 的 System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseNextSegment(IEdmModel 模型,ODataPathSegment 上一个,IEdmType 上一个EdmType,字符串段)的 System.Web.Http.OData.Routing.DefaultODataPathHandler.Parse(IEdmModel 模型,字符串odataPath) 在 System.Web.Http.OData.Routing.ODataPathRouteConstraint.Match(HttpRequestMessage request, IHttpRoute route, String parameterName, IDictionary`2 values, HttpRouteDirection routeDirection)

我的代码:

 public class TasksPlanController : ODataController
    
        private static ODataValidationSettings _validationSettings = new ODataValidationSettings();

        // GET: odata/TasksPlan
        [EnableQuery]
        public List<Models.TasksList> Get(string module)
        
            //var query= "";

            using (var context = new TasksPlanEntities())
            
                List<Models.TasksList> ts = new List<Models.TasksList>();

                if (module.ToLower() == "PEMS".ToLower())
                
                    var query = from PIRTL in context.PIRTaskLists
                                select PIRTL;

                    ts = query.Select(x => new Models.TasksList  PIRCode = x.PIRCode, FunctionalLocation = x.FunctionalLocation, TaskName = x.TaskName, OperationCode = x.OperationCode, OperationNo = x.OperationNo, StartDate = x.StartDate, LastInspDate = x.LastInspDate, NextInspDate = x.NextInspDate ).ToList<Models.TasksList>();
                
    
                return ts;
            
        

webapiconfig.cs

 public static class WebApiConfig
    
        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 
            //);

            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<TasksList>("TasksPlan");
            config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());

            //var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
            //config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
        

调用基于 odata 的 web api 方法是否有效?

【问题讨论】:

【参考方案1】:

您需要遵循默认的routing conventions,除非您已自定义它们。在这种情况下,Get 方法可能会返回一个 IQueryable&lt;TasksList&gt;,直接从您的 DbSet 查询。

我可以看到您正在执行一些自定义逻辑来确定您的返回列表是否实际上是从数据库中填充的,在这种情况下,我建议您将此逻辑实现为自定义 OData 函数 (example here),您可以在其中定义定义查询逻辑的自定义参数。

作为一种可行的替代方法,您可以尝试使用当前代码,但将参数更改为 [FromQuery] string module 以表明该参数不是 OData 路由的一部分。最好直接返回 IQueryable&lt;TasksList&gt; 而不是新的 List 对象,因为可查询对象被转发到 EnableQuery 属性过滤器。

类似这样的:

// GET: odata/TasksPlan?module=PEMS
[EnableQuery]
public IQueryable<Models.TasksList> Get([FromQuery] string module)

    using (var context = new TasksPlanEntities())
    
        if (module.ToLower() == "PEMS".ToLower())
        
            var query = from PIRTL in context.PIRTaskLists
                        select PIRTL;

            return query.Select(x => new Models.TasksList  PIRCode = x.PIRCode, FunctionalLocation = x.FunctionalLocation, TaskName = x.TaskName, OperationCode = x.OperationCode, OperationNo = x.OperationNo, StartDate = x.StartDate, LastInspDate = x.LastInspDate, NextInspDate = x.NextInspDate );
        

        return Enumerable.Empty<Models.TasksList>().AsQueryable();
    

【讨论】:

以上是关于为啥调用 webapi 方法会引发错误,即路径无效?的主要内容,如果未能解决你的问题,请参考以下文章

在单元测试 setUp 方法中调用路径辅助函数会引发错误

为啥HTML调用JS无效

为啥“引发错误”有效,而“断言”无效?

html怎么调用外部css?为啥我用link无效?

带有网络路径的 FilePathResult 引发 COMException(句柄无效)

为啥我在函数内部调用时会收到“错误:无效的挂钩调用”?