ModelState.IsValid is false - But Which One - Easy Way - asp.net-mvc

In ASP.NET MVC, when we call a post action with some data, we check ModelState and in case some validation error, it would be falst. For a big Enter User Information form, it is annoying to expand each Value and look at the count to see which Key (9 in attached example image) has validation error. Wondering if someone knows an easy way to figure out which element is causing validation error.

In VS2015+, you can use LINQ in the Immediate Window, which means you can just run the following:
ModelState.SelectMany(
x => x.Value.Errors,
(state, error) => $"{state.Key}: {error.ErrorMessage}"
)

I propose to write a method:
namespace System.Web
{
using Mvc;
public static class ModelStateExtensions
{
public static Tuple<string, string> GetFirstError(this ModelStateDictionary modelState)
{
if (modelState.IsValid)
{
return null;
}
foreach (var key in modelState.Keys)
{
if (modelState[key].Errors.Count != 0)
{
return new Tuple<string, string>(key, modelState[key].Errors[0].ErrorMessage);
}
}
return null;
}
}
}
Then during debugging open Immediate Window and enter:
ModelState.GetFirstError()

Sounds like you're looking for debugger enhancements. I recently came across this product in the visual studio gallery.
http://visualstudiogallery.msdn.microsoft.com/16acdc63-c4f1-43a7-866a-67ff7022a0ac
I have no affiliation with them, and haven't used it. It's also a trial version and have no idea how much it costs for the full thing.

If you're more focused on the debugger side of things, have a go with the trial copy of OzCode. It enhances the Visual Studio IDE by replacing the usual debugging tooltip with it's own, more powerful, debugging tooltip. It's hard to epxlain with words, check out their website, they have a gallery of features on there.
I've been playing around with the beta for a few weeks, and it's proved a very valuable tool. You can query against data in the debugger using OzCode. For example, you could query items in the ModelState by filtering against the Values collection.

Related

Vaadin "A connector with id xy is already registered"

Somewhere in my Vaadin application, I'm getting this exception as soon as I connect using a second browser
Caused by: java.lang.RuntimeException: A connector with id 22 is already registered!
at com.vaadin.ui.ConnectorTracker.registerConnector(ConnectorTracker.java:133)
It happens always in the same place but I don't know why exactly as the reason for this must be somewhere else.
I think I might be stealing UI components from the other session - which is not my intention.
Currently, I don't see any static instances of UI components I might be using in multiple sessions.
How can I debug this? It's become quite a large project.
Any hints to look for?
Yes, this usually happens because you are attaching a component already attached in other session.
Try logging the failed connector with a temporal ConnectorTracker, So the next time that it happens, you can catch it.
For example:
public class SomeUI extends UI {
private ConnectorTracker tracker;
#Override
public ConnectorTracker getConnectorTracker() {
if (this.tracker == null) {
this.tracker = new ConnectorTracker(this) {
#Override
public void registerConnector(ClientConnector connector) {
try {
super.registerConnector(connector);
} catch (RuntimeException e) {
getLogger().log(Level.SEVERE, "Failed connector: {0}", connector.getClass().getSimpleName());
throw e;
}
}
};
}
return tracker;
}
}
I think I might be stealing UI components from the other session - which is not my intention. Currently, I don't see any static instances of UI components I might be using in multiple sessions.
That was it. I was actually stealing UI components without prior knowledge.
It was very well hidden in a part which seems to be same for all instances. Which is true: the algorithm is the same.
Doesn't mean I should've reused the same UI components as well...
Thanks to those who took a closer look.
Here is how I fixed it -
1) look for components you have shared across sessions. For example if you have declared a component as static it will be created once and will be shared.
2) if you are not able to find it and want a work around until you figure out the real problem, put your all addComponent calls in try and in catch add following code -
getUI().getConnectorTracker().markAllConnectorsDirty();
getUI().getConnectorTracker().markAllClientSidesUnititialized();
getPage().reload():
This will clear old connectors and will reload the page properly only when it fails. For me it was failing when I was logged out and logged in back.
Once you find the real problem you can fix it till then inform your customers about the reload.
**** note - only solution is to remove shared components this is just a work around.
By running your application in debug mode (add ?debug at the end of URL in browser) you will be able to browse to the component, e.g:
-UIConnector(0)
--VerticalLayoutConnector(1)
---...
---LabelConnector(22)
where 22 is id from your stack trace. Find this component in your code and make sure that it is not static (yes, I saw such examples).

