简体   繁体   中英

MVC EF6 Async delete

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).

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM