RIA Services validation order - silverlight

So I have some validations in my metadata like the following:
internal sealed class Metadata
{
[Key]
[ReadOnly(true)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string CountryCode { get; set; }
[CustomValidation(typeof(PCNValidator), "SetNumber")]
public string Number { get; set; }
}
I have some code to validate the Number property as you can see here, but I need the other Required properties of some of the attributes to fire first.
How can I achieve that?

You could make your PCNValidator return success until name and countryCode have been completed. Once that condition had been satisfied you could then do the remaining validation checks on Number. Not a wonderful solution but it does allow for your ordering requirement.

As far as I could find out, the answer to this question is NO, there's no way to tell an order in property-level validation.
Having said that, every Required property is validated before the others.
What I did in order to achive what I wanted was adding a type validator for the class. Type validators are always fired after property validators, which is exactly what I needed.
here's my code:
[MetadataType(typeof(PCN.Metadata))]
[CustomValidation(typeof(PCNValidator), "ValidateInsert")]
public partial class PCN : IValidate
{
internal sealed class Metadata
{
[Key]
[ReadOnly(true)]
public int Id { get; set; }
[Required(AllowEmptyStrings=false)]
public string Name { get; set; }
[Required]
public string CountryCode { get; set; }
}
}

Related

DevExpress LookUpEdit Column Binding To Navigation Property

Good day!
I'm having an issue with the DevExpress LookUpEdit I can't figure out what the problem is.
I'm use Entity Framework list as a datasource.
public partial class provider_scheme : BaseEntity
{
public provider_scheme()
{
}
public int Provider_Scheme_RowID { get; set; }
public int Currency_RowID { get; set; }
public string Provider_Scheme_Name { get; set; }
public virtual currency currency { get; set; }
}
public partial class currency : BaseEntity
{
public currency()
{
provider_scheme = new HashSet<provider_scheme>();
}
public int Currency_RowID { get; set; }
public string Currency_ISOCode { get; set; }
public virtual ICollection<provider_scheme> provider_scheme { get; set; }
}
I'm setting the Datasource property of the LookUpEdit to IEnumerable<provider_scheme>, and setting up two column field names in my LookUpEdit. One for 'Provider_Scheme_Name' and one for 'currency.Currency_ISOCode'. But for some reason only the 'Provider_Scheme_Name' column values are showing. I've also checked and the 'currency' navigation property is being loaded.
Thanks in advance for your help
A bit late for an answer, but you might consider using the GridLookupEdit control instead. It permits adding all the columns you want

Business Rule errors not going away when data is valid

I am using Orc.FluentValidation and I have:
[ValidatorDescription(nameof(Customer), ValidationResultType.Error,
Orc.FluentValidation.ValidationType.BusinessRule)]
public class CustomerBusinessRuleValidator : AbstractValidator<Customer>
{
public CustomerBusinessRuleValidator()
{
RuleFor(x => x.Addresses).Must(x => x != null && x.Count > 0 && x.Any(add => add.IsCurrent))
.WithMessage("Customer object is required to have at least 1 current address.");
}
}
CustomerAddress
public class CustomerAddress : Entity
{
[DomainSignature] public Address Address { get; set; }
[DomainSignature] public Lookup AddressType { get; set; }
[DomainSignature] public bool IsCurrent { get; set; }
}
Customer
public class Customer : Entity
{
[DomainSignature]
public string Code { get; set; }
public Gender Gender { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public DateTime DateOfBirth { get; set; }
public Lookup PlaceOfBirth { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public ICollection<CustomerAddress> Addresses { get; set; }
public Lookup Occupation { get; set; }
public IdDocument Id1 { get; set; }
public IdDocument Id2 { get; set; }
}
On the View even after a CustomerAddress with IsCurrent = true is added for the Customer, the message still shows. Also, I am not sure why some field-bound controls show the error and others not _this is not a field validation rule.
Is there like a method call to be done after adding the CustomerAddress to the Addresses collection?
i.imgur.com/eecAFuJ.png
Make sure you raise a property changed on the whole collection for error validation (e.g. RaisePropertyChanged(nameof(MyCollection)), otherwise the UI can't update the validation results.
Also, I am not sure why some field-bound controls show the error and
others not _this is not a field validation rule.
This is probably because of the default styles you are using. For most of the controls, Orchestra creates an error template (decorator), but not every control had this. We've been working on adding these last week, so I recommend to try out the latest alpha of Orchestra & Orc.Controls.
Also make sure to set ValidateOnDataErrors and NotifyOnValidationErrors on the binding to show the validation in the UI.

How to to make entity relationships in WEB API database?

I'm making a task management tool using AngularJS for the frontend and ASP.NET WEB API 2 for the backend. I have two entities in the database, a "Task" and a "Type". Each task has one type associated. The user fills a form when he can create a new task, and he has to select a type for that task.
Here's the C# code:
// KBTM_Task.cs file
public class KBTM_Task
{
public int ID { get; set; }
public string TaskID { get; set; } // User defined ID
public string Title { get; set; }
public string Description { get; set; }
}
// KBTM_Type.cs file
public class KBTM_Type
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
So my question is: how do I "connect" the two in the database? What I mean is, let's say I want to POST data to the database. I have to make two POSTs, right? One for the Task and one for the Type, since they're two separate entities.
But since they're stored with two different IDs, how do I know that a certain task has a certain type? In other words, if I send a GET request to KBTM_Task, how do I get the type of that task?
Modify your KBTM_Task entity to include the Type Id and foreign key relationship
public class KBTM_Task
{
public int ID { get; set; }
public string TaskID { get; set; } // User defined ID
public string Title { get; set; }
public string Description { get; set; }
public int TypeID { get; set; }
[ForeignKey("TypeID")]
public virtual KBTM_Type Type { get; set; }
}
This way when you get the data from the API your task object will already include the key ("TypeID") that can be updated and related object ("Type") that you can access its properties (Name, Description, ...).
When you update TypeID on the client object (model) you can simply push the updated task object to the API using $http.put() to handle the database update.
1) Add foreign key using fluent api (or data annotation)
// KBTM_Task.cs file
public class KBTM_Task
{
public int ID { get; set; }
public string TaskID { get; set; } // User defined ID
public string Title { get; set; }
public string Description { get; set; }
public int KBTM_TypeID {get;set}
public virtual KBTM_Type {get; set}
}
// KBTM_Type.cs file
public class KBTM_Type
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public KBTM_Task KBTM_Task { get; set;}
}
Add the following in the class inheriting from DbContext
public class KbtmContext : DbContext
{
...
//public virtual DbSet<KBTM_Task> KbtmTasks {get; set;}
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure KBTM_TypeID as FK for KBTM_Task
modelBuilder.Entity<KBTM_Task>()
.HasRequired(k => k.KBTM_Type)
.WithRequiredPrincipal(ad => ad.KBTM_Task);
}
}
2) If exposing the entity class in API response or request then you need to exclude navigation property from being serialized.
// KBTM_Task.cs file
public class KBTM_Task
{
...
[JsonIgnore]
public virtual KBTM_Type Type { get; set; }
}
To use the [JsonIgnore] atttribute use Install-Package Newtonsoft.Json in package manager console.(One of the popular solutions to manage serialization)

