Required attribute in Data Annotations - asp.net-mvc-4

I'm using MVC 4 and Entity Framework 5 to build my website. To validate data in client side, I use Data Annotations. Here is my property in View Model:
public int Salary { get; set; }
As you can see, I don't put any annotation there. Also, in my database, the Salary column was marked as Allow null.
My problem is whenever I submit my form, the ModelState is invalid because of this property. It thinks that this property is required and display error on client side.
Do you know what causes the problem? Please help me. Thanks a lot.

The issue you are having is because the default constructor initializes the property to 0. If you want to allow nulls do this:public int? Salary { get; set; }

Related

APS.NET core 2.2 Entity framework db migration looking for primary key

I am trying to run DB migration on my DAL project but receiving an error that my entity does not have key defined which has ?! could anyone help, please.
For posterity, please post your code and not an image.
Entity Framework will work from properties defined in your model, and the Id property is set up by convention. However you need to have the Id set up as a property for it to work correctly, and right now you have it as a field.
Change
public int Id; to public int Id { get; set; } and try again and you should be in business.

Filter contents of lazy-loaded collection with NHibernate

I have a domain model that includes something like this:
public class Customer : EntityBase<Customer>, IAggregateRoot
{
public IList<Comment> Comments { get; set; }
}
public class Comment : EntityBase<Comment>
{
public User CreatedBy { get; set; }
public bool Private { get; set; }
}
I have a service layer through which I retrieve these entities, and among the arguments passed to that service layer is who the requesting user is.
What I'd like to do is be able to construct a DetachedCriteria in the service layer that would limit the Comment items returned for a given customer so the user isn't shown any comments that don't belong to them and are marked private.
I tried doing something like this:
criteria.CreateCriteria("Comments")
.Add(Restrictions.Or(Restrictions.Eq("Private", false),
Restrictions.And(Restrictions.Eq("Private", true),
Restrictions.Eq("CreatedBy.Id", requestingUser.Id))));
But this doesn't flow through to the lazy-loaded comments.
I'd prefer not to use a filter because that would require either interacting with the session (which isn't currently exposed to the service layer) or forcing my repository to know about user context (which seems like too much logic in what should be a dumb layer). The filter is a dirty solution for other reasons, too -- the logic that determines what is visible and what isn't is more detailed than just a private flag.
I don't want to use LINQ in the service layer to filter the collection because doing so would blow the whole lazy loading benefit in a really bad way. Lists of customers where the comments aren't relevant would cause a storm of database calls that would be very slow. I'd rather not use LINQ in my presentation layer (an MVC app) because it seems like the wrong place for it.
Any ideas whether this is possible using the DetachedCriteria? Any other ways to accomplish this?
Having the entity itself expose a different set of values for a collection property based on some external value does not seem correct to me.
This would be better handled, either as a call to your repository service directly, or via the entity itself, by creating a method to do this specifically.
To fit in best with your current model though, I would have the call that you currently make to get the the entities return a viewmodel rather than just the entities;
public class PostForUser
{
public Post Post {get; set;}
public User User {get; set;}
public IList<Comment> Comments}
}
And then in your service method (I am making some guesses here)
public PostForUser GetPost(int postId, User requestingUser){
...
}
You would then create and populate the PostForUser view model in the most efficient way, perhaps by the detached criteria, or by a single query and a DistinctRootEntity Transformer (you can leave the actual comments property to lazy load, as you probably won't use it)

EF : MVC : ASP: TPH Error - Store update, insert, or delete ... number of rows (0). Entities ... modified or deleted ... Refresh ObjectStateManager

Error Message: "Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries."
Hello All,
I've created a Code First TPH(Table Per Hierarchy) within MVC and EF with a SQL compact db.
Here's the Class diagram/Hierarchy:
Class Diagram
Client and SalesRep both inherit the BaseUser class. The Key is "UserID" and it's coded with the Data Annotation [Key](I'm aware that 'ID' should set it as well)
Here's where I'm at: I can seed the database with a few entries. When I try to set the "UserID" in the seeding method it seems to ignore it and just apply the UserID in numerical order...(Seems ok to me?)
furthermore here's my DbContext
public class SiteDB:DbContext
{
public DbSet<BaseUser> AllUsers { get; set; }//enable TPH
public DbSet<SalesRep> SalesReps { get; set; }
public DbSet<Client> Clients { get; set; }
}
Next,
I have created a controller for Clients -> ClientsController with strongly typed Razor Views. With this. I now have a CRUD for the Clients. I can create new Clients without any issue, but when I try to edit a Client entry, I get the error message stated above.
I did notice something interesting I stepped through the code and the error is happening on the db.SaveChanges();
When the client is passed back into the ActionResult Edit method the UserID=0! Bizarre? I'm not sure if this is a bug or if it's an actual issue that's causing this.
UserID=0
Your help with this is appreciated. Thanks!
To modify an entity you need to get it from the database: when you pass back the modified values in the Edit action you need to retrive the entity from the db object, getting it by ID, apply the modified values and save it.
Here an example:
public ActionResult Edit(int id, MyModel model){
using (SiteDBdb = new SiteDB()){
Client cl = (from c in db.Clients where c.id == id select c).First();
cl.MyProp = model.MyProp;
...
db.SaveChanges();
}
...
}

