How to implement concept of .Net RIA Service (Sing

2019-06-07 16:51发布

问题:

First, let's see the following picture that explain the concept of .Net RIA Service.


(source: nikhilk.net)

As you see, the application has app logic (business rule) that can be implemented both server side (databases + Repositories + external services) and client side (asp.net web page + Silverlight + WCF)

Next, I create some data class that contains some validation rule.

namespace [SolutionName].Models
{
    public interface IUser
    {
        Guid ID { get; set; }

        [Required]
        [StringLength(15)]
        [RegularExpression("^[a-zA-Z][a-zA-Z_]+$")]
        string LoginName { get; set; }

        [Required]
        [StringLength(255)]
        string HashedPassword { get; set; }

        DateTime CreateTime { get; set; }

        [StringLength(255)]
        string Description { get; set; }

        [Required]
        Role Role { get; set; }
    }
} 

After that, I create some custom Model Binder for validating data when users post it to controllers. So, I can ensure that every Model is valid before I save it.

public ActionResult SaveData()
{
    if(ModelState.IsValid)
    {
        // logic for saving data
    }
    else
    {
        // logic for displaying error message
    }
}

However, some view page doesn't require all of fields in data type. It needs some of field in data type. I can't separate this data type into multiple interfaces depend on what data field that view page requires. Because some of data fields are duplicate. Moreover, it will separate app logic too.

For example

  1. LogOn view uses only 2 fields, including LogOnName and HashedPassword.
  2. ChangePassword view use only 2 fields, including Id and HashedPassword.
  3. UserProfile view uses 4 field, including ID, LogOnName, HashedPassword and Description.

Do you have any idea for solving this problem? I think it much like AOP concept.

By the way, I can solve this by adding a list field that contains unused fields. But this idea is quite bad when I use it with a large data type that contains more than 100 fields.

namespace [SolutionName].Models
{
    public interface IUser
    {
        /*
            Some defined data type
        */

        // All fields that is contained in this list won't be validated by defined rules.
        List<string> unusedFields { get;set; }
    }
} 

Thanks,

回答1:

The fundamental issue here seems to be one of the following:

  1. Contextual validation rules are being expressed as invariants
  2. Entities with unsatisfied invariants are being prematurely created/validated

I would suggest that you don't attempt using Model Binders to instantiate and validate types for which all invariant information isn't obtainable from the Http request. In the case of LogOn, the only information you have is the user's name and password. Therefore, LogOn shouldn't expect a User type, but rather the username and password, perhaps encapsulated in a Credentials type.