json 如何从 MVC 控制器操作方法调用 WebApi 方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12741052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can i call a WebApi method from MVC Controller Action Method?
提问by SoftwareNerd
How can I call a Web API method from an MVC controller action method?
如何从 MVC 控制器操作方法调用 Web API 方法?
This is what I am trying, this is my controller method:
这就是我正在尝试的,这是我的控制器方法:
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);
}
}
My Web API method:
我的 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;
}
When I am doing this I am getting an error @ var modelin my MVC action method after returning the data, saying:
当我这样做时var model,我在返回数据后在我的 MVC 操作方法中收到一个错误 @ ,说:
"
Newtonsoft.Json.JsonSerializationException: Cannot deserialize JSON array "(i.e.[1,2,3]) into type 'ProductDetails.Models.ProductItems'. The deserialized type must be an array or implement a collection interface likeIEnumerable,ICollectionorIList. To force JSON arrays to deserialize add theJsonArrayAttributeto the type. Line 1, position 1."
“
Newtonsoft.Json.JsonSerializationException:无法将 JSON 数组”(即[1,2,3])反序列化为类型“ProductDetails.Models.ProductItems”。反序列化类型必须是一个数组或实现一个集合接口,如IEnumerable,ICollection或IList。要强制 JSON 数组反序列化,JsonArrayAttribute请在类型中添加。第 1 行,位置 1。”
Can anyone help me do this, suggest another better method, or correct me if I am doing it wrong anywhere? I have to show the returned data in my view, the data should be returned to my controller.
任何人都可以帮助我做到这一点,建议另一种更好的方法,或者如果我在任何地方做错了,请纠正我?我必须在我的视图中显示返回的数据,数据应该返回给我的控制器。
采纳答案by nemesv
As the exception states "Cannot deserializeJSON array ..." you have a problem on the receiver side e.g with the deserialization not in your web api method with the serialization.
由于异常状态“无法反序列化JSON 数组......”,您在接收方方面遇到了问题,例如反序列化不在您的 web api 方法中进行序列化。
And your problem is that you try to deserialize into the wrong type because your web api method looks like:
您的问题是您尝试反序列化为错误的类型,因为您的 web api 方法如下所示:
public IEnumerable<ProductItems> GetProductDetail(int ID)
So it returns IEnumerable<ProductItems>(e.g. an array of ProductItems) but in your controller action you try to deserialize the response into oneProductItemswith the call ReadAsAsync<ProductItems>()
所以它返回IEnumerable<ProductItems>(例如一个数组ProductItems),但在你的控制器动作中,你尝试通过调用将响应反序列化为一个ProductItemsReadAsAsync<ProductItems>()
So change your ReadAsAsyncto deserialize into an array ProductItemsand it should work:
因此,将您ReadAsAsync的反序列化更改为数组ProductItems,它应该可以工作:
var model = client
.GetAsync(productDetailUrl)
.Result
.Content.ReadAsAsync<ProductItems[]>().Result;
回答by Regfor
When your ASP.NET web site is hosting together with Web API controller then you can call Web API as ordinary class method to avoid any delays related to HTTP request.
当您的 ASP.NET 网站与 Web API 控制器一起托管时,您可以将 Web API 作为普通类方法调用,以避免与 HTTP 请求相关的任何延迟。
And problem is not in Web API call. Problem is in result deserialization, that comes from ExecuteStoreQuery, make sure you have serializable collection in it. To make sure, you can simply try to convert this method result to list before return and return from web api method serializable list, then localize problem.
问题不在于 Web API 调用。问题在于来自 ExecuteStoreQuery 的结果反序列化,请确保其中包含可序列化的集合。为了确保,您可以简单地尝试在返回之前将此方法结果转换为列表,并从 web api 方法可序列化列表返回,然后本地化问题。
UPD: So, root of problem is in what ExecuteStoreQuerymethod returns. It returns ObjectResult. It actually implements IEnumerable, but it's returned from EF and in some cases there are e.g. cyclic dependencies between objects, that Json deserialzers couldn't resolve.
UPD:所以,问题的根源在于ExecuteStoreQuery方法返回的内容。它返回ObjectResult。它实际上实现了 IEnumerable,但它是从 EF 返回的,并且在某些情况下,对象之间存在循环依赖关系,而 Json 反序列化器无法解决这些问题。
To resolve problem simply convert explicitly ObjectResult to e.g. List:
要解决问题,只需将 ObjectResult 显式转换为例如 List:
public IEnumerable<ProductItems> GetProductDetail(int ID)
{
var products = products.ExecuteStoreQuery<ProductItems>(
"GetProductDetail @ProductID ",
new SqlParameter("@ProductID", ID));
return products.ToList<ProductItems>();
}
When problem is actually with cycle dependencies in collections of your objects that come from EF, you can switch it off in Json.NET
当问题实际上是来自 EF 的对象集合中的循环依赖项时,您可以在 Json.NET 中将其关闭
And also check your client side deserialization:
并检查您的客户端反序列化:
var model = client.GetAsync(productDetailUrl).Result
.Content.ReadAsAsync<List<ProductItems>>().Result;
But when you are hosting your ASP.NET MVC site and ASP.NET Web API in one project, then you do not need all this stuff with HTTP request and serialization/deserialization, just call your method as ordinary class method.
但是,当您在一个项目中托管 ASP.NET MVC 站点和 ASP.NET Web API 时,您不需要所有这些带有 HTTP 请求和序列化/反序列化的东西,只需将您的方法作为普通类方法调用即可。

