What kind of data is it? - asp.net-mvc

maybe my question can seem very silly, but i am a beginner and i am doing an exercise from a book about MVC and ASP.NET.
I don't understand the meaning of the second rows:
[LargerThanValidationAttribute(18)]
public VoterAge { get; set; }
because i see that VolterAge has not a type, and i read the message from VS that VolterAge doesn't exist in this context, and i don't understand the meaning of it. What have i to use for VolterAge? A field in a DataBase? What type of data is it?
Thank you to all.
P.S. LargerThanValidationAttribute is an extension of ValidationAttribute.

You're definitely missing a type in that property declaration.
At a guess, given it's 'VoterAge' and by the value supplied in the LargerThanValidationAttribute I would say it's missing int
It should be
[LargerThanValidationAttribute(18)]
public int VoterAge { get; set; }
This declares that property to be of type int

Related

EF Core Find breaks with Nullable Id

Using EF Core 1.1 and Asp Core 1.1 on Mac
With a model like
public class Model {
public int? Id { get; set; }
public string OtherProp { get; set; }
}
And an action
public class ModelController
{
public Model Get(int? id)
{
DbContext.Set<Model>.Find(id)
}
}
Accessing the url /model/10 fails with a message The key value at position 0 of the call to 'DbSet<Model>.Find' was of type 'int', which does not match the property type of 'Nullable<int>'
The error message is clear but my question is if there is a way to make this work, it seems like a very common use case and one that used to work in previous versions.
I tried casting id to int? but it didn't work. Any ideas?
Also, in case it's useful this is the line that's breaking in EF
Looking at the code you've already linked: this cannot work, since the CLR gives you always the underlying type for a null-able instance. (Don't know why, had similar issues before...)
In code: typeof(int?) != ((int?)1).GetType().
Thus, comparing the type of the property (int?) and the type of the argument will always fail. You have to ask the EF Core team to add support for null-able types for that.
Related: Nullable type is not a nullable type?

Getting timestamp() value using C# client

Just a quick one, I have a node that gets a value set using the value of timestamp(), when I query for the node using
public List<Thing> ListThings()
{
return client.Cypher
.Match("(thing:Thing)")
.Return<Thing>("thing").Results.ToList();
}
I have a class called Thing that looks like this:
public class Thing{
public string name {get; set;}
public int id {get;set;}
public DateTimeOffset timestamp{get;set}
}
We create the 'thing' ahead of time by using:
Create(thing:Thing{id:6,name:'thing1', timestamp:timestamp()}) return thing
I get every value back apart from timestamp when calling from my script, which is a little annoying, any ideas? I get all the values back using the query in Neo4j browser, so I was wondering if I was actually doing something wrong?
Thanks
Tatham is right, the timestamp() returns a long that's not convertible into DateTimeOffset or DateTime. One of the problems is that the returned value is Milliseconds since 1/1/1970, so you need to calculate that, unfortunately, JSON.Net can't do that automagically.
If you can change your Thing class you could have a property that isn't serialized but is calculated by the Timestamp property, something like this:
public class Thing
{
private static DateTime _epoch = new DateTime(1970, 1, 1);
public string id { get; set; }
public string name { get; set; }
private long _ts;
public long timestamp
{
get { return _ts; }
set
{
_ts = value;
TimestampAsDateTime = _epoch.AddMilliseconds(_ts);
}
}
[JsonIgnore]
public DateTime TimestampAsDateTime { get; set; }
}
The TimestampAsDateTime property would only ever be available in your code.
If you go to the Neo4j console and just run RETURN timestamp(), you'll see the result is a number like 1440468541547. That can't be de-serialized to a DateTimeOffset, especially as there's no offset component. You'll need to use a different type in C#: probably long, or maybe DateTime.
Thank you for your excellent answers, you solved the problem, but I am using a slightly overlooked (on my part) solution.
As the data type for timestamp() is long I am just going to return that from the service. We have the ability to handle that perfectly using the clients in-built Date object.
It was a mistake on my part, I wrongly assumed that timestamp would have been DateTime, but then I got an error about it and was advised to use DateTimeOffset, which I did, never really considered long as an option.
Please remember I am from a MSSQL background and some things, although easier to do, take a different perspective to grasp.
Thanks to you both though, appreciate the time taken to assist.

