在我正在开发的项目中生成WebAPI超媒体链接时遇到了一些麻烦。
在扩展方法Order
下面的代码段中,单个订单的OrderUpdate
和OrderDelete
都返回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"
}
]
}
答案 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 时解决了。