Reputation: 4383
I developed an MVC 5 app.
Inside a controller, I have this action:
// POST: Usuario/Edit
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<JsonResult> Edit(UsuarioViewModel model)
{
//
// some tasks
//
//
return Json("Some text", JsonRequestBehavior.AllowGet);
}
When that action is called after a html form submit, System.Web.HttpContext.Current
is not null. I am using that object somewhere in the code.
Now, I need to call this same action method from other action method in the same controller. In that case, System.Web.HttpContext.Current
is null, causing obviously, the application to throw a null object exception.
The action method and the call are:
// POST: Usuario/CreateFromStaff
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<JsonResult> CreateFromStaff(int[] trabajadores)
{
//
// some tasks
//
//
UsuarioViewModel model = new UsuarioViewModel();
//
// model properties assignments
//
//
JsonResult json = Task.Run(async () => await Edit(model)).Result; // When this call is made, the Http context get lost.
}
What can I do so that the http context is kept? or, how can I do that call?
Question Edit:
Just to be clearer. The Edit
action method is the standard way to store a record, in this case a user record. At some point in this action method I have:
await db.SaveChangesAsync();
On the other hand, the JsonResult json = Task.Run(async () => await Edit(model)).Result;
is inside a ForEach
method. After that loop, I need to save other data, so that I am using another await db.SaveChangesAsync();
after it.
If I configure the ForEach method as async
I have always problems with the second await db.SaveChangesAsync();
. An error is thrown telling that some database operations are incomplete. That is why I used .Result
and the ForEach
method not to be async
.
Thanks Jaime
Upvotes: 0
Views: 922
Reputation: 456477
What can I do so that the http context is kept? or, how can I do that call?
Remove the Task.Run
call. You should strongly avoid ever using Task.Run
on ASP.NET.
the
JsonResult json = Task.Run(async () => await Edit(model)).Result;
is inside aForEach
method... If I configure theForEach
method asasync
... An error is thrown telling that some database operations are incomplete. That is why I used.Result
and theForEach
method not to be async.
Indeed, the ForEach
method does not properly understand async
lambdas, and if you make its lambda async
, then you will end up with async void
lambdas, which should be avoided. That would cause the "asynchronous operation incomplete" errors.
I assume the fix went something like this:
ForEach
doesn't work with async
, so I need to make it synchronous.Task.Run
to avoid the deadlock.HttpContext.Current
. How can I get HttpContext.Current
?But a better fix is this:
ForEach
doesn't work with async
, so I need to use something other than ForEach
.Changing ForEach
to foreach
will solve your problem in a much nicer way.
Upvotes: 3