IIS Server starting MVC - System.Threading.LockRecursionException
I have a basic MVC website, all updates are installed. It is running Microsoft-IIS / 8.5 with Windows 2012 Server on AWS. Error listed below.
The problem is that the problem is with the API pair used on the site. The caller posts a JSON object to the function and returns a JSON object. This works in testing and usually on the site, but when I go through the ELMAH logs I see a lot of errors below. My code does not trigger any locks as shown below, so I believe this will happen before the code gets into my function.
I noticed that the error mentions the routing collection, I am not doing any custom routing or changing it after starting the site.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Server Variables:
string="HTTP_CONTENT_LENGTH:264;HTTP_CONTENT_TYPE:application/json;HTTP_ACCEPT:application/json;HTTP_HOST:my.site.com;HTTP_USER_AGENT:libcurl-agent/1.0"
Error message:
application="program"
host="WIN-thing"
type="System.Threading.LockRecursionException"
message="Recursive read lock acquisitions not allowed in this mode."
source="System.Core"
detail="System.Threading.LockRecursionException: Recursive read lock acquisitions not allowed in this mode.
at System.Threading.ReaderWriterLockSlim.TryEnterReadLockCore(TimeoutTracker timeout)
at System.Threading.ReaderWriterLockSlim.TryEnterReadLock(TimeoutTracker timeout)
at System.Web.Routing.RouteCollection.GetReadLock()
at System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext)
at System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)"
SUDO code for the controller: The registration function is really very simple, you call a stored procedure that returns multiple data fields and then returns a JSON packet with values (two fields). Received JSON again, couple of fields.
An example of a registration package: {"Address": "value", "company": "name"}
example result package: {"success": true, "value": "updated 1"}
namespace ApMonitor.Controllers
{
[OutputCache(Duration = 0, NoStore = true)]
[AllowAnonymous]
public class ApiController : Controller
{
// passed via json data
public async Task<JsonResult> Register(Models.ApRegisterModel apReg)
{
try
{
using (var db = new ApplicationDbContext())
{
// get device data from SQL (one call)
var result = await DataLink.RegisterDevice(db, apReg);
// return json success fail
if(string.IsNullOrEmpty(result.DevicePw))
{
return DataLink.Fail("Unknown", string.Empty);
} else {
return DataLink.Success(result.DeviceData);
}
}
} catch (Exception ex)
{
DataLink.ProcessError(ex, "API Controller - Register");
}
}
public async Task<JsonResult> Log()
{
try
{
var input = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
apEvent = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.ApEventModel>(input);
using (var db = new ApplicationDbContext())
{
deviceId = await DataLink.GetDeviceId(db, apEvent.Address);
foreach(var e in apEvent.Device)
db.Events.Add(new Event() { /* ... */ });
// save data to DB
var cnt = await db.SaveChangesAsync();
return DataLink.Success(string.Format("updated {0}", cnt));
}
} catch (Exception ex)
{
DataLink.ProcessError(ex, "API Controller - Log");
}
return DataLink.Fail("Unknown", string.Empty);
}
// moved from another class called DataLink
internal static JsonResult Success(string value)
{
var result = new JsonResult()
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new { success = true, value = value }
};
return result;
}
internal static JsonResult Fail(string reason, string value)
{
var result = new JsonResult()
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new { success = false, reason = reason, value = value }
};
return result;
}
}
}
source to share
No one has answered this question yet
Check out similar questions: