如何从MVC Controller Action Method调用WebApi方法?

Sof*_*erd 24 json json.net asp.net-mvc-4 asp.net-web-api

如何从MVC动作控制器方法调用Web API方法.这是我正在尝试的,这是我的控制器方法:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的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;
}
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我在返回数据后,在我的MVC操作方法中收到错误@ var model

"Newtonsoft.Json.JsonSerializationException:无法将JSON数组反序列化"(即[1,2,3])为"ProductDetails.Models.ProductItems"类型.反序列化类型必须是数组或实现集合接口,如IEnumerable,ICollection或IList.要强制JSON数组反序列化,请将JsonArrayAttribute添加到该类型.第1行,第1位."

任何人都可以帮我这样做...或者建议我任何其他最好的方法或纠正我,如果我在任何地方做错了...我必须在我的视图中显示返回的数据...数据应该返回给我调节器

nem*_*esv 15

由于异常状态"无法反序列化 JSON数组...",您在接收器端遇到问题,例如反序列化不在您的带有序列化的Web api方法中.

您的问题是您尝试反序列化为错误的类型,因为您的web api方法如下所示:

public IEnumerable<ProductItems> GetProductDetail(int ID)
Run Code Online (Sandbox Code Playgroud)

所以它返回IEnumerable<ProductItems>(例如一个数组ProductItems),但在你的控制器操作中,你试图将响应反序列化为一个 ProductItems调用ReadAsAsync<ProductItems>()

所以改变你ReadAsAsync的反序列化成一个数组ProductItems,它应该工作:

var model = client
               .GetAsync(productDetailUrl)
               .Result
               .Content.ReadAsAsync<ProductItems[]>().Result;
Run Code Online (Sandbox Code Playgroud)


Reg*_*for 8

当您的ASP.NET网站与Web API控制器一起托管时,您可以将Web API称为普通类方法,以避免与HTTP请求相关的任何延迟.

问题不在Web API调用中.问题在于结果反序列化,来自ExecuteStoreQuery,确保你有可序列化的集合.为了确保,您可以在返回之前尝试将此方法结果转换为列表,并从web api方法可序列化列表返回,然后本地化问题.

UPD:问题的根源在于ExecuteStoreQuery方法返回的内容.它返回ObjectResult.它实际上实现了IEnumerable,但它是从EF返回的,在某些情况下,对象之间存在例如循环依赖关系,Json反序列化器无法解析.

要解决问题,只需将ObjectResult显式转换为例如List:

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

当问题实际上是来自EF的对象集合中的循环依赖性时,您可以在Json.NET中将其关闭

并检查您的客户端反序列化:

var model = client.GetAsync(productDetailUrl).Result
                .Content.ReadAsAsync<List<ProductItems>>().Result;
Run Code Online (Sandbox Code Playgroud)

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