3

我编写了一个 C# 接口并将其编译为 Contract.dll。Contract.dll 由 ASP.NET MVC 网站(本场景中的客户端)和 ASP.NET Web API 服务引用。

我在网站上使用 Refit 来调用服务。我尝试在 Refit 的 Get 属性和 Web API 的 HttpGet 属性中使用 Contract.dll 中的常量来指示服务方法 URL。这将允许我在一个地方指定 URL 并让客户端和服务引用它。

客户

public static class WidgetServiceUrls
{
    public const string ListByName = "/widget/list/{Name}";
}



public interface IWidgetService
{
    // Refit requires a string literal URL, not a constant.  Ensure the implementing service uses the same URL.
    [Get(WidgetServiceUrls.ListByName)]
    Task<List<Widget>> List(string Name);
}

服务

// TODO: Determine how to eliminate duplicate URL string in service controller action and interface method.
[HttpGet(WidgetServiceUrls.ListByName)]
public async Task<List<Widget>> List(string Name)

Refit 在调用 RestService.For(httpClient) 时抛出异常:

IWidgetService 看起来不像 Refit 接口。确保它至少有一个带有 Refit HTTP 方法属性的方法,并且在项目中安装了 Refit。

显然,Refit 不理解 Get 属性中的常量。如果我在两个地方都使用字符串文字,则代码将正确执行。但是,现在我在两个地方重复 URL 违反了DRY原则。

如何在 Contract.dll 中注释接口,以便 Refit 客户端和 Web API 服务方法使用相同的 URL?

4

1 回答 1

-1

从 interface 属性中获取 URL 怎么样?

public interface IWidgetService
{
    [Get("/widget/list/{Name}")]
    Task<List<Widget>> List(string Name);
}

private string GetUrl()
{
    MethodInfo method = typeof(IWidgetService).GetMethod("List");
    object[] attributes = method.GetCustomAttributes(true);
    foreach (var attr in attributes)
    {
        GetAttribute attribute = attr as GetAttribute;
        if (attribute != null)
        {
            return attribute.Path;
        }
    }

    throw new Exception("Unable to get API URL");
}
于 2018-07-24T15:59:28.973 回答