我写了一个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");
}
