首页 > 解决方案 > 如何在 ASP.NET MVC 控制器中调用异步方法?

问题描述

我正在尝试调用asyncASP.NET MVC 控制器中的方法,但出现异常:

此时无法启动异步操作。异步操作只能在异步处理程序或模块内或在页面生命周期中的某些事件期间启动。如果在执行页面时发生此异常,请确保将页面标记为 <%@ Page Async="true" %>。此异常还可能表示尝试调用“async void”方法,在 ASP.NET 请求处理中通常不支持该方法。相反,异步方法应该返回一个任务,调用者应该等待它。

我的代码:

控制器:

[HttpGet]
public ActionResult OfferDetailsPage(string id)
{
    // string userid = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Name).Value.ToString();
    // var u_role = db.UserDetails.Where(x => x.ADID == userid).FirstOrDefault();
    // if (u_role == null)
    // {
    //    return RedirectToAction("Unauthorize", "Account");
    // }
    // else if (u_role.TypeOfUser.ToLower() != "validator")
    // {
    //    return RedirectToAction("Unauthorize", "Account");
    // }

    ProductOfferDetails model = new ProductOfferDetails();

    AssignedOffersImplementation offerdetail_ = new AssignedOffersImplementation();

    DataSet dstProductlist = offerdetail_.GetOfferSubmittedById(id);

    if(dstProductlist.Tables[0].Rows[0]["status"].ToString()!="Active")
    {
        return Content("Offer moved from here..");
    }

    model.Offer_UOID = dstProductlist.Tables[0].Rows[0]["Offer_UOID"].ToString();
    model.OfferId = dstProductlist.Tables[0].Rows[0]["Offer_Id"].ToString();
    model.ProductURL = dstProductlist.Tables[0].Rows[0]["Offer_pgURL"].ToString();
    // string ProductURL = dstProductlist.Tables[0].Rows[0]["Offer_pgURL"].ToString();
    model.DatePublication = Convert.ToDateTime(dstProductlist.Tables[0].Rows[0]["Date_Publication"].ToString());
    // model.SoldDate = Convert.ToDateTime(dstProductlist.Tables[0].Rows[0]["Date_Sold"].ToString());
    model.OfferStatus = dstProductlist.Tables[0].Rows[0]["OfferStatus"].ToString();
    model.SellerComments = dstProductlist.Tables[0].Rows[0]["Seller_Comments"].ToString();
    model.Product_Title = dstProductlist.Tables[0].Rows[0]["Product_Title"].ToString();
    model.Offer_Sk = dstProductlist.Tables[0].Rows[0]["Offer_Sk"].ToString();
    model.ProductSN = dstProductlist.Tables[0].Rows[0]["ProductSN"].ToString();
    // model.ImageURL = dstProductlist.Tables[0].Rows[0]["Image_url"].ToString();
    model.SNSticker = dstProductlist.Tables[0].Rows[0]["SN_sticker"].ToString();
    model.CH_Fashion_Intranet = dstProductlist.Tables[0].Rows[0]["CH_Fashion_Intranet"].ToString();
    // model.SNTag = dstProductlist.Tables[0].Rows[0]["SN_Tag"].ToString();
    model.SNCard = dstProductlist.Tables[0].Rows[0]["SN_Card"].ToString();
    // model.ValidatorComments = dstProductlist.Tables[0].Rows[0]["Validator_Comments"].ToString();
    // model.IntialSN = dstProductlist.Tables[0].Rows[0]["Initial_SN"].ToString();
    model.SNComments = dstProductlist.Tables[0].Rows[0]["SN_comments"].ToString();
    model.SNCertificate = dstProductlist.Tables[0].Rows[0]["SN_Certificate"].ToString();
    // model.DateIdentification = dstProductlist.Tables[0].Rows[0]["DateIdentification"].ToString();
    model.Offer_UOID = dstProductlist.Tables[0].Rows[0]["Offer_UOID"].ToString();
    model.OfferId = dstProductlist.Tables[0].Rows[0]["Offer_Id"].ToString();
    model.ProductURL = dstProductlist.Tables[0].Rows[0]["Offer_pgURL"].ToString();
    string ProductURL = dstProductlist.Tables[0].Rows[0]["Offer_pgURL"].ToString();
    model.DatePublication = Convert.ToDateTime(dstProductlist.Tables[0].Rows[0]["Date_Publication"].ToString());
    model.SoldDate = (dstProductlist.Tables[0].Rows[0]["Date_Sold"].ToString());
    model.OfferStatus = dstProductlist.Tables[0].Rows[0]["OfferStatus"].ToString();
    // model.SellerComments = dstProductlist.Tables[0].Rows[0]["Seller_Comments"].ToString();
    model.Product_Title = dstProductlist.Tables[0].Rows[0]["Product_Title"].ToString();
    model.Offer_Sk = dstProductlist.Tables[0].Rows[0]["Offer_Sk"].ToString();

    // if (dstProductlist.Tables[0].Rows[0]["SNEnteredStatus"ToString() == "True")
    // {
    //    return Content("Offer Already Submitted");
    // };
    // model.ProductSN = dstProductlist.Tables[0].Rows[0]["ProductSN"].ToString();
    // model.ImageURL = dstProductlist.Tables[0].Rows[0]["Image_url"].ToString();
    // model.SNSticker = dstProductlist.Tables[0].Rows[0]["SN_sticker"].ToString();
    // model.CH_Fashion_Intranet = dstProductlist.Tables[0].Rows[0]["CH_Fashion_Intranet"].ToString();
    // model.SNTag = dstProductlist.Tables[0].Rows[0]["SN_Tag"].ToString();
    // model.SNCard= dstProductlist.Tables[0].Rows[0]["SN_Card"].ToString();
    // model.ValidatorComments = dstProductlist.Tables[0].Rows[0]["Validator_Comments"].ToString();
    // model.IntialSN = dstProductlist.Tables[0].Rows[0]["Initial_SN"].ToString();
    // model.SNComments = dstProductlist.Tables[0].Rows[0]["SN_comments"].ToString();
    // model.SNCertificate = dstProductlist.Tables[0].Rows[0]["SN_Certificate"].ToString();

    DataSet dstBlobImages = offerdetail_.BlobImages(model.Offer_Sk);
    IEnumerable<Models.BlobImages> _blobs = DataTableExtentions.ToList<Models.BlobImages>(dstBlobImages.Tables[0]);
    model.blobs = _blobs;

    IEnumerable<ProductOfferDetails> _Productimageslist = DataTableExtentions.ToList<ProductOfferDetails>(dstProductlist.Tables[0]);

    TempData["SN_Tag"] = model.SNTag;
    TempData["SN"] = model.ProductSN;
    TempData["CH_Fashion_Intranet"] = model.CH_Fashion_Intranet;
    TempData["SN_Certificate"] = model.SNCertificate;
    TempData["SN_Sticker"] = model.SNSticker;
    TempData["SN_Comments"] = model.SNComments;
    TempData["SN_Card"] = model.SNCard;

    string itemcode = string.Empty;
    string stylecode = string.Empty;

    GetORLIData(model.ProductSN);
    MakeRequest(model.ProductSN);

    if (Session["itemcode"] != null)
    {
        itemcode = Session["itemcode"].ToString();
        stylecode = Session["stylecode"].ToString();

        Session.Remove("itemcode");
        Session.Remove("stylecode");
    }

    // var photo = GetPhoto(model.ProductSN);
    ViewBag.itemcode = itemcode;
    ViewBag.stylecode = stylecode;

    return View(model);
}   

