本文介绍了WebAPI Url.Link()返回NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我正在处理的项目中生成WebAPI超媒体链接时遇到了一些麻烦.

I am having some trouble in generating WebAPI hypermedia links in a project I am working on.

在单独方法的扩展方法OrderOrderUpdateOrderDelete下方的代码段中,所有返回的都是Null链接.我怀疑这是因为WebAPI无法从父Orders路由解析这些内部路由.

In the code snippet below the extension methods Order, OrderUpdate and OrderDelete for individual orders are all returning Null links. I suspect this is because WebAPI is unable to resolve these inner routes from the parent Orders route.

我不确定为什么要向Link方法提供有效的路由名称时返回Null链接.

I am not certain why Null links are being returned as I am supplying valid route names to the Link method.

从产生的JSON输出中可以看到,Uri元素内的Links数组元素的Uri元素都是Null.

You can see from the resulting JSON output that the Uri elements are all Null for the Links array element within the Order object.

// 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响应:

The above code generates the following JSON response:

{
    "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"
        }
    ]
}

推荐答案

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

I've answered my own question after discovering that the parameter names in the route values must match those of their defined routes.

orderid替换id即可完成工作.

这是更新的代码:

// 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 } );
}

这篇关于WebAPI Url.Link()返回NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 18:49