Wcf 带可选参数的OData路由

Wcf 带可选参数的OData路由,wcf,sharepoint,asp.net-web-api,odata,asp.net-web-api2,Wcf,Sharepoint,Asp.net Web Api,Odata,Asp.net Web Api2,我有一个OData(v3)Web API 2项目,它是另一个wcf Web服务的包装器。此odata连接的预期客户端是SharePoint 2013。我正在这个包装器中创建CRUD操作,并注意到当sharepoint被要求删除某些内容时,它会以以下格式发送请求:/Entity(Identity=XX),而不是我正常使用的normal/Entity(XX)。我需要能够在不破坏另一个请求的情况下处理该请求。这是我的密码: public IHttpActionResult GetSchool(

我有一个OData(v3)Web API 2项目,它是另一个wcf Web服务的包装器。此odata连接的预期客户端是SharePoint 2013。我正在这个包装器中创建CRUD操作,并注意到当sharepoint被要求删除某些内容时,它会以以下格式发送请求:/Entity(Identity=XX),而不是我正常使用的normal/Entity(XX)。我需要能够在不破坏另一个请求的情况下处理该请求。这是我的密码:

    public IHttpActionResult GetSchool([FromODataUri] int key, ODataQueryOptions<School> queryOptions)
    {
        // validate the query.
        try
        {
            queryOptions.Validate(_validationSettings);
        }
        catch (ODataException ex)
        {
            return BadRequest(ex.Message);
        }
        SchoolDataSource data = new SchoolDataSource();
        var result = data.GetByID(key);
        return Ok<School>(result);
        //return StatusCode(HttpStatusCode.NotImplemented);
    }
我得到的错误:
406如果我设置了路由属性。500如果我没有设置路由属性。除非我指定参数,否则我的服务似乎不知道如何处理该参数,但如果我指定了,所有调用都会出现406个错误。

可能不是最好的方法,但使它能够与此类一起工作:

public class SharePointRoutingConvention : EntitySetRoutingConvention
{
    public override string SelectAction(ODataPath odataPath, HttpControllerContext context,
        ILookup<string, HttpActionDescriptor> actionMap)
    {
        //Gets the entity type
        IEdmEntityType entityType = odataPath.EdmType as IEdmEntityType;

        //makes sure the format is correct
        if (odataPath.PathTemplate == "~/entityset/key")
        {
            //parses out the path segment (Identity=X)
                            KeyValuePathSegment segment = odataPath.Segments[1] as KeyValuePathSegment;

            //Gets the verb from the request header
            string actionName = context.Request.Method.ToString();

            // Add keys to route data, so they will bind to action parameters.
            KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment;

            //Checks to see if the "Identity=" part is in the url
            if (keyValueSegment.Value.Contains("Identity="))
            {
                //removes the extra text
                context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value.Replace("Identity=", "");
            }
            else
            {
                //parses it normally
                context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value;
            }

            //returns the verb
            return actionName;

        }
        // Not a match.
        return null;
    }
}

可能不是最好的方法,但使其适用于本课程:

public class SharePointRoutingConvention : EntitySetRoutingConvention
{
    public override string SelectAction(ODataPath odataPath, HttpControllerContext context,
        ILookup<string, HttpActionDescriptor> actionMap)
    {
        //Gets the entity type
        IEdmEntityType entityType = odataPath.EdmType as IEdmEntityType;

        //makes sure the format is correct
        if (odataPath.PathTemplate == "~/entityset/key")
        {
            //parses out the path segment (Identity=X)
                            KeyValuePathSegment segment = odataPath.Segments[1] as KeyValuePathSegment;

            //Gets the verb from the request header
            string actionName = context.Request.Method.ToString();

            // Add keys to route data, so they will bind to action parameters.
            KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment;

            //Checks to see if the "Identity=" part is in the url
            if (keyValueSegment.Value.Contains("Identity="))
            {
                //removes the extra text
                context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value.Replace("Identity=", "");
            }
            else
            {
                //parses it normally
                context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value;
            }

            //returns the verb
            return actionName;

        }
        // Not a match.
        return null;
    }
}
        var conventions = ODataRoutingConventions.CreateDefault();

        //adding the custom odata routing convention
        conventions.Insert(0, new SharePointRoutingConvention());



     config.Routes.MapODataRoute(
            routeName: "odata",
            routePrefix: null,//this is so that you can type the base url and get metadata back (http://localhost/) 
            model: builder.GetEdmModel(),
            pathHandler: new DefaultODataPathHandler(),
            routingConventions: conventions //this assigns the conventions to the route
            );