2015-04-03 158 views
1

我有一个动作要搜索的人的控制,它会返回anonymouse的列表:无法将IEnumerable的匿名类型转换为IEnumerable <dynamic>?

[UnitOfWork] 
[HttpGet, Route("api/Search/People")] 
public virtual IHttpActionResult GetResult(string keyword) 
{ 
    // ... 
    var result = peopleList.Select(x => new 
    { 
     PersonId = x.Id.Value, 
     EmploymentNumber = x.EmploymentNumber, 
     FirstName = x.Name.FirstName, 
     LastName = x.Name.LastName, 
     Email = x.Email 
    }); 
    return Ok(result); 
} 

下面是该方法的测试案例:

[Test] 
public void ShouldSearchPeople() 
{ 
    // Mocks... 
    var target = new PeopleSearchController(searchRepository, personRepository, new FakePermissionProvider()); 
    // Error here 
    var result = (OkNegotiatedContentResult<IEnumerable<dynamic>>)target.GetResult("Ashley"); 
    Assert.NotNull(peopleList); 
    // Other assert... 
} 

然后我得到如下错误:

System.InvalidCastException: Unable to cast object of type 
'System.Web.Http.Results.OkNegotiatedContentResult`1[System.Collections.Generic.IEnumerable`1[<>f__AnonymousType1e`5[System.String,System.String,System.String,System.Guid,System.String]]]' 
to type 
'System.Web.Http.Results.OkNegotiatedContentResult`1[System.Collections.Generic.IEnumerable`1[System.Object]]'. 

看起来像IEnumerable类或单匿名可以这样转换,但IEnumerable与匿名不起作用。

我该怎么做这样的转换?谢谢。

+0

也许'var result = target.GetResult(“Ashley”)为OkNegotiatedContentResult >;'在你的测试方法中适合你......? – stefankmitph 2015-04-03 06:53:13

+0

@stefankmitph'result'将始终为空。 – 2015-04-03 07:07:39

回答

1

您不是将一些动态转换为其他参数化类型的动态但具体的参数化类型。你的代码遭受的问题称为协变和逆变。不幸的是,class不支持协变/逆变(class总是不变)。 可能的解决方法:

var result = ((dynamic)target).GetResult("Ashley"); 
//result is of type OkNegotiatedContentResult<...> 
var content = (IEnumerable<dynamic>)result.Content; 

由于IEnumerable是协变,即投将工作。

更多关于协方差和逆变on MSDN.

+0

谢谢,这个作品:-) – xinfli 2015-04-21 05:07:49

0

您可以用

IHttpActionResult result = target.GetResult("Ashley"); 
IEnumerable<dynamic> content = (IEnumerable<dynamic>)((dynamic)result).Content; 

您使用dynamic使用属性.Content尝试将返回IEnumerable<T>,然后用协方差丢给IEnumerable<object>/IEnumerable<dynamic> (它们相当于CLR级别...... dynamic是由编译器完成的一项神奇功能)

请注意,如果OkNegotiatedContentResultT是一个值类型,那么这将不起作用,但在您的情况下它是引用类型,所以没有问题。

+1

我也有类似的问题。您的解决方案可用于测试返回结果。但是如果我想测试控制器是否返回'''OkNegotiationResult'''或者不呢? – 2015-05-20 02:49:37

+0

这应该工作:Assert.AreEqual(typeof(OkNegotiatedContentResult <>),result.GetType()。GetGenericTypeDefinition()); – 2016-10-21 14:25:18

相关问题