May a scenario not have a When in BDD?

I'm currently learning/testing BDD using SpecFlow, and it works great!
Before I choose to ask my question, I have read this one, and I felt like I had to ask my question despite the fact that the same problem is addressed, because of the Exception scenario which is not mentioned.
I'm actually testing this scenario:
Scenario: I should get an error whenever I try to remove an item from an empty stack
Given I have an empty stack
When I pop from it
Then I should get an error
public class StackBehaviour {
public void GivenIHaveAnEmptyStack() { stack = new CustomStack<string>(); }
// This will throw whenever called!
// So the Then method will never be run!
// I feel like I should just put a comment which says why it's empty,
// allowing a fellow programmer to understand the exact intention.
public void WhenIPopFromIt() { stack.Pop(); }
// It is here that it verifies whether the CustomStack meets the expected behaviour.
public void ThenIShouldGetAnError() {
Assert.Throws<IndexOutOfRangeException>(delegate {
stack.Pop();
});
}
private CustomStack<string> stack;
}
public class CustomStack<T> {
public T Pop() {
if (stack.Count == 0)
throw new IndexOutOfRangeException("Cannot pop from an empty stack!");
T item = stack[stack.Count-1];
stack.RemoveAt(stack.Count-1);
return item;
}
private ArrayList stack = new ArrayList();
}
I think that leaving a comment in the When method is correct, so that the business requirement doesn't lack any information, and on the code behind, I put it clear what my intention is exactly by commenting.
What do you think? Any other ideas why I shouldn't make it?
There is another trick that you can use where the bindings help make the feature's meaning a little clearer. In this case, let's start at the end.
Then I should get an error
Your problem is a basically here, you know want an error, but you don't know how to get it. In fact you've already missed it, the error has already occurred in the When step, and in your code example, you moved the action into the then step just so you could get the error.
But what if keep the when performing the action amd re-express our then to reflect what really happens
Then I should have had an error
Seems a trivial change but now our feature reflects that the error should have been associated with the When step and we are simply evaluating it later, and that is something we can code. We just need something to remember the error in the when and deliver it to the then.
private Exception errorFromWhen = null;
public void WhenIPopFromIt()
{
try
{
stack.Pop();
}
catch(Exception ex)
{
errorFromWhen = ex;
}
}
public void ThenIShouldGetAnError()
{
errorFromWhen.ShouldNotBeNull();
errorFromWhen.ShouldBe<IndexOutOfRangeException>();
}
SpecFlow has absolutely no problems with this, in fact due to its mini Dependency injection system, you can even pass this state between binding classes if necessary.
May a scenario not have a When in BDD?
In Specflow, neither given, when or then are mandatory.
However in your example, I don't believe this is a good use of Specflow and BDD. In this answer here Marcus states:
"BDD is about ensuring that we're building the right thing, TDD is about ensuring that we're building it right."
In your example the scope of what is being tested i.e. the CustomStack, should be tested via TDD. It is the end solution that makes use of the CustomStack should be tested via BDD (and hence SpecFlow) e.g. if this CustomStack was being exercised via a certain action on a website.
This answer is also pertinent to your question.

Role-based navigation display in MVC4 Bootstrap Sample

