I'm making a Filesharing system for a school project using a n-tier architecture.
I want to validate user input in my business logic and be able to notify the user what input has errors and which error it is.
I don't really know how to approach this. My business logic has a method to insert a new upload like this:
public bool NewFile(File entity)
{
return repo.Insert(entity);
}
This is my model of the File object:
public class File : Upload
{
public int UploadId { get; set; }
public string FileType { get; set; }
public string Category { get; set; }
public int Upvote { get; set; }
public int Downvote { get; set; }
}
The upload model contains properties like title, description etc.
How will I be able to notify the user about input errors with a method that returns a Boolean? Do I make a separate validation class and make the method return an instance of the validation class? Or do I throw custom exceptions with the right error message and catch it in my presentation layer?
Would appreciate it if anyone could point me in the right direction
I don't know what framework your are using but the good method to validate user input would be to perform validations before trying to insert in database.
There is this solution that is quite common in asp.net mvc, you might be able to use it in your case.
If that is note convenient I would suggest to use a try/catch around your insert but you would have to do the logic yourself to notify the user what input threw the error and how it can be fixed (maybe there would be a size limit for example?).
EDIT: try/catch is enough for a school project but in production you would prefer anticipating any possible errors before the insert. Like so :
public bool NewFile(File entity)
{
if( /* check a validation rule */)return false;
else if( /* check another rule */ )return false;
return repo.Insert(entity);
}
of course if you want to send back information to the user maybe you would prefer returning a string message explaining what validation rule did not pass.
regards
Related
I am attempting my first foray into DDD, and I asked a question about bulk imports here, but I am going in circles trying to apply the validation for my domain model.
Essentially I want to run through all the validation without throwing exceptions so that I can reject the command with all the validation errors via a list of CommandResult objects inside the Command object. Whilst some are just mandatory field checks which are configurable and so will be handled outside the aggregate, there are also business rules, so I don't want to duplicate the validation logic and don't want to fall into an anaemic model by moving everything outside the aggregate to maintain the always-valid mantra of entities.
I am at a bit of a loss, so thought it be best I ask the experts if this I am going about things correctly before I start muddying the waters further!
To try and demonstrate:
Take the below, we have fairly simple UserProfile aggregate, the constructor takes the minimum information required for a profile to exist.
public class UserProfile : AggregateRoot
{
public Guid Id {get; private set; }
public Name Name {get private set;}
public CardDetail PaymentInformation {get; private set;}
public UserProfile(Guid id, Name name, CardDetail paymentInformation)
{
Name = name;
PaymentInformation = paymentInformation;
}
}
public class CardDetail : ValueObject
{
public string Number {get; private set;}
public string CVC {get; private set; }
public DateTime? IssueDate {get; private set;}
public DateTime ExpiryDate {get;private set;}
public CardDetail(string number, string cvc, DateTime? issueDate, DateTime expiryDate)
{
if(!IsValidCardNumber(number))
{
/*Do something to say details invalid, but not throw exception, possibly?*/
}
Number = number;
CVC = cvc;
IssueDate = issueDate
ExpiryDate = expiryDate;
}
private bool IsValidCardNumber(string number)
{
return Regex.IsMatch(/*regex for card number*/);
}
}
I then have a method which accepts a command object, which will construct a UserProfile and save to the database, but I want to validate before saving
public void CreateProfile(CreateProfileCommand command)
{
var paymentInformation = new CardDetail(command.CardNumber, command.CardCVC, command.CardIssueDate, command.CardExpiryDate)
var errors = /* list of errors added to from card detail validation, possibly? */
var profile = new UserProfile(/* pass args, add to errors? */
if(errors.Any())
{
command.Results.Add(errors.Select(x => new CommandResult { Severity = Severity.Error, Message = x.Message });
return;
}
/* no errors, so continue to save */
}
Now, I could handle exceptions and add them to the command result, but that seems expensive and surely violates the rule of allowing exceptions to control flow? but on the other hand I want to keep entities and value object valid, so I find myself in a bit of a rut!
Also, in the example above, the profile could be imported or done manually from a creation screen, but the user should get all error messages rather than each one in the order they occur. In the application I am working on, the rules applied are a bit more complex, but the idea is the same. I am aware that I shouldn't let a UI concern impact the domain as such, but I don't want to have to duplicate all validation twice more so that I can make sure the command won't fail as that will cause maintainability issues further down the line (the situation I find myself in and trying to resolve!)
The question is maybe a bit broad and around architectural design which is something you should decide upon, but I will try and assist anyway -I just cannot help myself.
Firstly: This is a great article that might already hint at you are too critical about your design: http://jeffreypalermo.com/blog/the-fallacy-of-the-always-valid-entity/
You would need to decide about the way your system is going to handle validation.
That is, do you want a system where the domain will just absolutely never ever fail consistency? Then you might need additional classes to sanitize any commands as you have and validate them before you accept or reject the change to the domain(Sanitation layer). Alternatively, as in that article, it might indicate that there is a completely different type of object required to deal with a specific case. (something like legacy data which does not conform to current rules)
Is it acceptable for the domain to throw an exception when something seriously goes wrong? Then discard all changes in the current aggregate (or even current context) and notify the user.
If you are looking for a peaceful intermediate solution, maybe consider something like this:
public OperationResult UpdateAccount(IBankAccountValidator validator, IAccountUpdateCommand newAccountDetails)
{
var result = validator.Validate(newAccountDetails);
if(result.HasErrors)
{
result.AddMessage("Could not update bank account", Severity.Error);
return result;
}
//apply further logic here
//return success
}
Now you can have all the validation logic in a separate class, but you have to pass that and call via the double dispatch and you will add the result handling as seen above in every call.
You will truly have to decide what style is acceptable for you/team and what will remain maintainable in the long run.
I have a model described as below:
public class Projet
{
public int ProjetId { get; set; }
public int SeqNumber{ get; set; }
public string Code{ get; set; }
public string Description { get; set; }
public bool Std{ get; set; }
public bool Archive { get; set; }
}
I have a create view to let a user create a new project, and I must let the SeqNumber field free so the user can input whatever number he wants.
However, I must return an error if the SeqNumber choosen is already taken.
I'm not sure how to implement this. Should I do some validation in my ProjetsController/Create action ? From what I can find, validating stuff in the controller is a bad practise, but I can't think of where to implement validation when it depends on other members of the same class.
Would coding a custom validator for MVC considered a good practise?
Thanks !
You can use this in your http post action method which handles the form submit
[HttpPost]
public ActionResult Create(Projet model)
{
var exist = db.Projects.Any(s=>s.SeqNumber===model.SeqNumber
&& s.ProjectId!=model.ProjectId);
if(exist)
{
ModelState.AddModelError(string.empty,"Sequence number is already in use");
return View(model);
}
// to do : Continue with your save
}
Now when user submits the form, if the sequence number is being used for any other project, it will throw a validation message. Make sure you are using the Validation summary helper in your view to render the validation error message.
#model Project
#Html.ValidationSummary(false)
#using(Html.BeginForm())
{
<!-- your existing code goes here-->
}
Now to give a nice user experience, you may take advantage of the Remote validation feature. What it does is, when user takes the focus out from the input, it makes an ajax call to server to check whether your SequenceNumber exist in db. Based on the result, the validation messages will be shown to the user.
To do this, decorate your property with the Remote attribute.
[Required]
[System.Web.Mvc.Remote("CheckSeqNumber", "Project",
ErrorMessage = "SeqNumber is already used!")]
public int SeqNumber { get; set; }
Now make sure you have an action method called CheckSeqNumber which returns either true or false as a json response.
public ActionResult CheckTagName(int SeqNumber)
{
var exist= !db.Projects.Any(g => g.SeqNumber == SeqNumber);
return Json(exist,JsonRequestBehavior.AllowGet);
}
Also make sure you have the relevant javascript files loaded to do this unobtrusive validation.
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
Another option is to write a custom validation attribute which does this check for you (if you do not like that check in the action method). Here is an SO post explaining how to do it.
I was wondering if there was a more elegant way in managing contact details for an individual. Forget the SQL side of things for a moment, I am intrigued in how one would perhaps attempt to drive this via a DDD approach.
I was fooling around with some code in an effort to get comfortable with DDD as a whole and came up with the following which seems awful.
Firstly, I have an object called Person (simplified for the purpose of this post) where I envision methods to add and essentially manage different methods of communicating an individual.
public class Person
{
public Person()
{
this.ContactDetails = new List<ContactDetails>();
}
public void AssociateContactDetails(ContactDetails contactDetails)
{
var existingContactDetails = this.ContactDetails.FirstOrDefault(x => x.ContactType == contactDetails.ContactType);
if (existingContactDetails != null)
{
this.ContactDetails.Remove(existingContactDetails);
}
this.ContactDetails.Add(contactDetails);
}
public IList<ContactDetails> ContactDetails { get; private set; }
}
Two approaches spring to mind. One where I have a fairly simple object like the one below which is quite generic (using the term loosely).
public enum ContactType
{
Email, Telephone, Mobile, Post
}
public class ContactDetails
{
private readonly ContactType contactType;
private readonly string value;
public ContactDetails(ContactType contactType, string value)
{
this.contactType = contactType;
this.value = value;
}
public ContactType ContactType
{
get { return this.contactType; }
}
public string Value
{
get { return this.value; }
}
}
But then I put myself into a corner with this approach as although it works well for trivial items such as email and telephone, when it comes to something like postal a string doesn't quite cut it. Therefore, after this I am heading towards the approach of having each mechanism of communication to represented by its own type, i.e.:
public class Post
{
public Address PostalAddress { get; set; }
}
public class Mobile
{
public string MobileNo { get; set; }
}
public class Telephone
{
public string AreaCode { get; set; }
public string TelephoneNo { get; set; }
}
public class Email
{
public string EmailAddress { get; set; }
}
Each type can then represented as a collection or single instance in the Person class? Seems long winded however is perhaps more readable and maintainable.
The question I guess is if there is a more elegant way in implementing such a feature and whether someone can point me in the direction of a good example similar to this. I imagine this is a common thing / problem to overcome.
Cheers, DS.
We know for sure what are the contact methods "email, "phone" and "address", so having identified those what we have to do first is to model those concepts taking into account what they really are. Let's take "email" as example and see what it really is in order to model it properly. It is a value object (an immutable object) that once created it will never change just as an integer number is an immutable object as well. The difference is that for modelling an integer number we can use the int type provided by any programming language, but the question is what class do we use for modelling en Email? Most of people would use a String instance to model an Email, but is this OK? In order to answer it let's see what is the protocol (the set of messages) a String object knows to response: "charAt(anIndex), replace(aString, anotherString), etc... ". Imagine that if we model an email by using a String class we could ask the email "replace(aString, anotherString)". That sounds weird, that message should not be part of the behavior an email should expose to other objects. Also so so important we said an email is immutable to it cannot expose behavior that at the end change it state. So it makes visible that we need to create a whole new abstraction to model an email and what is it? The Email class finally comes in!!! I know you suggested it but I just wanted to let you see why we need an Email class created.
First of all this is DDD (object oriented) so FORGET avoid setters and getters. In the email class you created you expose a setter method meaning that you can change the email and it contradicts with the nature of what an email is (immutable). An email is immutable from the momento it is created:
Email.fromString("monicalewinsky#gmail.com");
that is the same as doing
new Email("monicalewinsky#gmail.com");
The fromString method is a factory method that adds semantic to our domain model. This is very common in smalltalk instead of calling the constructor directly. Are we done??? Not at all. An email instance should be created as long as it is valid so the email class should assert the string from which is created is valid:
Email(String anEmailStringRepresentation) {
assertIsValid(anEmailStringRepresentation);
}
assert is valid should verify it is actually an email string representation. This is that is has only one # character, its local part is valid and then its domain part is valid. You can check the wikipedia for email address to understand better how it is composed.
Remember always that programming is a learning process, as long as we understand a domain better and better we reflect that domain in the code and it always must be consistent with the real world! Our Email class should look like more or less like:
class Email {
String value;
Email(aString) {
value = aString;
}
public String getLocalPart()
public String getDomainPart()
public String asString()
public boolean equals(anObject)
public static Email fromString(aString)
}
That's it. It happens the same with PhoneNumber. It is also an inmmutable object and you should create a class with its own protocol. Remember never use set/get as you showed up if we are doing DDD. I don't think you need two value objects Telephone and Mobile since those are polymorphic objects and you could model a mobile phone number or a home phone number with the TelephoneNumber abstraction. It's like modelling a credit card. At the end you will end up and understand that the class CreditCard is enough and a better design than having several class such as Visa, MasterCard, and so on.
Let's skip the Address class and let's go back to your problem now.
So far we have identified and created properly all the value objects we need. Now we need to create an abstraction for representing an email, phonenumber, address as contact methods and if we keep loyal to the domain language we could say:
ContactMethod.for(Email.fromString("monica#gmail.com"));
or
ContactMethod.for(PhoneNumber("34234234234"));
etc
so our ContactMethod would look like:
class ContactMethod {
static EMAIL = 1;
static PHONE_TYPE = 2;
static ADDRESS_TYPE = 3;
String type;
String value;
ContactMethod(int aType, String aValue) {
type = aType;
value = aValue;
}
String getType()
String getValue()
public static ContactMethod at(Email anEmail) {
return new ContactMethod(EMAIL, anEmail.asString());
}
public static ContactMethod at(PhoneNumber aPhoneNumber) {
return new ContactMethod(PHONE_TYPE, aPhoneNumber.asString());
}
public static ContactMethod at(Address anAddress) {
return new ContactMethod(ADDRESS_TYPE, anAddress.asString());
}
}
See that ContactMethod is also an immutable class, actually a rule of thumb is that an Aggregate root should have ideally only an aggregation of value objects.
This is finally how your Person class would look like:
class Person {
List<ContactMethod> contactMethods;
contactedAt(Email anEmail) {
contactMethods.add(ContactMethod.at(anEmail));
}
contactedAt(PhoneNumber aPhoneNumber) {
contactMethods.add(ContactMethod.at(aPhoneNumber));
}
contactedAt(Address anAddress) {
contactMethods.add(ContactMethod.at(anAddress));
}
}
On my journey of learning DDD sometimes I see patterns instead of problems... an interesting example Everything seems to be an Aggregate Root is another answer I had provided regarding a menu, which had different categories such as starter, main, desert etc.
I had modeled this implicitly as a category string. After i posted there was a second answer where someone suggested modeling these as explicit lists of:
Menu {
List<Food> starters;
List<Food> entrees;
List<Food> desserts;
List<Food> drinks;
}
In this way, the entire concept of the category for a food was removed, this was enlightening for me and saw a different way of modeling and in this case reducing complexity.
My view is to try and model the code so that if I sat down with the business expert (who is not a developer) and showed them the use case code from a high level person.SetMobileNumber("078321411", Countries.UK) they would be able to understand it:
public void HandleUpdateMobileCommand(UpdateMobileNumber command)
{
// repositories, services etc are provided in this handler class constructor
var user = this.UserRepository.GetById(command.UserId);
user.SetMobile(command.number, command.country);
this.UserRepository.Save(user);
// send an SMS, this would get the number from user.Mobile
this.SmsService.SendThankYouMessage(user);
}
Or even better, you could have a MobileUpdated event get fired when you update the user mobile, to which some code somewhere else (which is an expert on sending SMS messages, and nothing else) is listening to these events - for me this is the real power of DDD of breaking down code in to expert systems.
So in summary, I think your second suggestion of explicitly modeling with Post, Mobile, Landline and Email makes most sense.
I wouldn't say this a DDD domain or not as there isn't enough information on any complex logic (or multi-user race conditions) that you require, just to mention don't forget that you may be better writing a CRUD app if that makes more sense in this situation.
There's this central idea in DDD that domain modelling must take shape through discussion with domain experts. If you're making up these class names out of thin air, chances are they won't exactly match your real domain. Trivial ones such as Email or Telephone should be correct, but maybe for others you want feedback from an expert first.
Generally speaking, it's a good idea indeed to favor semantically rich modelling with dedicated value objects over primitive types. In C# it comes at a cost though since the amount of boilerplate code needed is huge (unlike F# for instance). This is why I usually prefer to do it only when the type has more than a single property or when there are specific construction rules or invariants to it.
One good thing you can do is model your types as immutable Value Objects. So something like:
public class Telephone
{
public string AreaCode { get; set; }
public string TelephoneNo { get; set; }
}
Might become:
public class TelephoneNumber
{
private string areaCode;
private string subscriberNumber;
private TelephoneNumber()
{
}
public TelephoneNumber(string areaCode, string subscriberNumber)
{
this.AreaCode = areaCode;
this.SubscriberNumber = subscriberNumber;
}
public string AreaCode
{
get
{
return this.areaCode;
}
private set
{
if (value == null)
{
throw new ArgumentNullException("AreaCode");
}
if ((value.Length <= 0) || (value.Length > 5))
{
throw new ArgumentOutOfRangeException("AreaCode");
}
this.areaCode = value;
}
}
// Etc.
}
I'm wanting to check if I can send a message from a Model to a Controller, I'll explain.
So I have a Model
public class Car()
{
public int Id { get; set; }
public string Make { get; set; }
}
So when a user adds a new Car, I could make it required by using Fluent API or the [Required] annotation.
But what if I wanted to make sure I had only certain characters in there, so I wouldn't want the percentage symbol in there (unless there are any cars out there?!).
So I thought I'll use a constructor:
public class Car()
{
public Car(string _name)
{
if(this.Make.Contains("%"))
{
//Let the user know this isn't valid there is an error
}
}
public int Id { get; set; }
public string Make { get; set; }
}
I usually place the error logic in the Controller. So I would have
public ActionResult AddCar(Car car)
{
if(car.Make.Contains("%"))
{
//let user know this is not valid
}
if(ModelState.IsValid)
{
}
///
}
But then I thought, I'm never going to want to have a car Make with a % sign (I've picked on % sign, but actually there is a host of validation I would use, such as a list containing invalid characters), and every place in which I allowed for a user to add a car, I would duplicate the validation code, which just felt inefficient.
Maybe producing a the error checking in the controller is the correct way?
Again for clarity. The question, is there a way to pass a message from a Model to a Controller, which I can then pass to the User's view?
Kind regards
You should not use validation logic in your controller, we have DataAnnotations which allows us to validate model's properties value.
for your purpose you can use RegularExpression validator for this.
Refer to this Link for more details
Just curious if someone can shed some light on if this is a good practice or not?
Currently I am working on a C# project that performs and Inserts a record and runs through 4 or 5 methods to validate that the record can be added and returns a string that tells the presentation layer if the record has been submitted or not.
Is this a good practice? Pros/Cons?
The call from the presentation is:
protected void btnProduct_Click(object sender, EventArgs e)
{
lblProduct.Text = ProductBLL.CreateProduct(txtProductType.Text, txtProduct.Text, Convert.ToInt32(txtID.Text);
}
The BLL method is:
public class AccountBLL
{
// Create The Product w/ all rules validated
public static string CreateProduct(string productType, string product, int id)
{
// CHECK IF PRODUCT NAME IN DB
else if (ValidateIfProductNameExists(product) == true)
{
return "Invalid Product Name";
}
// CHECK IF 50 PRODUCTS CREATED
else if (ValidateProductCount(id) == true)
{
return "Max # of Products created Can't add Product";
}
// CHECK IF PRODUCT TYPE CREATED
else if (ValidateProductType(productType) == false)
{
return "No Product Type Created";
}
// NOW ADD PRODUCT
InsertProduct(productType, product,id);
return "Product Created Successfully";
}
As mentioned in the previous post, use Enum types.
Below is a sample code that could be used in your application.
public struct Result
{
public Result(ActionType action, Boolean success, ErrorType error) :
this()
{
this.Action = action;
this.HasSuceeded = success;
this.Error = error;
}
public ActionType Action { get; private set; }
public Boolean HasSuceeded { get; private set; }
public ErrorType Error { get; private set; }
}
public enum ErrorType
{
InvalidProductName, InvalidProductType, MaxProductLimitExceeded, None,
InvalidCategoryName // and so on
}
public enum ActionType
{
CreateProduct, UpdateProduct, DeleteProduct, AddCustomer // and so on
}
public class ProductBLL
{
public Result CreateProduct(String type, String name, Int32 id)
{
Boolean success = false;
// try to create the product
// and set the result appropriately
// could create the product without errors?
success = true;
return new Result(ActionType.CreateProduct, success, ErrorType.None);
}
}
Don't use hardcoded strings.
Use an Enum for the return value, you can do much more and more efficiently with enums.
Validations must be done, only thing you can improve is to put the whole validation process in a single method.
After you call the method, you can have a single if sentence in the main method to check the enum returned.
if (IsValidated(productType, product,id) == MyEnumType.Success) { }
I'd use exceptions rather than a string or a enum...
I would recommend looking at the Validation framework used by Imar Spaanjaar in his N-Layer architecture series. The framework he uses if very versatile and it even supports Localization through using Resource files for the validation strings.
It is not a best practice to return a string with the status of the method.
The main reason is that it violates the separation of concerns between the UI layer and the business layer. You've taken the time to separate out the business logic into its own business layer; that's a good thing. But now the business layer is basically returning the error message directly to the UI. The error message to display to the user should be determined by the UI layer.
With the current implementation the business layer also becomes hard to use (for anyone without explicit knowledge of the implementation) because there is no contract. The current contract is that the method will return a string that you should display to the user. This approach makes reuse difficult. Two common scenarios that could cause headaches are if you want to support a new language (localization) or if you want to expose some of these business methods as a service.
I've been bitten when trying to use some old code like this before. The scenario is that I want to reuse the method because it does exactly what I want but that I want to take some action if a specific error occurs. In this case you end up either rewriting the business logic (which is sometimes not possible) or you end up having to hard code a horrible if statement into your application. e.g.
if (ProductBLL.CreateProduct(productType, product, ID) ==
"Max # of Products created Can't add Product")
{
...
}
Then a requirement comes down that the message should be changed to something different ("The maximum number of products has been exceeded. Please add less products and try again."). This will break the above code. In production. On a Saturday night.
So in summary: don't do it.