WebAPI Url.Link()返回NULL

时间:2015-02-05 10:01:33

标签: asp.net-web-api2

在我正在开发的项目中生成WebAPI超媒体链接时遇到了一些麻烦。

在扩展方法Order下面的代码段中,单个订单的OrderUpdateOrderDelete都返回Null链接。我怀疑这是因为WebAPI无法从父Orders路由解析这些内部路由。

我不确定为什么返回Null链接,因为我正在为Link方法提供有效的路由名称。

您可以从生成的JSON输出中看到Uri对象中的Null数组元素Links元素都是Order

// WebApiConfig.cs

config.Routes.MapHttpRoute(
    name: "Orders",
    routeTemplate: "api/orders",
    defaults: new { controller = "order", action = "get" },
    constraints: new { httpMethod = new HttpMethodConstraint( HttpMethod.Get ) }
);


config.Routes.MapHttpRoute(
    name: "Order",
    routeTemplate: "api/orders/{orderid}",
    defaults: new { controller = "order" },
    constraints: new { orderid = "^[0-9]+$", httpMethod = new HttpMethodConstraint( HttpMethod.Get ) }
);

config.Routes.MapHttpRoute(
    name: "OrderUpdate",
    routeTemplate: "api/orders/{orderid}",
    defaults: new { controller = "order", action = "put" },
    constraints: new { orderid = "^[0-9]+$", httpMethod = new HttpMethodConstraint( HttpMethod.Put ) }
);

// OrderController.cs

public async Task<Orders> Get()
{
    var orders = new Orders();

    orders.Links.OrderList( Url, "self" ); // returns a link OK
    orders.Links.OrderAdd( Url, "order-create" ); // returns a link OK
    foreach ( var order in await _repository.GetOrders() )
    {
        order.Links.Order( Url, "self", order.Id ); // returns NULL
        if ( !User.IsInRole( "Readonly" ) )
        {
            order.Links.OrderUpdate( Url, "order-update", order.Id ); // returns NULL
            order.Links.OrderDelete( Url, "order-delete", order.Id ); // returns NULL
        }
        orders.Order.Add( order );
    }
    return orders;
}

// LinkGenerationExtensions.cs

public static void Order( this List<Link> @this, UrlHelper url, string rel, int orderId )
{
    @this.Add( new Link { Rel = rel, Uri = url.OrderUri( orderId ) } );
}

public static string OrderUri( this UrlHelper url, int orderId )
{
    return url.Link( "Order", new { id = orderId } );
}

public static void OrderList( this List<Link> @this, UrlHelper url, string rel )
{
    @this.Add( new Link { Rel = rel, Uri = url.OrderListUri() } );
}

public static string OrderListUri( this UrlHelper url )
{
    return url.Link( "Orders", new { } );
}

public static void OrderUpdate( this List<Link> @this, UrlHelper url, string rel, int orderId )
{
    @this.Add( new Link { Rel = rel, Uri = url.OrderUpdateUri( orderId ) } );
}

public static string OrderUpdateUri( this UrlHelper url, int orderId )
{
    return url.Link( "OrderUpdate", new { id = orderId } );
}

以上代码生成以下JSON响应:

{
    "Order": [
        {
            "Id": 4,
            "OrderRef": 123456,
            "OrderDate": "2015-02-04T10:28:00",
            "CustomerName": "ACME Construction Ltd",
            "OrderedBy": "PA",
            "InstallationDate": "2015-06-15T00:00:00",
            "Address": "900 ACME Street",
            "Postcode": "SW2 7AX",
            "Town": "London",
            "OrderNumber": "6508756191",
            "Value": 525,
            "Invoice": 0,
            "Links": [
                {
                    "Rel": "self",
                    "Uri": null
                },
                {
                    "Rel": "order-update",
                    "Uri": null
                },
                {
                    "Rel": "order-delete",
                    "Uri": null
                }
            ]
        }
    ],
    "Links": [
        {
            "Rel": "self",
            "Uri": "http://localhost/Site/api/orders"
        },
        {
            "Rel": "order-create",
            "Uri": "http://localhost/Site/api/orders/add"
        }
    ]
}

2 个答案:

答案 0 :(得分:3)

在发现路由值中的参数名称必须与其定义的路径中的参数名称匹配后,我已经回答了我自己的问题。

id替换orderid完成了这项工作。

以下是更新后的代码:

// LinkGenerationExtensions.cs

public static void Order( this List<Link> @this, UrlHelper url, string rel, int orderId )
{
    @this.Add( new Link { Rel = rel, Uri = url.OrderUri( orderId ) } );
}

public static string OrderUri( this UrlHelper url, int orderId )
{
    return url.Link( "Order", new { orderid = orderId } );
}

public static void OrderList( this List<Link> @this, UrlHelper url, string rel )
{
    @this.Add( new Link { Rel = rel, Uri = url.OrderListUri() } );
}

public static string OrderListUri( this UrlHelper url )
{
    return url.Link( "Orders", new { } );
}

public static void OrderUpdate( this List<Link> @this, UrlHelper url, string rel, int orderId )
{
    @this.Add( new Link { Rel = rel, Uri = url.OrderUpdateUri( orderId ) } );
}

public static string OrderUpdateUri( this UrlHelper url, int orderId )
{
    return url.Link( "OrderUpdate", new { orderid = orderId } );
}

public static void OrderDelete( this List<Link> @this, UrlHelper url, string rel, int orderId )
{
    @this.Add( new Link { Rel = rel, Uri = url.OrderDeleteUri( orderId ) } );
}

public static string OrderDeleteUri( this UrlHelper url, int orderId )
{
    return url.Link( "OrderDelete", new { orderid = orderId } );
}

答案 1 :(得分:0)

在 VS2019 上有这个问题。当我将项目升级到 .NET5 并将所有 Microsoft nuget 包升级到 v5.x 时解决了。