How are you supposed to conditionally display menu items based on roles in the Bootstrap Sample project? I was thinking of doing the following
Implement INavigatonRouteFilter - really just implementing the shouldRemove(Route navigationRoutes) method - by getting the default controller/action for the route and seeing if the user is authorized
Call NavigationRoutes.Filters.Add(myAuthorizationFilter) after configuring the NavigationRoutes in App_Start
There are two problems I see with this approach:
I don't actually know how to do the first step unless I add in a bunch of conditional statements to check for Controller's name explicitly
This seems like it could make NavigationRoutes.Filters very hard to deal with once there are a lot of filters or a desire for more modularity later on
I don't know that I've explained the problem clearly enough, but basically I want to use what is provided in the Bootstrap sample to implement authorization-based navigation menu display if at all possible. Using INavigationRouteFilter just seemed like the most natural way to do so.
For those looking for an answer or at least a quick fix.
Here's what I've come up with after 5 minutes and I most certainly haven't though about any side effects this may have.
routes.MapNavigationRoute<HomeController>("Index", c => c.Index())
.FilterRoute(() => !WebSecurity.IsAuthenticated);
You can either do all your filtering in your call to FilterRoute() or you can add more extension methods to save you some characters.
I'm thinking of .RequireRole("Adiministrators"); that calls WebSecurity.RequireRoles() in turn (or HttpContext.Current.User.IsInRole()) etc.
public static NavigationRouteBuilder FilterRoute(this NavigationRouteBuilder builder, Func<bool> func)
{
var currentRoute = builder._parent;
NavigationRoutes.Filters.Add(new BootstrapAuthorizationFilter(builder, x =>
{
if (x == currentRoute)
return func();
else
return false;
}));
return builder;
}
and BootstrapAuthorizationFilter is just a class implementing INavigationRouteFilter that calls func() in its ShouldRemove() method
public class BootstrapAuthorizationFilter : INavigationRouteFilter
{
private NavigationRouteBuilder builder;
private Func<NamedRoute, bool> func;
public BootstrapAuthorizationFilter(NavigationRouteBuilder builder, Func<NamedRoute, bool> func)
{
this.builder = builder;
this.func = func;
}
public bool ShouldRemove(Route navigationRoutes)
{
if (navigationRoutes is NamedRoute)
return func(navigationRoutes as NamedRoute);
return false;
}
}
Clearly nothing fancy and I'm not sure if I'd use it in production.
But I think is simple enough and works (for the cases I tested).
Having said that, I hope the new routing functionality is going to be released soon :)

MvvmCross vNext: ObservableColletion is defined in an assembly that is not referenced

