Is it possible to indicate a property is a required field without using data annotation attributes?
Instead of using annotation attributes, I want to set it as a required field, based on particular conditions.
For eg, something like below
if (true)
{
//set myObj.Name as required field
}
Edit: The reason why I need to do is, I'm calling a business service class of our own framework, which I can not touch, and inside the class, when the entity is being saved, mandatory checking is already catered.
But, in my requirement, I need to save my entity several times and , each times, the mandatory checking may be different . That's the reason why I need to mark the properties required fields dynamically.
Otherwise, I have to made my own mandatory checking before calling the business service class, which I don't want to do.
From your description, it seems like you need to provide your "own mandatory checking". I say this for two reasons;
To provide your user meaningful feedback as to why something field is required
Also, to satisfy the contract of your business service class
Can you have a "validate" method that simply runs through your set of rules (that mandatory checking, that you mentioned earlier) and have it return a list of strings indicating the rules that were violated on an attempt to save. Then you can use these strings to populate the text of a message box, logfile or whatever to provide meaningful feedback to the user as to why something wasn't saved, and also ensuring that data that is saved, is compliant to your business service class.
Related
It said that 'edvRcvMisc' does not exist in the current context. How do i called a different table(RcvMisc) in RcvHead ?
I tried to do use BPM but it doesn't seem work as well and put different methods
To continue down your implementation method, you need to instantiate your reference to edvRcvMisc as such:
EpiDataView edvRcvMisc = (EpiDataView)oTrans.EpiDataViews["RcvMisc"];
However, I strongly recommend using row rules. You can simply use the Epicor wizard to create a row rule for RcvMisc.DocScrActualAmt. If there is not a field that can be used to indicate received status in edvRcvMisc and you do not want to denormalize the data with a BPM, then after you create the row rule you can change the row rule condition to a delegate, in which you can reference edvRcvHead data or perform any conditional function you wish.
I'm a bit confused about C#'s use of attributes. At first I thought it was simply used to give program code additional information through the use of the [Obsolete] attribute. Now I find that [Dllimport] can be used to import a dynamic linked library and its functions. Can attributes import .exe files and other kind of files?
A last question, for programmers working in C# every day, how much do you use attributes, and do you use it for anything else than extending information and importing dll's?
Simply said, attributes are just metadata attached to classes or methods, at the very base.
The compiler, however, reads through your code, and runs specific actions for specific attributes it encounters while doing so, hardcoded into it. E.g., when it finds a DllImportAttribute on a method, it will resolve it to an external symbol (again, this is a very simplified explanation).
When it finds an ObsoleteAttribute, it emits a warning of deprecation.
Your own attributes (which you can create with a class inheriting from the Attribute base class) will not have an effect on the default compiler. But you (or other libraries) can also scan for them at runtime, opening up many possibilities and leading to your second question:
I typically use them to do meta programming. For example, imagine a custom network server handling packets of a specific format, implemented in different classes. Each packet format is recognized by reading an integer value. Now I need to find the correct class to instantiate for that integer.
I could do that with a switch..case or dictionary mapping integer -> packet which I extend every time I add a packet, but that is ugly since I have to touch code possibly far away from the actual Packet class whenever I add or delete a packet. I may not even know about the switch or dictionary in case the server is implemented in another assembly than my packets (modularity / extensibility)!
Instead, I create a custom PacketAttribute, storing an integer property set via the attribute, and decorate all my Packet classes with it. The server only has to scan through my assembly types at startup (via reflection) and build a dictionary of integer -> packet pairs automatically. Of course I could scan my assembly every time I need a packet, but that's probably a bit slow performance-wise.
There are APIs which are much more attribute heavy, like controllers in ASP.NET Core: You map full request URLs to methods in handler classes with them, which then execute the server code. Even URL parameters are mapped to parameters in that way.
Debuggers can also make use of attributes. For example, decorating a class with the DebuggerDisplayAttribute lets you provide a custom string displayed for the instances of the class when inspecting them in Visual Studio, which has a specific format and can directly show the values of important members.
You can see, attributes can be very powerful if utilized nicely. The comments give some more references! :)
To answer the second part of your questions, they are also used, for example, in setting validation and display attributes for both client and server side use in a web application. For example:
[Display(Name = "Person's age")]
[Required(ErrorMessage = "Persons's age is required")]
[RangeCheck(13, 59, ErrorMessage = "The age must be between 13 and 59")]
public int? PersonsAgeAtBooking { get; set; }
Or to decorate enums for use in display
public enum YesNoOnlyEnum
{
[Description("Yes")]
Yes = 1,
[Description("No")]
No = 2
}
There are many other uses.
I have to validate three things when a consumer of my API tries to do an update on a customer.
Prevent the customer to be updated if:
The first name or last name are blank
For a certain country, if the customer's inner collection of X is empty, then throw an exception. X is hard to explain, so just assume it's some collection. For all other countries, X doesn't apply / will always be empty. But if it's a certain country, then X is required. So it's almost a conditional required attribute. A customer belongs to a country, so it's figured out from the JSON being sent.
Prevent the customer from being updated if some conditions in the database are true.
So basically i'm stuck with the following problem, and I wanted some advice on the most appropriately way to solve it:
Do I create an Action Filter to do the validation on the customer entity before the saving takes place? Or would it be better to create custom validation attribute derived from ValidationAttribute and override the IsValid member function.
Basically a question of saying
if (first name is empty, if x, if y, etc) vs (!ModelState.IsValid)
And then using IsValid to cause the custom attributes to work.
It seems like validation attributes are best for "simple" validation, i.e. required field. But once you start getting into things like "I need to look at my database, or analyze the http request header for custom values, and based on that, invalid = false" then it almost seems wrong to do this sort of stuff so close to the entity.
Thoughts?
Thanks!
I like FluentValidation a lot: https://github.com/JeremySkinner/FluentValidation
As you mentioned built-in validation attributes are limited. For complex validations you had better implement your own attributes or use a library like this.
One thing I like about FluentValidation is that it performs at model-level rather than field-level, meaning that you can use related fields' values for validation. For example
RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
(Code excerpt taken from project's Wiki page)
It's also extensible so you can develop your own custom validators on top of this library as well.
Fluent builder is a well-known pattern to build objects with many properties:
Team team = teamBuilder.CreateTeam("Chelsea")
.WithNickName("The blues")
.WithShirtColor(Color.Blue)
.FromTown("London")
.PlayingAt("Stamford Bridge");
However, using it doesn't seem very clear to me due to one particular reason:
Every Team object has its minimal operational state, in other words, set of properties which have to be set (mandatory), so that the object is ready to use.
Now, how should the Fluent builder approach be used considering that you have to maintain this state?
Should the With_XYZ members modify the part of the object, that can't affect this state?
Maybe there are some general rules for this situation?
Update:
If the CreateTeam method should take the mandatory properties as arguments, what happens next?
What happens if I (for example) omit the WithNickName call?
Does this mean that the nickname should be defaulted to some DefaultNickname?
Does this mean that the example (see the link) is bad, because the object can be left in invalid state?
And, well, I suspect that in this case the fluent building approach actually loses it's "beauty", doesn't it?
CreateTeam() should have the mandatory the properties as parameters.
Team CreateTeam(string name, Color shirtColor, string Town)
{
}
Seems to me the points of Fluent Interface are:
Minimize the number of parameters to zero in a constructor while still dynamically initializing certain properties upon creation.
Makes the property/ parameter-value association very clear - in a large parameter list, what value is for what? Can't tell without digging further.
The coding style of the instantiation is very clean, readable, and editable. Adding or deleting property settings with this formatting style is less error prone. I.E. delete an entire line, rather than edit in the middle of a long parameter list; not to mention editing the wrong parameter
I'm developing an application that does some CRUD operations through a WCF service. The read method returns a complete entity, the update is performed through a legacy system, and only the changed values should be updated.
What is the best way to design the data contract for this scenario without simply sending a dictionary of key-value pairs?
The only other thing I can think of is to make your component durable - i.e. persist its state to a file or database. That way, on the update you can compare the previous state to the state being passed in. I'm not sure that's a good way to go since it will introduce more overhead than just passing in the key-value pairs.
From the outside it might look more CRUDy or whatever, but from a practical standpoint you may be better off just passing some indication as to which values changed.
In case it helps, not sure exactly what you're looking for though ...
In the update request, only act upon fields that are not null.
In addition wrap any non-nullable types in a nullable structure.
As an example ...
Update( Nullable<int> orderNumber,
Nullable<DateTime> orderDate,
Nullable<bool> isComplete )
{
if( orderNumber != null )
databaseRecord.OrderNumber = orderNumber;
if( orderDate != null )
databaseRecord.OrderDate = orderDate;
if( isComplete != null )
databaseRecord.IsComplete = isComplete;
}
the best way to do this is with property dictionary, just represent your entities as dictionary of property name and value.
save all changes in some list and pass a partial dictionary with all changed properties.
i think this is best design,
if u wanna avoid this design, send entire entity with some list of changed properties.
(to save transport u can put null on other properties)
if u don't wanna change the service contract signature u can push the names of modified properties on the header
I had two ideas of how to achieve this;
Have the client send both the original entity, and the changed entity in full, the service would then figure out what properties were changed.
Use a pattern similar to Nullable, lets call it Modified with an IsModified flag and a NewValue property of type T. Each property of the DataContract would be of this type, the service can check the IsModified flag when performing the update.
The legacy sytem we use has an api that accepts String.Empty to identify unmodified fields, a '?' character is used to indicate an update to an empty string. I really don't like this, the user of the api is forced to read the documentation, and if you actually want to store a '?' you can't. I want our webservice api to be more explicit.
You can use DataSet to keep your changes. Call your record as DataSet then assign some values to the record. DataSet.Tables[0].GetChanges() will give you the columns which were changed.
You could leave the data contract alone and update your service contract. Just represent the required fields for the method as properties within the service contract. Any consuming application using the service will have to be updated if the service contact changes, but the consuming application will know what is required to successfully update the data.
There are positives and negatives to this method, but I use it when a method I am writing doesn't require the full data contract.
--Edited for a spelling error--
Looking at your requirements and statements, i've made a few assumptions before starting to write my vision on a possible solution:
You are using the same class for retrieving (return value type of "read" operation) and updating an item (input parameter type of "update" operation) in your WCF service.
Your current problem of implementation is how to use the original class (not a dictionary) AND still be able to determine 'what has changed compared to the read' when you get the "Update" operation called on your WCF service
You are writing both the server and client. Both are written using the MS .Net framework.
If this is true, the problem lies in the Update method missing information. The information required is 'has changed' which could be inferred if a 2nd state is present to compare against or should already be present along side the state to update in the back-end.
Since you only have the 'back-end state' (without flags) when the client posts its data to the WCF service, how should we determine what did change? Obviously, we want to prevent another 'read' roundtrip to get the current server state and start comparing.
Sending the original & changed state from the client to the server is a possible but heavy solution. Next to that, the client isn't interrested in this information, the server is.
Adding this all up makes my guess is that changing the type of the 'Update' operation input parameter is the easiest way to go. Create a decorator class that adds 'dirty bit' behavior to the original entity. Use this new class as input parameter for your "Update" operation. You then will have the availability in the server to check this dirty bit next to the full state send by the client. The major change on the client side is that the object needed for the 'Update' operation is no longer the same as the one provided by the 'Read' method. To eleviate this pain, i would probably create a decorator class which added the required 'dirty bit' handling. This only requires the object instanciation to change, while maintaining the interface signature for the client (very little code changes).