How to force RIA Services to include a sub-entity in one Query method but not another

Here's the scenario:
I've got an association between "Groups" and "Users, represented by a "UserGroupAssignment" object.
public class UserGroupAssignment
{
[Key]
public virtual long Id { get; set; }
[Association("UserAssignmentToUser", "UserId", "Id", IsForeignKey = true)]
public virtual User { get; set; }
[Association("UserAssignmentToGroup", "GroupId", "Id", IsForeignKey = true)]
public virtual Group { get; set; }
public virtual bool IsPrimary { get; set; }
public virtual DateTime? ValidFrom { get; set; }
public virtual DateTime? ValidTo { get; set; }
}
I have two business logic methods, GetUserAssignmentsForGroups and GetGroupAssignmentsForUsers that I return the assignments with the User and Group properties populated respectively. i.e. GetUserAssignmentsForGroup takes a GroupId and returns the assignments for that Group with the User property populated.
What I want is to expose those two methods as domain query methods like so:
[Query]
public IQueryable<UserGroupAssignment> GetAssignmentsForGroupWithUsers(long groupId)
{
return this.businessLogic.GetUserAssignmentsForGroups(groupId);
}
[Query]
public IQueryable<UserGroupAssignment> GetAssignmentsForUserWithGroups(long userId)
{
return this.businessLogic.GetGroupAssignmentsForUsers(userId)
}
My problem is that whilst the business logic methods return the correctly populated Assignments via NHibernate, RIA Services is NOT passing the sub-entities (User or Group) across the wire.
I don't want to use [Include] attributes on the User or Group properties of the UserAssignment class, as I want to minimise the payload over the wire - I don't want to send the group over when I'm only interested in the User of each UserAssignment, for example.
So my question is this:
How do I tell RIA services to
explicitly include User sub-entities
in one domain query method and Group
sub-entities in the other?
Remember, I'm using NHibernate at the back end and custom query methods in the RIA Services, so can't use the EF-style include in the client query.
Thanks
Joel
you should apply the [Include] attribute in the metadata class. then create one domain service method for fetching data without properties included, and a separate method for fetching data with properties included.
You might find this thread helpful in understanding how [Include] attribute works.
Old question, but still interesting. Did you find a solution ?
As far as I know of WCF RIA Architecture it isn't so easy.
An easy and dirty way could be to override the Query method, force the enumeration of the IQueryable being returned (I guess you're using LINQ to nHibernate, in which case, good luck) then examine the HttpContext (you're using WCF RiaServices so you MUST have aspNetCompatibility turned on) and set to null the reference that you don't want to send over the wire (User or Group).
Anyway this way FORCE you to use the [IncludeAttribute]. However I don't see any reasonable route that avoid its use, and this way allow you to send the entity over the wire just when you need to.
IMO I belive that in order to totally avoid the use of [Include] you must rollout your own serializer serverside and deserializer clientside or change the UserGroupAssignment entity so that the user property become a string containing the serialized User (or Group) that you decide to valorize or not according your method.
Please let us knows if you already found a solution, the question is interesting.

C# WCF data contract partial class - new field in 2nd partial class not being picked up

I have a WCF service in which I have some data contracts. I'm using web service software factory, which uses a designer to create all the message and data and other contracts, and it creates them as partial classes. When the code is regenerated the classes are recreated.
using WcfSerialization = global::System.Runtime.Serialization;
[WcfSerialization::CollectionDataContract(Namespace = "urn:CAEService.DataContracts", ItemName = "SecurityItemCollection")]
public partial class SecurityItemCollection : System.Collections.Generic.List<SecurityItem>
{
}
The data contract is a generic List of a custom class which was working fine. However I now want to add a property to this class, so I added this partial class in the same namespace:
public partial class SecurityItemCollection
{
public int TotalRecords { get; set; }
}
This seems to work fine on the service side, but when I compile and then update the service reference from the client, the class doesn't have the new property i.e. when it serialises it and recreates it on the client side, it's missing the new property. Anyone know why this is?
TIA
EDIT:
Ok this is officially driving me nuts. The only thing I can see is that it is using the CollectionDataContract attribute instead of DataContract. Does this somehow not allow data members in the class to be serialised? Why would that be? It is working fine on the service side - I can see and populate the values no problem. However when I update the service refernce on my client there's nothing, just the colelction class without the data member.
Try to add the DataMember attribute to the TotalRecords property
Ok after much searching I finally found out that this isn't allowed i.e. classes marked as CollectionDataContract can't have data members. Why this is I have no idea but it cost me several hours and a major headache. See link below:
WCF CollectionDataContract and DataMember
I know this is old but it kept coming up when I searched on this subject.
I was able to get this working by adding a "DataMemberAttribute" attribute to the property. Below is a code example.
public partial class SecurityItemCollection
{
[global::System.Runtime.Serialization.DataMemberAttribute()]
public int TotalRecords { get; set; }
}