I have got my PCL model to build now, which took a bit of time making plug-ins, however now in my Android UI project I get two errors when building it.
First error is:
The type 'System.Collections.ObjectModel.ObservableCollection`1<T0>' is defined in an assembly that is not referenced.
You must add a reference to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e,
Retargetable=Yes'. C:\ENM\Main\src\prod\Mobile\Stakeholder\UI.Android.vNext\Views\LocationsMapView.cs 40 32 UI.Android.vNext
The second error is:
foreach statement cannot operate on variables of type
'System.Collections.ObjectModel.ObservableCollection`1<BK.EMS.Stakeholder.Model.ViewModels.LocationViewModel>'
because 'System.Collections.ObjectModel.ObservableCollection`1<BK.EMS.Stakeholder.Model.ViewModels.LocationViewModel>'
does not contain a public definition for 'GetEnumerator'
C:\ENM\Main\src\prod\Mobile\Stakeholder\UI.Android.vNext\Views\LocationsMapView.cs 40 32 UI.Android.vNext
I have referenced the System.Windows assembly from the System.Windows.Droid project, which is supposed to forward ObservableCollection<>.
The lines where the error occurs:
private void AddLocationOverlays()
{
if (_itemizedOverlay.Size() > 0) _itemizedOverlay.ClearOverlayItems();
RunOnUiThread(() =>
{
foreach (var location in ViewModel.Locations)
{
_itemizedOverlay.AddOverlayItem(location);
}
_mapView.Invalidate();
});
}
The Locations property in my ViewModel looks like this:
public ObservableCollection<LocationViewModel> Locations
{
get { return _locations; }
set
{
_locations = value;
RaisePropertyChanged(() => Locations);
}
}
Nothing too complicated and works fine in the non-PCL models...
So how do I get around and fix this?
We now have a solution to this problem - see fix from Daniel Plaisted in Portable Class Library strong assembly reference problems in MonoTouch/MonoDroid
This fix is checked in at https://github.com/slodge/MvvmCross/commit/f6a88048467838e5ac5ca687744dc0b2d1958aa8
Update : See other answer. It appears we now have a solution to this problem!
I believe this is linked to this problem - Portable Class Library strong assembly reference problems in MonoTouch/MonoDroid
Which is linked to: https://github.com/slodge/MvvmCross/issues/41
This is raised with Xamarin as a bug: https://bugzilla.xamarin.com/show_bug.cgi?id=8035 and
I'm afraid I don't understand the recommended Strong Signing solutions right now.
Please upvote the bug report to alert the Microsoft PCL and Xamarin teams about this. The MS and Xamarin teams are talking to each other on this (albeit through me!), and I am hopeful we will find a way for either Microsoft or Xamarin to ship some signed DLLs.
In the meantime, some possible workarounds are:
Use IEnumerable access instead of ObservableCollection - the collection can still be an ObservableCollection instance, just don't reference it as an ObservableCollection in the UI code.
Try putting your iterating code in a class library rather than in an application project - bizarre as it feels, the compiler seems perfectly happy building the same code when its in a library rather than in an application
Try building in MonoDevelop with the Mono compiler - this doesn't seem to have the same strong name reference checks.
Looking at your sample code I would just try:
private ObservableCollection<LocationViewModel> _locations;
public IEnumerable<LocationViewModel> Locations
{
get { return _locations; }
set
{
if (value != null && !(value is ObservableCollection<LocationViewModel>)
{
throw new Exception("You must Set an ObservableCollection");
}
_locations = (ObservableCollection<LocationViewModel>)value;
RaisePropertyChanged(() => Locations);
}
}
then AddLocationOverlays could stay the same.
The only problem with this would be if you then wanted to bind to INotifyCollectionChanged on this collection - but I think you can find a way around this too if needed - e.g. you could somehow expose another INotifyCollectionChanged hook, or you could try using a hack involving an intermediary class library.
I accept that for now these are workarounds not solutions :/

Is there an easy way to view the contents of a FormCollection?

When testing/debugging an ASP.NET MVC application, it's common to submit a form and then check all of the name/value pairs to make sure
All of the expected keys are present
All of the expected keys have the expected values
Debugging in Visual Studio is great for checking if a single variable (or even a simple object) contains the expected value(s), and as far as a FormCollection, it's pretty easy to check the presence of the keys. However, checking the key/value pairings in a FormCollection is a huge hassle. Is there a simple way to get Visual Studio to list the keys and their values side-by-side for a quick check?
Just a quick custom check
public void Edit(FormCollection team)
{
System.Text.StringBuilder st = new System.Text.StringBuilder();
foreach (string key in team.Keys)
{
st.AppendLine(String.Format("{0} - {1}", key, team.GetValue(key).AttemptedValue));
}
string formValues = st.ToString();
//Response.Write(st.ToString());
}
You can then place your mouse on formValues to check the key-value. Clicking the magnifier would reveal the Key-Values
Take a look at Glimpse, it is on nuGet. It exposes lots of information and is invaluable with AJAX and MVC development.
At its core Glimpse allows you to debug your web site or web service right in the browser. Glimpse allows you to "Glimpse" into what's going on in your web server. In other words what Firebug is to debugging your client side code, Glimpse is to debugging your server within the client.
Here is a method that outputs the collection to the Immediate window in a readable key/value pair format, one pair per line of output:
private void DebugWriteFormCollection(FormCollection collection)
{
foreach (string key in collection.Keys)
{
string value = collection.GetValue(key).AttemptedValue;
string output = string.Format("{0}: {1}", key, value);
System.Diagnostics.Debug.WriteLine(output);
}
}
Add that to your code and set a breakpoint. When you hit the breakpoint, call the method from the Immediate window:
DebugWriteFormCollection(collection);
Result:
Key1: Value1
Key2: Value2
Key3: Value3
etc.

Resources