validation based on attributes in metadata class - silverlight-4.0

I am performing validation based on attributes in metadata.cs file. I am using Entity framework 4.0 and using wcf ria services. I want to know what is the equivalent of Page.IsValid in asp.net in silverlight? How do i ensure that the entity is in correct state before saving it? If i do not ensure this an exception fires which looks very ugly. I found a property named entityName.ValidationErrorCount so if my entity is named User i do objUser.ValidationErrorCount is less than equal to 0 i save it. Problem with this approach is if the user doesn't enter value in any of the textbox then subsequently all the values in the entity are null. So ValidationErrorCount property returns 0 because all are null values and thus my program tries to save the entity but naturally the entity is in incorrect state so exception fires. How do i get past this problem?
I hope i am clear. If not, please let me know. Thanks in advance :)

You can validate an entity using the Validator class (from the System.ComponentModel.DataAnnotations
namespace), like so (where entity is a reference to the entity to be validated):
List<ValidationResult> validationResults = new List<ValidationResult>();
ValidationContext validationContext = new ValidationContext(entity, null, null);
bool isValid = Validator.TryValidateObject(entity, validationContext, validationResults, true);
Alternatively, are you using the DataForm control? If so, there's an even easier way to check whether the current item is valid, by calling the ValidateItem() method on the DataForm. This will return a boolean indicating whether the current item is valid (you can also check the IsItemValid property of the DataForm). It will also update the bound controls to show their validation status. If you're not using the DataForm, then it will certainly make it easier if you can. Otherwise, simply add the validation results to the entity's ValidationErrors property:
foreach (ValidationResult result in validationResults)
entity.ValidationErrors.Add(result);
Hope this helps...
Chris

Related

Can I delete an entity that is not in cache?

I want to delete a record from the DB that hasn't been retrieved from a breeze query. The entity hasn't been retrieved so it's not in the cache, but I know the KEY of the record from another operation. Here's what I've tried:
create a new entity from the manager:
manager.createEntity(entityNames.book);
setting the ID :
bookToDelete().bookID(1); // bookToDelete is a ko observable from step 1
updating the state:
bookToDelete().entityAspect.setDeleted();
When I save changes, this transaction is not included in the JSON
You almost have it. Calling entityAspect.setDeleted on an 'Added' entity moves it directly to a 'Detached' state, which in effect removes it from the EntityManager, and hence it cannot be saved. This is deliberate. It handles the case where you create an entity and later delete it. In this case, there is no entity to save.
So, in your case, you have to make the entity either 'Modified' or 'Unchanged' before you call entityAspect.setDeleted. You can do this by either calling entityAspect.setUnchanged or entityAspect.setModified before calling entityAspect.setDeleted or you can call entityAspect.acceptChanges.
Note that you will also have to insure that the 'clone' entity passes validation and if you have a concurrency field on the entity, you will need to set this appropriately as well.
UPDATE Dec 7th
You can create the book entity in the marked-for-delete state in a single step as shown:
var book = manager.createEntity(entityNames.book,
{ BookID: 1 }, // use initializer to set the key
breeze.EntityState.Deleted); // creates the entity in the Deleted state
Be sure to initialize it with all other properties that are necessary for the entity to pass validation and optimistic concurrency checks on the server.
No problem if you don't have these checks. Not sure how you'd get those values without querying the server if you did have such checks.
got it. cant delete entity while still in added state. I first setModified. then setdeleted. didnt see any side affects.

Trying to update entities from a disconnected entity

Ok, each and every time I get into this situation, I struggle back and forth until I find a way to solve it (and that is usually not the way I would have liked to solve it).
What I'm talking about is disconnected entities in EF that should update existing entities in the database.
I'll give an example of my problem here (this example is the last time I got into this problem that caused me to write this question).
I have a WCF service that uses Entity Framework as well. The other program that have added a service reference to my service have gotten proxy versions of the Entities as normal.
The case is that the consumer of the service now construct a object of this proxy class, and call the method UpdateEntity on the WCF service. This entity has a foreign key to another type of entities, and the primary key of the entity I want to link this new entity to is also sent as a parameter to this method. In this case, I want the entity with the same primary key in the database to be updated. It seems simple enough right?
My method looks something like this now:
public bool ChangeEntity(MyEntity entity, int otherTableForignKey)
{
//first I verify that the entity to update exist in the system
var entitytochange = entityContext.MyEntities.FirstOrDefault(e => e.Name == entity.Name);
if (systemtochange == null) return false;
try
{
entity.ForignEntity = entityContext.ForeignEntities.FirstOrDefault(f => f.Key == otherTableForignKey);
//code for updating the entity should go here, but I'm nor sure what
entityContext.SaveChanges();
return true;
}
catch (Exception exc)
{
return false;
}
}
I tried many different combinations of ApplyCurrentValues, Attach, setting ObjectState to Modified and so on, but I get either the error message that I can't add a new entity with the same key as an existing entity, that the object state of the new object can't be Added and so on.
So my question is: What is the best way to do this without writing code that looks like a big hack.
The only way I got this working now was to just set the properties of entitytochange manually with the properties of entity, but it is a bad solution since any added properties to MyEntity will break the code if I don't remember to add code in this method as well, and it seems there really should be another way that is better.
EDIT
When I put entityContext.MyEntities.ApplyCurrentValues(entity); where my comment is put above, I get the following exception on this line:
The existing object in the ObjectContext is in the Added state. Changes can only be applied when the existing object is in an unchanged or modified state.
However, if I remove this line above entity.ForignEntity = entityContext.ForeignEntities.FirstOrDefault(f => f.Key == otherTableForignKey); then the ApplyCurrentValues works without any problems.
Why would me setting the ForeignEntity of the object set it to Added state? So it seems that setting a Property on the Detached entity, attaches it to the context with a state of added?

