Try Catch not working in MVC3 - c#

try
{
var orderedListOfRfidTags = uow.RfidTags.ToList().OrderBy(t => int.Parse(t.Number));
return View(orderedListOfRfidTags);
}
catch
{
var orderedListOfRfidTags = uow.RfidTags.OrderBy(t => t.Number).ToList();
return View(orderedListOfRfidTags);
}
MVC3 - in Release mode this will still fail on the first line var ordreedListOfRfidTags...
I wonder why try catch isn't trying and catching?
then pressing F10 it goes to here.. which is part of my ORM wrapper... hmm I wonder if this is the problem.
protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (_unitOfWorkScope != null)
{
_unitOfWorkScope.Dispose();
}
base.OnResultExecuted(filterContext);
}

The delegate passed to OrderBy is not invoked until you try to access the elements in the list.
So I think the error is not caught because your collection is not enumerated until the view is being rendered, after the action method has returned.

This is a bad design; you shouldn't have any code in your catch that could potentially throw another exception.
If I'm understanding your code, you want to attempt to parse the RFID to an int, but fall back on string as your sort if a failure?
If you can't gaurentee that the Numbers of the RfidTags won't be a number (which seems a silly naming structure), then I'd leave it as a string sort and ditch the int parsing

The answer was that LightSpeed was failing out. Once the support was added (very quickly - awesome product!) it all worked fine:
// trying to convert to an int.. if fail, use string
// need up to date nightly build of LS3.1 for this to work
// otherwise trycatch will fail due to LS crashing out.
try
{
var orderedListOfRfidTags = uow.RfidTags
.OrderBy(t => Convert.ToInt32(t.Number))
.ToList();
return View(orderedListOfRfidTags);
}
catch
{
var orderedListOfRfidTags = uow.RfidTags
.OrderBy(t => t.Number)
.ToList();
return View(orderedListOfRfidTags);
}

Related

C# lambda null runtime binding

I'm running into an odd scenario that doesn't happen on my PC, but does for a coworkers.
I have this piece of code:
LoaderHelpers.SetStringValue<blah>(this, "x", $"x response in Header",
() => jsonData.x.response[0].value, false);
The problem is that sometimes, "jsonData.x" is null and, for my coworker a 'cannot bind to null at runtime exception' is thrown, but not for me there isn't. I have code to handle the null scenario, but it's like his code never gets to that point and fails at the call level.
jsonData is of type dynamic.
The method code that handles the null scenario:
public static void SetStringValue<T>(IValidate data, string propertyName,
string valuePath, Func<string> value, bool required)
{
if (data.GetType().GetProperty(propertyName) != null)
{
try
{
if (string.IsNullOrEmpty(value()))
{
if (required)
data.DataValidationErrors.Add($"{valuePath} can't be empty");
data.GetType().GetProperty(propertyName).SetValue(data, null);
}
else
{
data.GetType().GetProperty(propertyName).SetValue(data, value());
}
}
catch
{
//property doesn't exist
if (required)
data.DataValidationErrors.Add($"{valuePath} doesn't exist");
data.GetType().GetProperty(propertyName).SetValue(data, null);
}
}
else
{
throw new NullReferenceException($"In {data.GetType()} => SetStringValue. " +
$"Passed property {propertyName}, but property doesn't exist.");
}
}
Again. Works perfect for me, but not for him. I'm completely lost. Maybe I don't understand how the lamba/function parameters work 100%, but I thought it only got evaluated when value() is invoked.
I should also mention that when I debug this code, I can step into the Nuget package and when he hits the same line, he can't. This maybe a useful hint.
If jsonData (or jsonData.x) is null (as it seems to be at this point) it will crash and give you that error every time you call the method value().
You need to check why jsonData.x is null. Maybe it´s a race condition caused by another thread setting this value to null, maybe it´s because a bad jsonData initialization... Can´t say since that code is not here.
There are so many things wrong with your code, i can't resist.
First of all, instead of copy/pasting the same stuff over and over, you might want to use a variable:
var property = data.GetType().GetProperty(propertyName);
Second, you pass a Func<string> and execute it multiple times, why is it even a function then? Yet again, better only evaluate it once and use a variable...
var unwrapped = value();
That would solve the issue, that Roberto Vázquez' answer adresses.
Then you are misusing NullReferenceException, instead rather use a ArgumentException
Next issue, that valuePath is only used in the exception message, that is a poor design to my beliefs.
The generic T parameter isnt even used, so get rid of it.
Last but not least, that catch-block doing the exact thing that could possibily throw the exception again, i cant see any reason why you would do this.
Finnaly this whole thing becomes a little more clear but its still a mess.
public static void SetStringValue(IValidate data, string propertyName,
string valuePath, Func<string> value, bool required)
{
if(data == null)
throw new ArgumentNullException(nameof(data));
var property = data.GetType().GetProperty(propertyName);
if(property == null)
throw new ArgumentException($"In {data.GetType()} => SetStringValue. " +
$"Passed property {propertyName}, but property doesn't exist.");
var unwrapped = value();
try
{
if (string.IsNullOrEmpty(unwrapped))
{
if (required)
data.DataValidationErrors.Add($"{valuePath} can't be empty");
unwrapped = null; // this might be unecessary.
}
property.SetValue(data, unwrapped);
}
catch(Exception e)
{
// This is probably a bad idea.
property.SetValue(data, null);
if (required)
data.DataValidationErrors.Add(Atleast put a better message here. e.Message ...);
}
}

