prasanth
prasanth

Reputation: 75

How to call asynchronous methods in an ASP.NET MVC controller?

I am trying to call async methods in an ASP.NET MVC controller, but I am getting an exception:

An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>. This exception may also indicate an attempt to call an "async void" method, which is generally unsupported within ASP.NET request processing. Instead, the asynchronous method should return a Task, and the caller should await it.

My code:

Controller:

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

Asynchronous method :

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

        // Request headers
                    client.DefaultRequestHeaders.Add("X-API-Key", "computer-vision");
        client.DefaultRequestHeaders.Add("lang", "en");
        

        string serialNumber = "18845681";

        



        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;

        
        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;

    }

Please give me suggestion to call asynchronous methods in ASP.NET MVC controller

Upvotes: 0

Views: 2297

Answers (1)

Tetsuya Yamamoto
Tetsuya Yamamoto

Reputation: 24957

Since MakeRequest() declared as async method, the controller which calls that method must also has async modifier with Task<ActionResult> return type instead of normal ActionResult because async methods did not work properly with synchronous handler as mentioned in exception message:

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

However I suggest you to avoid async void method definitions, you can see the reasons here. I recommend to use another return type other than void, e.g. string if you want to return a string and assign it like this:

var result = await MakeRequest(model.ProductSN);

Upvotes: 1

Related Questions