webentwicklung-frage-antwort-db.com.de

Wie kann ich eine Web-API-Methode über die MVC Controller-Aktionsmethode aufrufen?

Wie kann ich eine Web-API-Methode von einer MVC-Aktionscontrollermethode aufrufen? Dies ist, was ich versuche, das ist meine Controller-Methode:

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);
    }
}

Meine Web-API-Methode:

private ProductEntities products = new ProductEntities();

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

   return produc;
}

Wenn ich dies tue, erhalte ich ein error @ var-Modell in meiner MVC-Aktionsmethode, nachdem ich die Daten zurückgegeben habe, die sagen

"Newtonsoft.Json.JsonSerializationException: JSON-Array kann nicht deserialisiert werden" (d. H. [1,2,3]) in Typ "ProductDetails.Models.ProductItems". Der deserialisierte Typ muss ein Array sein oder eine Erfassungsschnittstelle wie IEnumerable, ICollection oder IList implementieren. Fügen Sie dem Typ das JsonArrayAttribute hinzu, um die Deserialisierung von JSON-Arrays zu erzwingen. Zeile 1, Position 1. "

Kann mir jemand dabei helfen ... oder mir eine andere beste Methode vorschlagen oder mich korrigieren, wenn ich etwas falsch mache, wo ... Ich muss die zurückgegebenen Daten in meiner Ansicht anzeigen ... Die Daten sollten an meine zurückgegeben werden Regler

24
SoftwareNerd

Da die Ausnahmebedingung "Kann nicht deserialisieren JSON-Array ..." lautet, liegt auf der Empfängerseite ein Problem vor, z.

Und Ihr Problem ist, dass Sie versuchen, in den falschen Typ zu deserialisieren, weil Ihre Web-API-Methode so aussieht:

public IEnumerable<ProductItems> GetProductDetail(int ID)

Es gibt also IEnumerable<ProductItems> Zurück (z. B. ein Array von ProductItems), aber in Ihrer Controller-Aktion versuchen Sie, die Antwort mit dem Aufruf in einsProductItems zu deserialisieren ReadAsAsync<ProductItems>()

Ändern Sie also Ihr ReadAsAsync, um es in ein Array ProductItems zu deserialisieren, und es sollte funktionieren:

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

Wenn Ihre ASP.NET-Website zusammen mit dem Web-API-Controller gehostet wird, können Sie die Web-API als gewöhnliche Klassenmethode aufrufen, um Verzögerungen im Zusammenhang mit HTTP-Anforderungen zu vermeiden.

Und das Problem liegt nicht im Web-API-Aufruf. Das Problem liegt in der Deserialisierung der Ergebnisse, die von ExecuteStoreQuery stammt. Stellen Sie sicher, dass Sie eine serialisierbare Auflistung enthalten. Um sicherzugehen, können Sie einfach versuchen, dieses Methodenergebnis in eine Liste zu konvertieren, bevor Sie von der serialisierbaren Liste der Web-API-Methoden zurückkehren, und dann das Problem lokalisieren.

UPD: Die Wurzel des Problems liegt also in der zurückgegebenen ExecuteStoreQuery -Methode. Es wird ObjectResult zurückgegeben. Es implementiert tatsächlich IEnumerable, wird jedoch von EF zurückgegeben, und in einigen Fällen gibt es z. Zyklische Abhängigkeiten zwischen Objekten, die Json-Deserialzer nicht auflösen konnten.

Um das Problem zu lösen, konvertieren Sie ObjectResult einfach explizit in z. Aufführen:

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

Wenn tatsächlich Zyklusabhängigkeiten in Auflistungen Ihrer Objekte auftreten, die von EF stammen, können Sie diese in Json.NET deaktivieren

Überprüfen Sie auch die Deserialisierung auf Ihrer Clientseite:

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

Wenn Sie jedoch Ihre ASP.NET MVC-Site und die ASP.NET Web API in einem Projekt hosten, benötigen Sie nicht all dieses Zeug mit HTTP-Anforderung und Serialisierung/Deserialisierung. Rufen Sie Ihre Methode einfach als gewöhnliche Klassenmethode auf.

8
Regfor