异步方法:

    public  static async void MakeRequest(string serial)
    {
        var client = new HttpClient();
        var queryString = HttpUtility.ParseQueryString(string.Empty);

        // Request headers
        client.DefaultRequestHeaders.Add("Authorization", "Basic Y2NAdGVzdC5jaGFuZWwtY29ycC5jb206cGFzc3dvcmQ=");
        client.DefaultRequestHeaders.Add("X-API-Key", "computer-vision");
        client.DefaultRequestHeaders.Add("lang", "en");
        client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "5d8c7294fed64d009cadcaea2fc2dff0");

        string serialNumber = "18845681";

        string uri = string.Format("https://int-apim.lpl-cloud.com/int/fshcatalog/serial/products/v1/fsh/serial/{0}?" + queryString, serialNumber);



        var response = await client.GetAsync(uri);

        string EmpResponse = string.Empty;

        if (response.IsSuccessStatusCode)
        {
            EmpResponse = response.Content.ReadAsStringAsync().Result;
        }


        var details = JObject.Parse(EmpResponse);

        string photo = details["photo"].ToString();
        string libelleColorisCommercial = details["libelleColorisCommercial"].ToString();
        string codeArticle = details["codeArticle"].ToString();

        string codeColorCommercial = details["codeColorCommercial"].ToString();


        string Param = codeArticle + codeColorCommercial;

        string uri2 = string.Format("https://int-apim.lpl-cloud.com/int/fshcatalog/product/products/v1/fsh/products/{0}?" + queryString, Param);
        var response2 = await client.GetAsync(uri2);
        string dimension = string.Empty;
        if (response2.IsSuccessStatusCode)
        {
            dimension = response2.Content.ReadAsStringAsync().Result;
        }
        var dim = JObject.Parse(dimension);

        string dimensioncode = dim["dimensionsCode"].ToString();

        //Session["photo"] = photo;
        //Session["libelleColorisCommercial"] = libelleColorisCommercial;
        //Session["dimensioncode"] = dimensioncode;

    }

请给我建议在 ASP.NET MVC 控制器中调用异步方法

标签: asp.net-mvc

解决方案


由于MakeRequest()声明为async方法,调用该方法的控制器还必须具有返回类型而不是正常的async修饰符,因为方法不能与异常消息中提到的同步处理程序一起正常工作:Task<ActionResult>ActionResultasync

[HttpGet]
public async Task<ActionResult> OfferDetailsPage(string id)
{
    // other stuff

    // calling async method, this must be await-ed
    await MakeRequest(model.ProductSN);

    // other stuff

    return View(model);
}

但是我建议您避免async void使用方法定义,您可以在此处查看原因。我建议使用除 之外的其他返回类型void,例如,string如果您想返回一个字符串并像这样分配它:

var result = await MakeRequest(model.ProductSN);

推荐阅读