When Adding Data Annotation Attribute it's throwing Exception

public class Employee {
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public decimal Salary { get; set; }
public string Email { get; set; }
}
public class EmployeeContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
}
When I'm adding Data Annotation [Required(ErrorMessage = "Employee Name is required")] to the Name property it's throwing an InvalidOperationException. As I was trying to fix the bug I'm getting these suggestions online:
It means one of your classes use in the EmployeeContext has changed, but the database hasn't been updated so is now out of date. You need to update this use Code First migrations.
When I'm making the following changes its throwing an error now
public class Employee {
[Key]
public int Id { get; set; }
[DisplayName("Employee Name")]
[Required(ErrorMessage = "Employee Name is required")]
[StringLength(35)]
public string Name { get; set; }
public string Address { get; set; }
public decimal Salary { get; set; }
public string Email { get; set; }
}
Snapshot:
Questions:
If a Database Table is created is it possible to change a column ?
When adding a Data Annotation Attribute it's throwing an Exception, why is the database table column not changing ?
Addicted to your tutorials now
User Migration for update database structure
Without [Required] filed Name allow null (varchar(x) null), with [Required] Name change not null (varchar(x) not null)
If in database threre are rows with nullable Name, can be error on update (with migration)

EF Code First: Many-to-many and one-to-many

This is probably just because my knowledge with the EF Code First fluent API is lacking, but I'm stumped.
I want to model the following:
A Groups collection with Id and Name
A Users collection with Id and Name
Each user is assigned to exactly one primary group
Each user may have zero or many secondary groups
The table structure I'm going for would look like:
Groups
Id
Name
Users
Id
Name
PrimaryGroupId
SecondaryGroupAssignments
UserId
GroupId
I've been beating my head against a wall trying to model this with EF Code First, but I can't get it to accept both relationships between User and Group. Sorry for not posting any .NET code (I'm happy to), but it's probably all wrong anyway.
Is there a way to make EF model this? I'm assuming I have to do some sort of configuration with the Fluent API. Maybe a better question is: is there any good, definitive reference for the Fluent API?
Thanks!
Try this (untested):
public class Group
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<User> PrimaryUsers { get; set; }
public virtual ICollection<User> SecondaryUsers { get; set; }
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public int PrimaryGroupId { get; set; }
public virtual Group PrimaryGroup { get; set; }
public virtual ICollection<Group> SecondaryGroups { get; set; }
}
public class Context : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Group> Groups { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>()
.HasRequired(u => u.PrimaryGroup)
.WithMany(g => g.PrimaryUsers)
.HasForeignKey(u => u.PrimaryGroupId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<User>()
.HasMany(u => u.SecondaryGroups)
.WithMany(g => g.SecondaryUsers)
.Map(m => m.MapLeftKey("UserId")
.MapRightKey("GroupId")
.ToTable("SecondaryGroupAssignments"));
}
}
Based on Ladislav's excellent answer, here's how to do it without using any mappings - just attributes applied to the Model classes themselves:
public class Group
{
public int Id { get; set; }
[MaxLength(300)]
public string Name { get; set; }
public ICollection<User> Users { get; set; }
}
public class User
{
public int Id { get; set; }
[MaxLength(300)]
public string Name { get; set; }
[ForeignKey("PrimaryGroup")]
public int PrimaryGroupId { get; set; }
[Required]
public Group PrimaryGroup { get; set; }
[InverseProperty("Users")]
public ICollection<Group> SecondaryGroups { get; set; }
}
Notes
If you want, you can add the virtual keyword to the 2 ICollections and the Group. This allows lazy-loading. Performance-wise, I don't recommend it, but it is possible.
I included MaxLength attributes with an arbitrary (but safe) length of 300, because putting strings out in EF without a MaxLength gets you low-performance NVarChar(MAX) columns. Totally irrelevant to what's being asked but better to post good code.
I recommend against class names "User" and "Group" for your EF classes. They're going to complicate any SQL you attempt to run later, having to type [User] and [Group] to access them, and complicate using these classes in MVC Controllers where your class User will conflict with the Context property User that gives you access to the Asp.Net Identity library.

Resources