2012-10-05 82 views
23

我如何可以调用从MVC动作控制器方法的网页API方法。这就是我想,这是我的控制器方法:如何从MVC控制器操作方法调用WebApi方法?

public ActionResult ProductDetail(long id) 
{ 
    using (var client = new HttpClient()) 
    { 
     var productDetailUrl = Url.RouteUrl(
      "DefaultApi", 
      new { httproute = "", controller = "ProductDetails", id = id }, 
      Request.Url.Scheme 
     ); 
     var model = client 
        .GetAsync(productDetailUrl) 
        .Result 
        .Content.ReadAsAsync<ProductItems>().Result; 

     return View(model); 
    } 
} 

我的Web API方法:

private ProductEntities products = new ProductEntities(); 

public IEnumerable<ProductItems> GetProductDetail(int ID) 
{    
    var produc= products.ExecuteStoreQuery<ProductItems>(
      "GetProductDetail @ProductID ", 
      new SqlParameter("@ProductID", ID)); 

    return produc; 
} 

当我这样做,我得到我的MVC操作方法错误@ VAR模型返回数据说

后 “Newtonsoft.Json.JsonSerializationException:不能反序列化JSON 阵列”(即[1,2,3])转换成类型 'ProductDetails.Models.ProductItems'。 反序列化类型必须是一个数组或实现的集合 接口等的IEnumerable,ICollection的或IList的。要强制JSON阵列 反序列化添加到JsonArrayAttribute的类型。 1号线, 位置1”

任何一个可以帮助我做这个...还是建议我任何其他最佳方法或纠正我,如果我做的任何地方错了......我已经展示返回在我看来,数据......数据应该返回到我的控制器

+0

我会用ProductItem代替ProductItems的类/对象名称。并且使用“var”这个词阻碍了这些问题的解决,恕我直言。 – granadaCoder

回答

15

作为例外状态“不能反序列化 JSON数组...”你有一个接收端的问题,例如反序列化不在你的web API方法与序列化。

和你的问题是,你试图反序列化到了错误的类型,因为您的Web API方法是这样的:

所以它返回IEnumerable<ProductItems>(例如ProductItems数组),但在你的控制器动作,您试试反序列化响应为一个ProductItems与呼叫ReadAsAsync<ProductItems>()

因此改变你的ReadAsAsync反序列化到一个数组ProductItems,它应该工作:

var model = client 
       .GetAsync(productDetailUrl) 
       .Result 
       .Content.ReadAsAsync<ProductItems[]>().Result; 
+0

我geting异常话说传递到字典的模型产品类型“ProductDetails.Models.ProductItems []”,但这个字典需要类型“ProductDetails.Models.ProductItems”的典范项目。 – SoftwareNerd

+0

现在的问题是你的看法'ProductDetail.cshtml',你有我想'@model ProductDetails.Models.ProductItems'。在您的控制器';如果您的WebAPI方法反正只返回一个'ProductItems'你可以写'返回查看([0]模型)。或更改您的WebAPI方法只返回的'ProductItems'代替'的IEnumerable '... – nemesv

8

当你的ASP.NET网站是一起的Web API控制器主机,那么你可以调用Web API为普通类方法来避免与HTTP任何延误请求。

而且问题并不在网络API调用。问题是结果反序列化,即来自ExecuteStoreQuery,请确保您有序列化科尔在它里面。为了确保,您可以简单地尝试将此方法结果转换为列表,然后返回并从web api方法序列化列表返回,然后本地化问题。

UPD:所以,问题的根本是什么ExecuteStoreQuery方法返回。它返回ObjectResult。它实际上实现了IEnumerable,但是它从EF返回并且在某些情况下有Json解串器无法解决的对象之间的循环依赖关系。

要解决问题,只需将显式的ObjectResult转换为清单:

public IEnumerable<ProductItems> GetProductDetail(int ID) 
{    
    var products = products.ExecuteStoreQuery<ProductItems>(
       "GetProductDetail @ProductID ",  
       new SqlParameter("@ProductID", ID)); 
    return products.ToList<ProductItems>(); 
} 

当问题实际上是在你的对象来自EF的收藏周期的依赖,你可以在Json.NET

关掉它

而且还要检查你的客户端反序列化:

var model = client.GetAsync(productDetailUrl).Result 
       .Content.ReadAsAsync<List<ProductItems>>().Result; 

但是,当您在一个项目中托管ASP.NET MVC站点和ASP.NET Web API时,则不需要使用HTTP请求和序列化/反序列化所有这些东西,只需将您的方法作为普通的类方法调用即可。

+0

你能帮我做到这一点吗 – SoftwareNerd

+0

@Anil刚刚改变,尝试一下 – Regfor

+0

+1指出问题的两个问题,也指出你可以实例化控制器的一个实例,只是调用方法 –

相关问题