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

时间:2020-09-17 08:05:34

标签: c# .net asp.net-web-api controller odata

我已经编写了odata v3网络api并对其进行了调用,但会引发错误。

OData路径无效。 检测到无效的操作。 “获取”不是可以绑定到“集合([EPICOR.Models.TasksList Nullable = False])”的操作。 Microsoft.Data.OData.ODataException 在System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseAtCollection(IEdmModel模型,ODataPathSegmentE在前,IEdmType以前) System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseNextSegment(IEdmModel模型,ODataPathSegment上一个,IEdmType previousEdmType,字符串段),位于System.Web.Http.OData.Routing.DefaultODataPathHandler.Parse(IEdmModel模型,字符串) System.Web.Http.OData.Routing.ODataPathRouteConstraint.Match的odataPath)(HttpRequestMessage请求,IHttpRoute路由,String parameterName,IDictionary`2值,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 个答案:

答案 0 :(得分:0)

除非您已对其进行了自定义,否则需要遵循默认的routing conventions。在这种情况下,Get方法可能应返回一个IQueryable<TasksList>,直接从您的DbSet中查询。

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

作为一种可行的替代方法,您可以尝试使用当前代码,但将参数更改为[FromQuery] string module,以表明该参数不属于OData路由。还最好直接返回IQueryable<TasksList>而不是新的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();
    }
}