WCF Data Service - update a record instead of inserting it

I'm developing a WCF Data Service with self tracking entities and I want to prevent clients from inserting duplicated content. Whenever they POST data without providing a value for the data key, I have to execute some logic to determine whether that data is already present inside my database or not. I've written a Change interceptor like this:
[ChangeInterceptor("MyEntity")]
public void OnChangeEntity(MyEntity item, UpdateOperations operations){
if (operations == UpdateOperations.Add)
{
// Here I search the database to see if a matching record exists.
// If a record is found, I'd like to use its ID and basically change an insertion
// into an update.
item.EntityID = existingEntityID;
item.MarkAsModified();
}
}
However, this is not working. The existingEntityID is ignored and, as a result, the record is always inserted, never updated. Is it even possible to do? Thanks in advance.
Hooray! I managed to do it.
item.EntityID = existingEntityID;
this.CurrentDataSource.ObjectStateManager.ChangeObjectState(item, EntityState.Modified);
I had to change the object state elsewhere, ie. by calling .ChangeObjectState of the ObjectStateManager, which is a property of the underlying EntityContext. I was mislead by the .MarkAsModified() method which, at this point, I'm not sure what it does.

Why is ModelState.IsValid always false? FNH Model is expecting Id field

I am rather stumped on this.
Fluent Nhibernate v1.1.0.685
NHibernate v2.1.2.4000
When I check the ModelState.IsValid prop before calling the Save() on the Repository. The IsValid prop is always False. When debugging the Id value is "" (empty) in the Model. I have overridden the Mappings for the Id :: mapping.Id(x => x.Id).GeneratedBy.Identity();
If the Save() or Inset() method is called w/o checking checking modelstate the item is saved in the DB.
Any thoughts or suggestions would be appreciated.
I was using the DataAnnotations from within NHibernate.Validator with not realizing that would also need to be registered before the Session object was created.
I have since simply decided to user the MVC DataAnnotations within the ComponentModel namespace.
Simple enough.

Use enum to select string from wicket properties file

I'd like to add a label to a wicket panel where the label's model is an enum value. Based on the value of that enum, I'd like to display a different message pulled from the page's properties file.
For example, here's an enum:
public enum ApprovalType { UNAPPROVED, APPROVED, BLOCKED };
I can easily add a label to the panel that has this enum as its model:
add(new Label("approval", new Model(ApprovalType.APPROVED)));
However, this will simply output UNAPPROVED, APPROVED, or BLOCKED. I'd like to output a localized message that is selected based on the value of this enum.
So if I have this properties file, what's the best way to get these messages to output?
UNAPPROVED=Your membership is currently pending approval
APPROVED=Your membership has been approved
BLOCKED=You have been blocked from membership
I can get it working like this:
add(new Label("approval", new ResourceModel(ApprovalType.APPROVED.name());
But the problem is that ResourceModel only accepts a string (resource key). I'd like to pull the value of the resource key automatically from a model (preferrably a CompoundPropertyModel). In other words, I don't want to do this:
Member member = (Member) getDefaultModelObject();
add(new Label("approval", new ResourceModel(member.getApproval().name())));
I'd rather do something like:
add(new EnumLabel("approval"); // assuming I have a CompoundPropertyModel
Is there a component that does this that comes with Wicket? Or do I need to write my own?
Lastly, I discovered this also works:
add(new Label("approval", new StringResourceModel(
"${}",
new PropertyModel<ApprovalType>(getDefaultModel(),"approval")
)));
But this seems overly verbose, and still doesn't utilize the simplicity of using CompoundPropertyModel.
Ideas?
Not sure if this 'll work, but maybe you could try writing your own EnumModel class that takes the value of an Enum and returns a ResourceModel value..
Please say so if the above isn't clear enough, I'll try to elaborate.