System.AccessViolationException unknown module

I currently have a controller in my WebAPI that is returning a list of some items in my database:
As below:
public ICollection<TherapyGroup> OffUnit()
{
return _context.TherapyGroups.OrderBy(g => g.Name)
.Where(x => x.GroupTypeOffUnitOnUnit == TherapyGroup.OffUnit)
.ToList();
}
Everything works fine when I am testing against my local database; however, when I switch out the database string for a remote database it throws a System.AccessViolationException. Based upon breakpoints, the data is being returned from the database fine, and it seems the problem is happening when the method returns to the WebApi in MVC. This has become a very frustrating issue, and I would love any help to navigate it.
The error window that is popping up:
Decorate the methods you want to catch these exceptions in with the HandleProcessCorruptedStateExceptions attribute. See https://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035 for details.
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
public ICollection<TherapyGroup> OffUnit()
{
try
{
return _context.TherapyGroups.OrderBy(g => g.Name).Where(x => x.GroupTypeOffUnitOnUnit == TherapyGroup.OffUnit).ToList();
}
catch (Exception e)
{
// set break point to see the stack trace.
Debug.WriteLine(e.InnnerException);
return null;
}
}

Update only works in debug mode

I'm new to using entity as a data layer between MVC and SQL Server, so I apologize up front if what I'm doing is bad practice.
Let me start by sharing the code that is handling the update.
Update Delivery:
public bool One(Delivery toUpdate)
{
using (var dbContext = new FDb())
{
try
{
var deliveryInDb = this.dbTable(dbContext).Single(x => x.DeliveryId == toUpdate.DeliveryId);
dbContext.Entry(deliveryInDb).CurrentValues.SetValues(toUpdate);
//removal first
List<DeliveryDay> currentDays = FEngineCore.DeliveryDay.Get.ForValue((x => x.DeliveryId), toUpdate.DeliveryId);
List<DeliveryTime> currentTimes = FEngineCore.DeliveryTime.Get.ForValue((x => x.DeliveryId), toUpdate.DeliveryId);
//remove delivery days that are not needed
foreach (var curDay in currentDays)
{
if (!toUpdate.DeliveryDays.Select(x => x.DeliveryDayId).Contains(curDay.DeliveryDayId))
{
FEngineCore.DeliveryDay.Delete.One((x => x.DeliveryDayId), curDay.DeliveryDayId);
deliveryInDb.DeliveryDays.Remove(curDay);
}
}
//remove delivery times that are not needed
foreach (var curTime in currentTimes)
{
if (!toUpdate.DeliveryTimes.Select(x => x.DeliveryTimeId).Contains(curTime.DeliveryTimeId))
{
FEngineCore.DeliveryTime.Delete.One((x => x.DeliveryTimeId), curTime.DeliveryTimeId);
deliveryInDb.DeliveryTimes.Remove(curTime);
}
}
foreach (var day in toUpdate.DeliveryDays)
{
if (day.DeliveryDayId == 0)
{
dbContext.DeliveryDays.Add(day);
}
else
{
if (dbContext.DeliveryDays.Local.Any(e => e.DeliveryDayId == day.DeliveryDayId))
{
dbContext.Entry(dbContext.DeliveryDays.Local.First(e => e.DeliveryDayId == day.DeliveryDayId)).CurrentValues.SetValues(day);
dbContext.Entry(dbContext.DeliveryDays.Local.First(e => e.DeliveryDayId == day.DeliveryDayId)).State = EntityState.Modified;
}
else
{
DeliveryDay modDay = new DeliveryDay
{
DayOfWeek = day.DayOfWeek,
DeliveryDayId = day.DeliveryDayId,
DeliveryId = day.DeliveryId,
Interval = day.Interval
};
dbContext.DeliveryDays.Attach(modDay);
dbContext.Entry(modDay).State = EntityState.Modified;
}
deliveryInDb.DeliveryDays.Add(day);
}
}
foreach (var time in toUpdate.DeliveryTimes)
{
if (time.DeliveryTimeId == 0)
{
dbContext.DeliveryTimes.Add(time);
}
else
{
if (dbContext.DeliveryTimes.Local.Any(e => e.DeliveryTimeId == time.DeliveryTimeId))
{
dbContext.Entry(dbContext.DeliveryTimes.Local.First(e => e.DeliveryTimeId == time.DeliveryTimeId)).CurrentValues.SetValues(time);
dbContext.Entry(dbContext.DeliveryTimes.Local.First(e => e.DeliveryTimeId == time.DeliveryTimeId)).State = EntityState.Modified;
}
else
{
DeliveryTime modTime = new DeliveryTime
{
DeliveryId = time.DeliveryId,
DeliveryLocationId = time.DeliveryLocationId,
DeliveryTimeId = time.DeliveryTimeId,
DropoffTime = time.DropoffTime
};
dbContext.DeliveryTimes.Attach(modTime);
dbContext.Entry(modTime).State = EntityState.Modified;
}
deliveryInDb.DeliveryTimes.Add(time);
}
}
dbContext.SaveChanges();
dbContext.Entry(deliveryInDb).State = EntityState.Detached;
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
return false;
}
}
}
Let me continue by explaining that the delivery object has 2 children; DeliveryTime and DeliveryDay. The issue that arises happens when I try to remove one deliveryTime and modify nothing else. The end result of running the code normally (not in debug) is that the deliveryTime is in fact not removed. Here's the interesting thing guys, when I debug it and go through the break points, everything works as expected!
Let me continue by posting the code that is running behind the removal method of the deliveryTime (actually all entity objects in my system).
public bool One<V>(Expression<Func<T, V>> property, V value) where V : IComparable
{
using (var dbContext = new FoodsbyDb())
{
try
{
T toDelete;
//get the body as a property that represents the property of the entity object
MemberExpression entityPropertyExpression = property.Body as MemberExpression;
//get the parameter that is representing the entity object
ParameterExpression entityObjectExpression = (ParameterExpression)entityPropertyExpression.Expression;
//represent the value being checked against as an expression constant
Expression valueAsExpression = Expression.Constant(value);
//check the equality of the property and the value
Expression equalsExpression = Expression.Equal(entityPropertyExpression, valueAsExpression);
//create an expression that takes the entity object as a parameter, and checks the equality using the equalsExpression variable
Expression<Func<T, bool>> filterLambda = Expression.Lambda<Func<T, bool>>(equalsExpression, entityObjectExpression);
toDelete = this.dbTable(dbContext)
.SingleOrDefault(filterLambda);
if (toDelete != null)
{
this.dbTable(dbContext)
.Remove(toDelete);
dbContext.SaveChanges();
return true;
}
return false;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
return false;
}
}
}
The code above is obviously generic, and it handles all my entity objects. I have tested it in and out and know for sure the problem does not lie in there. I thought it would be helpful to post it so you all can have a full understanding of what's going on.
Here's my best guess as to what's going on:
The reference to the removed deliveryTime still exists when the database context is saved, but when I debug, the system has enough time to remove the context.
Here was one of my attempted solutions:
Remove all references to the children objects immediately after setting currentDays and currentTimes and then proceeding to add them back to deliveryInDb as you enumerate through them.
Because I am new to all of this, if you see some bad practice along with the solution, I wouldn't mind constructive criticism to improve my programming method.
I actually encountered this issue in a project at work. The project is an older MVC4 project using EF 6.1.
In our situation, a simple update attempting to set a related entity property to null was failing to actually set it to null while running the web app normally (in debug mode). When setting a break point on the line of code that sets the property to null the database would be updated as expected, though. So, the update was working when a break point was in place but not working when allowed to run normally.
Using an EF interceptor, we could see that, with the break point in place, the update query was going through as expected.
Now, in our situation the related entity was using the virtual keyword to allow for lazy loading. I think this is the root of the issue. When a break point is present, EF has enough time to both lazily load that related entity and evaluate whatever it needs to evaluate and finally set it to null. When running without a break point, I think EF gets caught up trying to lazily load that entity and therefore fails to think it needs to be updated. To be clear, I was both accessing the related entity property for the first time and setting it null using a one-liner of code.
foo.Bar = null;
I resolved this issue, in our scenario, by accessing that property at least once prior to setting it to null so that EF is forced to load it. With it loaded, setting it to null seems to work as intended now. So again, to be clear, I think the issue is a combo of lazy loading and the one-liner of code both accessing that property for the first time and assigning it to null.
It appears that you're using multiple instances of your DbContext, which are not synchronized.
The solution would be to use a single instance, and pass that instance between your methods.

