我有一个相当琐碎的WebAPI,它从另一个Web服务返回一个结果。
[HttpGet]
public List<MyList> GetResults()
{
var result = Webservice.GetResults().ToList();
return result;
}
以上内容返回了Webservice调用中的所有值,并且具有相同的prop名称。
我的问题是,如何从WebService获取数据,用我自己的数据扩展某些数据,更改一些属性名称,然后返回该新结果?不使用Automapper或类似组件?
[HttpGet]
public List<MyList> GetResults()
{
var result = Webservice.GetResults().ToList();
foreach (res in results) {
var newTitle = result.Title + " - my custom value";
var newData = "01/01/2019";
var newLink = GetCustomLink(result);
}
return newValues;
}
答案 0 :(得分:1)
您所说的是许多应用程序/ API中的常见情况。
如果您从工程学的角度看问题,那么我会这样做:
创建一个模型,该模型反映从外部API返回的数据。我们称其为ApiSourceDataDto。
您的API希望获取该数据并以某种方式对其进行转换并返回一种新格式,让我们将其称为MyApiDataDto。
创建一个额外的层,现在让我们说一个新的类库,您可以在其中添加从ApiSourceDataDto到ApiSourceDataDto的转换层。比方说,我们有一个叫TranslationLayer类。
使用功能性方法从控制器中调用此类。
我的意思是,您的翻译层不会对外部API有所了解,只知道它将接收某种特定格式的数据,它将对其进行转换并返回结果,仅此而已。这使测试变得非常容易,因为您可以随意添加数据并测试发生的事情而无需模拟任何东西。
类似这样的东西:
[HttpGet]
public List<MyApiDataDto> GetResults()
{
List<ApiSourceDataDto> externalApiResults = Webservice.GetResults().ToList();
List<MyApiDataDto> myResults = new TranslationLayer().Translate(externalApiResults)
return myResults;
}
在一个单独的类库中,假设您有类似的内容:
public class TranslationLayer{
public List<MyApiDataDto> Translate(List<ApiSourceDataDto> input)
{
//apply your business logic and transformations here.
//return the transformed data.
}
}
现在你有SOC(关注点分离),你可以开始做您身边的翻译方法(S)一些适当的测试。您的控制器很简单,并且没有应有的太多代码。您想要瘦而不胖的控制器。
当然,这只是给您一个初步的想法。如果您有很多翻译方法,则需要以一种对您的应用程序有意义的方式进行分离。不要将一切分开,控制器之外的任何业务逻辑也应保持分开。
当然,您还将添加一些代码来处理由外部API返回的错误。
答案 1 :(得分:1)
您还可以使用LINQ方法,例如:
[HttpGet]
public List<MyList> GetResults()
{
var result = Webservice.GetResults().ToList();
return results.Select(xx=> new MyList{ // ,-- HERE YOU CAN ALSO USE A GENERIC NEW
newTitle = result.Title + " - my custom value",
newData = "01/01/2019",
newLink = GetCustomLink(result)
}).ToList()
}
...然后..如果此映射是循环的..您可以创建扩展方法来执行以下操作:
public static MyList ToMyCustomType(this YOURWSTYPE input){
return new MyList{
newTitle = result.Title + " - my custom value",
newData = "01/01/2019",
newLink = GetCustomLink(result)
}
}
public static List<MyList> ToMyCustomType(this IEnumerable<YOURWSTYPE> input){
return input.Select(xx=> xx.ToMyCustomType()).ToList();
}
...然后您可以像这样使用它:
[HttpGet]
public List<MyList> GetResults()
{
return Webservice.GetResults().ToList().ToMyCustomType();
}
希望对您有帮助!
答案 2 :(得分:0)
您可以使用Linq的Select扩展名来创建自定义结果。
var result = Webservice.GetResults().ToList();
return result.Select( s => new MyList{
newTitle = result.Title + " - my custom value",
newData = "01/01/2019",
newLink = GetCustomLink(result)
});