Skip to main content
 首页 » 编程设计

c#之Refit和Web API之间如何共享服务方法URL

2024年01月13日30daizhj

我写了一个C#接口(interface),编译成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 doesn't look like a Refit interface. Make sure it has at least one method with a Refit HTTP method attribute and Refit is installed in the project.

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

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

请您参考如下方法:

如何从接口(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"); 
}