Issues with Nancy Framework for MVC (and NewRelic)

I just took over a bunch of C# code from another company, and I'm having big trouble getting the first build to work. The code uses a framework called Nancy, instead of MVC. I have never used this framework before, and there might be a real simply answer to my question, and I apllogize if I missed some basic understanding of Nancy, before posting here.
The problem is boiled down to a single class, handling the initialization of the application (I THINK) From what I've read, it's pretty standard Nancy:
using System;
using Nancy;
using NewRelicAgent = NewRelic.Api.Agent.NewRelic;
using Nancy.Bootstrapper;
using Nancy.Routing;
public class NewRelicStartup : IApplicationStartup
{
private readonly IRouteResolver routeResolver;
public NewRelicStartup (IRouteResolver routeResolver)
{
this.routeResolver = routeResolver;
}
public void Initialize(IPipelines pipelines)
{
pipelines.BeforeRequest.AddItemToStartOfPipeline(
context =>
{
var route = routeResolver.Resolve(context);
if (route == null || route.Item1 == null || route.Item1.Description == null) // probably not necessary but don't want the chance of losing visibility on anything
{
NewRelicAgent.SetTransactionName(
context.Request.Method,
context.Request.Url.ToString());
}
else
{
NewRelicAgent.SetTransactionName(
route.Item1.Description.Method,
route.Item1.Description.Path);
}
return null;
});
pipelines.OnError.AddItemToEndOfPipeline(
(context, ex) => {
NewRelicAgent.NoticeError(ex);
return null;
}
);
}
}
When this code is being build, I get several errors, some of which being:
Delegate 'System.Func<Nancy.NancyContext,System.Threading.CancellationToken,System.Threading.Tasks.Task<Nancy.Response>>' does not take 1 arguments
Cannot convert lambda expression to type 'Nancy.PipelineItem<System.Func<Nancy.NancyContext,System.Threading.CancellationToken,System.Threading.Tasks.Task<Nancy.Response>>>' because it is not a delegate type
Here is a screenshot of the kind of error I get:
https://www.dropbox.com/s/cigcfc4sfj8batg/Nancy%20Error.PNG
I am 100 % certain, that this is some kind of interpretation issue from Visual Studio's side, since the code is live atm. I just can't build it in VS.
Do any of you have any idea what I am missing, or doing wrong? Remember; the code is working and live atm.
Try changing "return null;" to "return (Nancy.Response)null;"
Edit: Sorry, just looked at the screenshot - it's using some properties that have changed in 0.20, so you will either have to manually fix up the code (it's now async at the core), or roll back to 0.19 for now, and re-write that bit of code at a later date.
Edit again: Give this ago:
pipelines.BeforeRequest.AddItemToStartOfPipeline(
context =>
{
var route = routeResolver.Resolve(context);
if (route == null || route.Route == null || route.Route.Description == null) // probably not necessary but don't want the chance of losing visibility on anything
{
NewRelicAgent.SetTransactionName(
context.Request.Method,
context.Request.Url.ToString());
}
else
{
NewRelicAgent.SetTransactionName(
route.Route.Description.Method,
route.Route.Description.Path);
}
return null;
});

