404方法未找到odata

时间:2019-10-07 10:33:06

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

我的网址如下:

https://localhost:44351/odata/PublicInsuranceOrder('To New1')

为此,我在工作正常的dotnet核心控制器下创建了

[ODataRoutePrefix("PublicInsuranceOrder")]
    public class PublicInsuranceOrderController : ODataController
    {
        [HttpGet]
        [EnableQuery]
        [SwaggerResponse("200", typeof(PublicInsuranceOrder))]
        [SwaggerResponse("404", typeof(void))]
        [ODataRoute("({insuranceOrderName})")]

        public ActionResult<PublicInsuranceOrder> Get([FromODataUri] string insuranceOrderName)
        {
           //this works 
        }

现在我有一个具有以下路由的API: https://localhost:44351/odata/PublicInsuranceOrder('To New1')/ Claim('1')

我已经尝试了以下不起作用的控制器方法

[HttpGet]
        [EnableQuery]
        [SwaggerResponse("200", typeof(PublicInsuranceOrder))]
        [SwaggerResponse("404", typeof(void))]
        [ODataRoute("({insuranceOrderName})/Claim({id})")]

        public ActionResult<PublicInsuranceOrder> Get([FromODataUri] string insuranceOrderName, string id)
        {
            //Not working
        }

我的startup.cs是这样的:

    public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
          .SetBasePath(env.ContentRootPath)
          .AddEnvironmentVariables();
        builder.AddJsonFile(env.IsDevelopment() ? "appsettings.Development.json" : "appsettings.json", false, false);
        Configuration = builder.Build();

    }


    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.ConfigureServices(Configuration, typeof(WomBCModule), "Wom");
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); // _2);
        services.AddTransient<PublicWorkOrder>();
        services.AddOData();

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.Configure(env, true);
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseMvc(routeBuilder =>
        {
            routeBuilder.EnableDependencyInjection();

      //            expand refs / which attr / query / count 
      //routeBuilder.Expand().Select().Filter().Count()
      routeBuilder.Select().Expand().Filter().OrderBy().MaxTop(100).Count();
      //routeBuilder.MapODataServiceRoute("odata", "odata/v1", GetEdmModel());
      //routeBuilder.MapODataServiceRoute("odata", "odata", GetEdmModel());
      // Create the default collection of built-in conventions.

      var conventions = ODataRoutingConventions.CreateDefault();

      // Insert the custom convention at the start of the collection.
      conventions.Insert(0, new NavigationIndexRoutingConvention());

            routeBuilder.MapODataServiceRoute("odata", "odata", GetEdmModel(), new DefaultODataPathHandler(), conventions);
        });
    }
    private static IEdmModel GetEdmModel()
    {
        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<PublicWorkOrder>("PublicInsuranceOrder");
        builder.EntitySet<Claim>("Claim");
        return builder.GetEdmModel();
    }

}

我创建了一个NavigationIndexRoutingConvention,如下所示:

公共局部类NavigationIndexRoutingConvention:IODataRoutingConvention {

IEnumerable<ControllerActionDescriptor> IODataRoutingConvention.SelectAction(RouteContext routeContext)
{

    // Get a IActionDescriptorCollectionProvider from the global service provider
    IActionDescriptorCollectionProvider actionCollectionProvider =
        routeContext.HttpContext.RequestServices.GetRequiredService<IActionDescriptorCollectionProvider>();
    Contract.Assert(actionCollectionProvider != null);

    // Get OData path from HttpContext
    Microsoft.AspNet.OData.Routing.ODataPath odataPath = routeContext.HttpContext.ODataFeature().Path;
    HttpRequest request = routeContext.HttpContext.Request;

    // Handle this type of GET requests: /odata/Orders(1)/OrderRows(1)
    if (request.Method == "GET" && odataPath.PathTemplate.Equals("~/entityset/key/navigation/key"))
    {
        // Find correct controller
        string controllerName = odataPath.Segments[3].Identifier;
        IEnumerable<ControllerActionDescriptor> actionDescriptors = actionCollectionProvider
            .ActionDescriptors.Items.OfType<ControllerActionDescriptor>()
            .Where(c => c.ControllerName == controllerName);

        if (actionDescriptors != null)
        {
            // Find correct action
            string actionName = "Get";
            var matchingActions = actionDescriptors
                .Where(c => String.Equals(c.ActionName, actionName, StringComparison.OrdinalIgnoreCase) && c.Parameters.Count == 2)
                .ToList();
            if (matchingActions.Count > 0)
            {
                // Set route data values
                var keyValueSegment = odataPath.Segments[3] as KeySegment;
                var keyValueSegmentKeys = keyValueSegment?.Keys?.FirstOrDefault();
                routeContext.RouteData.Values[ODataRouteConstants.Key] = keyValueSegmentKeys?.Value;

                var relatedKeyValueSegment = odataPath.Segments[1] as KeySegment;
                var relatedKeyValueSegmentKeys = relatedKeyValueSegment?.Keys?.FirstOrDefault();
                routeContext.RouteData.Values[ODataRouteConstants.RelatedKey] = relatedKeyValueSegmentKeys?.Value;

                // Return correct action
                return matchingActions;
            }
        }
    }

    // Not a match
    return null;

}

}

我遇到以下错误: 404未找到 我能知道我在做什么错

0 个答案:

没有答案