如何从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);
}
}
我的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 model
“Newtonsoft.Json.JsonSerializationException:无法反序列化JSON 数组“(即[1,2,3])到'ProductDetails.Models.ProductItems'类型。 反序列化类型必须是数组或实现集合 界面如IEnumerable,ICollection或IList。强制JSON数组 要反序列化,请将JsonArrayAttribute添加到该类型中。第1行, 位置1.“
任何人都可以帮我这样做......或者建议我使用其他最好的方法或纠正我,如果我在任何地方做错了......我必须在我的视图中显示返回的数据......数据应该是回到我的控制器
答案 0 :(得分:15)
由于异常状态“无法反序列化 JSON数组...”,您在接收方方面遇到问题,例如反序列化不在您的带有序列化的Web api方法中。
您的问题是您尝试反序列化为错误的类型,因为您的web api方法如下所示:
public IEnumerable<ProductItems> GetProductDetail(int ID)
因此它会返回IEnumerable<ProductItems>
(例如ProductItems
的数组),但在您的控制器操作中,您尝试通过调用将响应反序列化为一个 ProductItems
ReadAsAsync<ProductItems>()
因此,将您的ReadAsAsync
更改为反序列化为数组ProductItems
,它应该有效:
var model = client
.GetAsync(productDetailUrl)
.Result
.Content.ReadAsAsync<ProductItems[]>().Result;
答案 1 :(得分:8)
当您的ASP.NET网站与Web API控制器一起托管时,您可以将Web API称为普通类方法,以避免与HTTP请求相关的任何延迟。
问题不在Web 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请求和序列化/反序列化的东西,只需将你的方法称为普通的类方法。 / p>