Why does my ASP.NET MVC 3 with EF application only work when I step through it while debugging?

I have a controller that updates values in a database using Entity Framework. Unfortunately, when I run my application it doesn't seem to work at all. When I put breakpoints in and step through a specific part of the code, it works perfectly.
Here's my controller code:
public ActionResult ManageGame(int id, FormCollection collection, string[] selectedPlayers)
{
var gameToUpdate = db.Games
.Include("Teams")
.Where(g => g.ID == id)
.Single();
if (TryUpdateModel(gameToUpdate, "", null, new string[] { "Players" }))
{
try
{
List<Player> team1Players = generateRandomTeam();
List<Player> team2Players = generateRandomTeam();
If I put a breakpoint here and step through the rest of the code it's fine, otherwise nothing gets saved.
foreach (var team in gameToUpdate.Teams)
{
if (!team1added)
{
team.Players = team1Players;
team1added = true;
}
else
{
team.Players = team2Players;
}
}
db.Entry(gameToUpdate).State = EntityState.Modified;
db.SaveChanges();
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save changes.");
}
}
try
{
return RedirectToAction("Index");
}
catch
{
return View();
}
}
I have a feeling it's the way I'm assigning the new teams to the existing context, but from all the tutorials I've read, this is the way they do it, at least for string values. Does anybody know why I'm getting this bizarre behavior?
*UPDATE* SOLVED
I solved my problem. My hunch was right, I just needed to add team.Players.Clear() before assigning the new group of players to the existing team.
foreach (var team in gameToUpdate.Teams)
{
if (!team1added)
{
team.Players.Clear()
team.Players = team1Players;
team1added = true;
}
else
{
team.Players.Clear()
team.Players = team2Players;
}
}
When I didn't have that, I got a primary key violation exception. Unfortunately I didn't see this exception, because my code was swallowing this as pointed out by DarK. So, after adding the Clear() method everything worked like a charm.
Looks like other people have had the same problem like yours. Have alook at these links: C# code only gives expected results on step through?, Code runs correctly only when stepping through it with debugger?
So, if you are instantiating the Random class more than once, you will get some weird results.
EDIT:
From your code, it looks like you're consuming the exception. Can you possibly comment out the try-catch and run it without debugging and see if it throws any exceptions?

Categories

Resources