Customizing model binding error messages in ASP.NET MVC 3

I'm using ASP.NET MVC 3 with Fluent Validation. I'd like all my error messages to be worded and formatted the same, whether they are validation error messages or model binding error messages.
Let's say I have the following view-model:
[Validator(typeof(PersonValidator))]
public class Person
{
[ScaffoldColumn(false)] public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
To validate this using Fluent Validation, I might use something like this:
public class EditorValidator : AbstractValidator<EditorModel>
{
public EditorValidator()
{
RuleFor(model => model.Month.Value).InclusiveBetween(0, 120)
}
}
If the user enters "abc" for Age, this causes a model binding error, not a validation error. This is because "abc" is not an int. The system never even gets to the point of asking whether "abc" is between 0 and 120, because "abc" cannot be stored in Age.
This is fine and makes sense. The problem is that the resulting error message is:
The field Age must be a number.
I'd like the message to be formatted and worded like other error message produced by Fluent Validation. In this case, I would like:
'Age' must be a number.
I realize this is only a subtle difference, but I'd like to have control of model binding error messages.
How can I customize the model binding error messages to match the error messages used by Fluent Validation?
I'm not sure if there's another way to do this, but I use Data Annotations Extensions, also available via NuGet (Install-Package DataAnnotationsExtensions.MVC3) for this exact type of thing. This package will give you an IntegerAttribute, and from there you can specify an error message like so:
[Integer(ErrorMessage = "'Age' must be a number.")]
public int Age { get; set; }
Take a look at my answer here:
How to change 'data-val-number' message validation in MVC while it is generated by #Html helper
Actually, it's a very common question that you asked, so you should've googled the stackoverflow prior to posting.

Form Action Posting null

My baldness is growing more rapidly than it should be. I first posted this question a couple days ago. I now know the problem and have it working... sort of. Another problem surfaced in it's place.
To solve the previous problem, I manually created the name to requestedDays[{0}].DateOfLeave where {0} was a Guid. This allowed my controller to properly receive the List<> of values.
Using this article's method, the name generated is requestedDays[{0}].DayRequested.DateOfLeave which my controller doesn't properly receive because the name has the class in it, DayRequested.DateOfLeave.
[Authorize, HttpPost]
public ActionResult Create(LeaveRequest leaveRequest, List<DayRequested> requestedDays)
{
}
I have tried to figure out work-arounds with the manual generation, but nothing I have tried works thus far. You can see my validation method here. I do know about the second part of Sanderson's article on validation however, it is quite hard to validate something that isn't being passed into the method.
This is my ViewModel I am using in my partial view.
public class LeaveRequestRow
{
public LeaveRequestRow(DayRequested dayRequested, List<SelectListItem> leaveRequestType)
{
this.DayRequested = dayRequested;
this.LeaveRequestType = leaveRequestType;
}
public List<SelectListItem> LeaveRequestType { set; get; }
public DayRequested DayRequested { set; get; }
}
Does anyone have any ideas on how to proceed? Should I convert my dropdown to a jQuery build control and stop using the ViewModel?
Binding 1-N controller arguments of complex types can be kind of tricky.
Your code examples are not meshing with my fried end of day Friday brain but I'll give it a shot.
Assuming the LeaveRequest class looks like this:
public class LeaveRequest {
public string Text { get; set; }
public string Number { get; set; }
}
The posted form keys must be:
leaveRequest.Text
leaveRequset.Number
That is the easy part. The 1-N binding of a list of DayRequested gets a little weird. Say the DayRequested object looks like this:
public class DayRequested {
public string Words { get; set; }
public string Data { get; set; }
}
Your posted form keys look like:
requestedDays[0].Data
requestedDays[0].Words
requestedDays[1].Data
requestedDays[1].Words
requestedDays[2].Data
requestedDays[2].Words
requestedDays[3].Data
requestedDays[3].Words
The default MVC binder should then trun all 10 form values into your two method arguments ... a POCO and a List of POCOs.
I have solved this, though not as elegantly as I had hoped. All TextBoxFor had to be changed to TextBox along with the addtional changes needed with doing this. The names then were correctly generated and I could move on. This did break the ability for the validation message to appear next to the field, though ValidationSummary still does work. I will be working on fixing that later on and post code samples and a solution on my website.

Cannot delete entity with ComplexType property (Entity Framework 4)

This has been driving me nuts for a week now.
I have a class that looks like this:
public class SuggestionVote
{
public virtual int ID { get; set; }
public virtual Suggestion Suggestion { get; set; }
public virtual User User { get; set; }
public virtual VoteTypeWrapper VoteType { get; set; }
public virtual DateTime DateVoted { get; set; }
// Equality overrides omitted
}
VoteTypeWrapper is actually an enum wrapper based on an article on how to fake enums in Entity Framework 4 and looks like this:
public class VoteTypeWrapper
{
private VoteType _type;
public int Value
{
get { return (int)_type; }
set { _type = (VoteType)value; }
}
public VoteType EnumValue
{
get { return _type; }
set { _type = value; }
}
public static implicit operator VoteTypeWrapper(VoteType voteType)
{
return new VoteTypeWrapper { EnumValue = voteType };
}
public static implicit operator VoteType(VoteTypeWrapper voteTypeWrapper)
{
return voteTypeWrapper == null ? VoteType.NotVoted : voteTypeWrapper.EnumValue;
}
}
with the VoteType enumeration being:
public enum VoteType
{
Up,
Down,
NotVoted
}
I've also defined a ComplexType in the model designer:
<ComplexType Name="VoteTypeWrapper" >
<Property Type="Int32" Name="Value" Nullable="false" />
</ComplexType>
The voting system I'm implementing works somewhat like StackOverflow's voting system: The user can vote up or down; voting a second time undoes the previous vote, and voting in the opposite direction (i.e., down when previously voted up) undoes the vote as well.
Now for the problem. Voting once works like a charm and all the values are correctly saved to the database. Undoing a vote, however, refuses to work. To undo a vote I basically mark the vote to undo for deletion and then call SaveChanges on the context.
As soon as I do that an InvalidOperationException occurs giving me the following message:
The entity of type 'System.Data.Entity.DynamicProxies.SuggestionVote_4A3949F5B95E9A51567509467230FD7CEA0FB7761C3AC9C8C2BBC62BCAA033AF'
references the same complex object of type 'Web.Model.VoteTypeWrapper' more than once.
Complex objects cannot be referenced multiple times by the same entity.
I just don't get it. Down anyone know what I could be doing wrong? I've been Googleing for day but to no avail
Well, I've finally decided to work around it but simply mapping an int property instead of a ComplexType. I have also added a (non-mapped) helper property to avoid having to cast constantly from int to VoteType.
I would still love to get an answer for my problem so if you can help it I would appreciate it. I'll give it a couple of days before I mark my own answer as correct.
EDIT: Since I've gotten no answer whatsoever to this, m marking my own answer as good.
I've just encountered the same problem. I have a class that contains a complex type that contains another complex type. Let's call them Class1, Complex1 and ChildComplex. My scenario is the following (I don't know if it matches yours, but the error message is exactly the same).
I retrieve from the context an instance of Class1 and perform a change in a property of Complex1. I then call SaveChanges to the context and get the same exception :
The entity of type '<Class1>' references the same complex object of type '<Complex2>' more than once.
Complex objects cannot be referenced multiple times by the same entity.
I have not found a decent workaround other than cloning the Complex1 instance, replacing the cloned version in the Class1 instance and then making the change. That way EF does not complain that it's the same complex object.
This is a really strange behaviour. If I have time (around 2038) I'll try to isolate it and report it to MS, smells like a bug...
I've just been searching for this same issue, but I've just realized I was misreading the error. Its not complaining that your entity has two properties of the same type, its complaining that your storing the 'exact' same object of that type in both properties.
In my case I was doing a lookup on an table to get my complex type, and I now realize that if the lookup returned the same value it would be the same object.
I fixed this by creating a new object of my complex type and setting its values to the same as the lookup.

Resources