1

In my Controller I have action

[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(int id)
{
    clsHost HostDAL = new clsHost();
    vw_Host vw_host = await HostDAL.GetByIdAsync(id);
    string actionStatus = HostDAL.Delete(vw_host);

    TempData["msgHost"] = actionStatus;
    return RedirectToAction("Display");
}

Delete method:

public string Delete(vw_Host host)
{
    ObjectParameter executionStatus = new ObjectParameter("ExecutionStatus", "");

    try
    {
        using (Entities context = new Entities())
        {
            string name = HttpContext.Current.User.Identity.Name.ToString();
            context.sp_Host_Delete(host.ID, HttpContext.Current.User.Identity.Name.ToString(), executionStatus);
            context.SaveChanges();
        }
    }
    catch (Exception ex)
    {
        using (Entities context = new Entities())
        {
            context.sp_LogError(this.GetType().Name.ToString() + "." + System.Reflection.MethodBase.GetCurrentMethod().Name.ToString(), ex.Message, HttpContext.Current.User.Identity.Name);
            context.SaveChanges();
        }

        executionStatus.Value = "Error occured. Please contact to Administrator";
    }

    return executionStatus.Value.ToString();
}

Mi problem is that when I use Async DeleteConfirmed action, in Delete method I got error:

Object reference not set to an instance of an object.

for

HttpContext.Current.User.Identity.Name

On the other hand when I use sync action:

[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
    clsHost HostDAL = new clsHost();
    vw_Host vw_host = HostDAL.GetById(id);
    string actionStatus = HostDAL.Delete(vw_host);

    TempData["msgHost"] = actionStatus;
    return RedirectToAction("Display");
}

Everything is working fine and HttpContext.Current.User.Identity.Name returns no error. This problem occurs only for Delete action. It works fine for Edit action (even its async).

Nkosi
  • 235,767
  • 35
  • 427
  • 472
ironcurtain
  • 650
  • 9
  • 35
  • 1
    First, make sure `HttpContext.User` is indeed not `null`. Then see http://stackoverflow.com/questions/28427675/correct-way-to-use-httpcontext-current-user-with-async-await – haim770 Oct 14 '16 at 10:30
  • Is `sp_Host_Delete` a stored-procedure? sp's does not support async. – Salar Oct 14 '16 at 10:30
  • You should also consider grabbing the user before your async calls and pass it as an argument to the delete method – Nkosi Oct 14 '16 at 10:32
  • @haim770 - it is null and I am wonder why it happens for async action. – ironcurtain Oct 14 '16 at 10:37
  • @Salar - its stored procedure but even I set a variable BEFORE store procedure is reached it returns null. I have exact action for Edit method and it works fine - even it is async. – ironcurtain Oct 14 '16 at 10:39

1 Answers1

1

You could also consider grabbing the user before your async calls and pass it as an argument to the delete method.

[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(int id) {
    var name = "Unknown";
    try {
        name = HttpContext.Current.User.Identity.Name.ToString();
    }catch { }
    clsHost HostDAL = new clsHost();
    vw_Host vw_host = await HostDAL.GetByIdAsync(id);
    string actionStatus = HostDAL.Delete(vw_host, name);

    TempData["msgHost"] = actionStatus;
    return RedirectToAction("Display");
}

Refactored Delete method

public string Delete(vw_Host host, string name) {
    ObjectParameter executionStatus = new ObjectParameter("ExecutionStatus", "");

    try {
        using (Entities context = new Entities()) {
            context.sp_Host_Delete(host.ID, name, executionStatus);
            context.SaveChanges();
        }
    } catch (Exception ex) {
        using (Entities context = new Entities()) {
            context.sp_LogError(this.GetType().Name.ToString() + "." + System.Reflection.MethodBase.GetCurrentMethod().Name.ToString(), ex.Message, name);
            context.SaveChanges();
        }

        executionStatus.Value = "Error occured. Please contact to Administrator";
    }

    return executionStatus.Value.ToString();
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • Link provided by @haim770 in comments does give some details for behavior http://stackoverflow.com/questions/28427675/correct-way-to-use-httpcontext-current-user-with-async-await – Nkosi Oct 14 '16 at 11:05
  • I checked and when I move HttpContext.Current.User.Identity.Name.ToString() to Controller action, it is still null. – ironcurtain Oct 14 '16 at 11:09
  • I had to add string actionedBy = System.Web.HttpContext.Current.User.Identity.Name; at the first item of DeleteConfirmed action and it worked. Wen I put it after vw_Host vw_host = await HostDAL.GetByIdAsync(id); action it returend error. – ironcurtain Oct 14 '16 at 11:20
  • But that is what was advised in the answer. – Nkosi Oct 14 '16 at 11:33
  • I wasn't aware if that matters. – ironcurtain Oct 14 '16 at 11:37