I am working on a BI application in WPF. I am in the process of designing its architecture and am in search of a way to directly bind controls in the view to a xml which contains the metadata of the view. Do you think this is going to be possible? then how? or is it advisable to read off from the xml and generate the views accordingly?
Edited
Properties such as colors of charts, who created the chart, the next chart upon drilling down a chart, the user names and their passwords, user group names etc. are stored in XML files. When a user starts the application the dashboards he has created should be displayed; this happens with the retrieval of data from the back end and by assigning the correct chart colors. So if these data are available in the XML, my question is the best way to generate the charts and dashboards upon user request.
Edited
As I explained earlier as well, the problem is to store the metadata related to this application in the most efficient and structured way to call back upon a user loging in.
Thanks in advance.
I'm not sure I quite understand what you are looking to do. If you just want to bind some UI control properties to data in an XML document, that's entirely possible. I blogged about it years ago here.
I will suggest use of XAML instead of XML.
XAML will not only let you define the UI but XAML also can contain your other metadata or config information that you can read/write in the form of XAML to directly your CLR class.
Benefits are,
Xaml serialization is exactly same as that of Xml's serialization
Xaml will give you powerful intellisense while editing in Visual Studio (xml also can give but you will have to create and update schema everytime you make changes to your configuration schema)
In case of intellisense, Xaml is better because it will automatically give validation errors
It will also allow you to use Enums
It will also hide/show members or classes based on inheritance hierarchy
You can load XAML from string coming from database as well
It will let you specify bindings as well if your object is derived from DependencyObject and you will be able to transfer or reuse the bindings in your UI
For example,
public class ScreenElement{
public string Author {get;set;}
public DateTime DateCreated {get;set;}
}
// XAML can not directly deal with generics so this step is
// necessary
public class ScreenElements : ObservableCollection<ScreenElement>
{
}
[ContentProperty("Elements")]
public class Screen
{
public Screen(){
this.Elements = new ScreenElements();
}
public string Title{get;set;}
public bool ToolbarPresent {get;set;}
// this attribute is necessary if
// you want to save Screen to xaml
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ScreenElements Elements {get; private set;}
}
And your Screen xaml can look like
<Screen xmlns="clr-namespace:MyNamespace"
Title="Home Screen"
ToolbarPresent="false"
>
<ScreenElement Author="Myself" DateCreated="..."/>
<ScreenElement Author="Yourself" DateCreated="..."/>
</Screen>
You can create XAML resource and load it like...
Screen s = XamlReader.Load(.. resource uri to your XAML)
// and now you can use your "s" loaded with elements to
// populate your UI
foreach(ScreenElement e in s.Elements){
// use attributes of e to populate things..
}
I think the best in your case would be to devide all possible data in the system by data classes - metatypes. after that, in xml, specify data metatype so your data would be always have metatype. And when, before view creation, you should read all metatypes for data you are intend to display and create screen controls according to that metatypes. After that you could load and display data. Such approach works well in my small programm and I thinks it would yield good results in your system too.
[EDIT]
OK, your application includes business domain (your business data, business logic and rules for data displaying). All this things you have spread among three parts: Model, View and ViewModel. As I understand correctly your question is stright about ViewModel.
For example your hypothetical application containы employee information and suppose every employee may have three types of information about he or she:
Personal information (Name, date of birth, photo, home address, mobile phone number)
Education information (information about education, list of completed training cources)
Proffesional experience information (list of succesfully completed commercial projects)
So we have domain - employee. This domain may be devided into three metatype:
Personal metatype
Education metatype
Proffesional experience metatype
For each metatype we should create subscreen which would display metatype information according to business rules. I'll recomend you to make metatype subscreens with MVC pattern because of in case of editing of data some special editing rule or data validation may be applyed. When we have each subscreen created we can be free to display each type of meta information in the system.
For example you application have loaded employee information. After that you can determine which metatype presented in loaded data and can force creation of appropriate subscreens. The last part of work is to pass appropriate data to each sub screen.
It was very vague explanation sorry for my english, if you have any question about I have explained feel free and ask question again
Related
I have a requirement to make our current web application configurable based on client profile. So basically, allowing the application to scale and customize itself based on who the customer is. My current requirement to start off with will be simple, which is to make text within the web application configurable. So ATM, there will be 2 possible profiles, and based on which profile you select (either through AppSetting or database), all labels need to render accordingly. I can think of many ways of doing this. One thing I don't want to do is storing the label values in a database table because ATM there is no requirement to modify the labels through an interface, so I was thinking perhaps Resource files?
Also, my next requirement will be to all features within the website to be turned on/off based on profile, so I Need to keep this into consideration. Sometimes a feature will share 90% of the logic, so it wouldnt be feasible to duplicate to the feature and make the 10% changes for that profile and then have 2 copies of the same feature with minimum differences. So I'm looking for a solution for this as well. Perhaps an overall design that would cover both requirements?
Any advice will be highly appreciated.
Thanks
According to my understanding you need to update labels in the website and provide some features based on the profile selected.
So to do this , I would like to do this:
First implement MVC pattern, where our website will be in View , Model will be the Profile class and controller will host all the business logic.
If we don't want to use Database, we can serialize the object of Profile class and store (for ref
), in that we can have a File object which is a config file, where we can store the names of the features available to that profile.
At run time read all the features available for that profile and hence populate the view(website). This can be done by using either Inversion of Control Pattern. Like this:
public interface IFeatures{...}
public class Feature1 implements IFeatures{...}
public class Feature2 implements IFeatures{...}
public class Profile{
private String name;
private String pwd;
private File configFile;
...
}
public class Controller{
public List<?> getFeauturesForProfile(Profile p){
List<IFeatures> features;
List<String>feautures = scanConfigFileForFeatures(p.getConfigFile());
for(String feature : features)
features = Class.forName(feature).newInstance();
return features
}
}
Since I'm familiar with only java , I have written the syntax-es in java .
I know it is possible to pass a dictionary of compile time parameters to the dynamic filter controls by using the UIHint attribute on the models. Unfortunately this is not enough in our case.
For example, consider this model:
public class Device
{
public string Unit {get; set;}
public string Name {get; set;}
}
An 'Unit' is a segregating property in our models. One unit does not interfere with another. At the same time, multiple units coexist in the same server, and are accessed by different clients, with different needs.
Ideally, I wanted to load a different dynamic field when the unit has a certain value.
Consider the case where I have two units:
unit1: Requires no customization. Loads the [default] dynamic templates from the DynamicData\FieldTemplates folder
unit2: Clients who are in "unit2" requested a different way to show the device Name for instance, thus we create a custom folder for the unit and change the Text.ascx template there.
The structure would look like this:
Notice that there are now two 'Text' field templates. The idea is to use the one inside the 'unit2' folder whenever the instance I'm manipulating has 'unit2' as it's Unit property value. The controls in the root FieldTemplates folder would now act as a fallback mechanism for when the folders and controls do not exist for a given unit value.
These folders would be created after the project has been deployed and the units created, which shouldn't be a problem at all from what I can see. The only files that would be present in the original project are the "default" templates.
Initially I thought about creating my own FieldTemplateFactory implementation and attaching it to the MetaModel, but it doesn't seem to get access to the actual instance of the object, only it's MetaColumn. After that, I decided to take a look at how the DynamicField and DynamicControl controls were implemented, but couldn't find any extension point that would do what I want.
I've seen people do something similar, but with entire page templates. By using custom routes, one can make that work. In my case though, since we are talking Field Templates, that doesn't apply.
Is there another way I should be approaching this? Can I somehow base the decision of template loading on the value of a property inside the object? Is there some other, perhaps simpler, strategy to show different templates for different units?
you can maybe do this through the route but not the live data as the Field Template is selected before the data is bound.
Background
We've been migrating a large amount of legacy code & systems to ASP.NET MVC forms. I've already coded up a number of CRUD type interfaces with MVC 4, using model binding, validation, attributes etc., so I'm fairly familiar with that whole paradigm. So far, all of these forms have been on our backend administration & management applications, where it pays to have very strict input validation. We are launching our first consumer facing application in MVC and are faced with a different type of problem.
The Problem
Our legacy forms in this area are the main revenue engine for our company. Usability of the consumer experience is the rule of the day. To that end, we want our forms to be as lenient as possible - the legacy system did a number of things to automatically correct user input (in entirely custom, non standard ways each time, of course). To that end, we don't so much want input validation as we want sanitation.
Examples
We ask the user for numerical inputs which have a unit of measure implied. Common ones are currency amounts or square footage. The input label is clear that they don't need to provide these formats:
What is the approximate square footage? (example: 2000)
What is your budget? (example: 150)
People being people, not everyone follows the directions, and we frequently get answers like:
approx 2100
1500 sq. ft.
$47.50, give or take
(Okay, I exaggerate on the last one.) The model that we are ultimately storing into our business logic accepts numeric input type for these fields (e.g. int & float). We can of course use datatype validator attributes (example [DataType(DataType.Currency)] for the budget input, or just having the field type be an integer for the square footage) to clearly indicate to the user they are doing it wrong, providing helpful error messages such as:
The square footage must be numbers only.
A better user experience, however, would be to attempt to interpret their response as leniently as possible, so they may complete the form with as little interruption as possible. (Note we have an extensive customer service side who can sort out mistakes on our system afterwards, but we have to get the user to complete the form before we can make contact.) For the square footage examples above, that would just mean stripping out non-digit characters. For the budget, it would mean stripping out everything that's not a digit or a decimal point. Only then would we apply the rest of the validation (is a number, greater than 0, less than 50000 etc.)
We're stuck on the best approach to take to accomplish this.
Potential Solutions
We've considered custom attributes, custom model bindings, and a separate scrubber service class that would live between the model and the database. Here are some of the considerations we've taken into account trying to decide upon the approach.
Custom Validation Attributes
I've read a number of helpful resources on this. (They have varying degrees of relevancy and recency. A lot of stuff I found searching for this was written for MVC2 or MVC3 and is available with standard attributes in MVC4.)
Extending ASP.NET MVC’s Validation
Custom Validation Attribute in ASP.NET MVC3
A lot of questions & topics on input sanitization which were focused on Cross-site scripting attacks or database injection.
What I haven't found is anyone doing what I want to do, which would be changing the model value itself. I could obviously create a local copy of the value, sanitize it and provide a pass/fail, but this would result in a lot of duplicate code. I would still have to sanitize any input values again before saving to the database.
Changing the model value itself has 3 benefits:
It affects subsequent validation rules, which would improve their acceptance rate.
The value is closer to what will be put into the database, reducing the additional prep & mapping overhead needed before storage.
In the event of the form being rejected for another reason, it gently suggests to the user "You're trying to hard on these fields."
Is this a valid approach? Is there someone out there who has used validation attributes in this way that I just missed?
Custom Model Binding
I read Splitting DateTime - Unit Testing ASP.NET MVC Custom Model Binders which focuses on custom date time input fields with custom validation & parsing done at the model binding layer. This lives a lot closer to the model itself, so it seems like a more appropriate place to be modifying the model values. In fact, the example class DateAndTimeModelBinder : IModelBinder does exactly that in a few places.
However, the controller action signature provided for this example does not make use of an overall model class. It looks like this
public ActionResult Edit(int id,
[DateAndTime("year", "mo", "day", "hh","mm","secondsorhwatever")]
DateTime foo) {
Rather than this
public ActionResult Edit(
MyModelWithADateTimeProperty model) {
Shortly before that, the article does say
First, usage. You can either put this Custom Model Binder in charge of all your DateTimes by registering it in the Global.asax:
ModelBinders.Binders[typeof(DateTime)] =
new DateAndTimeModelBinder() { Date = "Date", Time = "Time" };
Would that be sufficient to invoke the model binding for the date time field on the single-parameter model example MyModelWithADateTimeProperty?
The other potential draw back that I see here is that the model binder operates on a type, rather than an attribute you can apply to the standard data types. So for example, each set of validation rules I wanted to apply would necessitate a new, custom type. This isn't necessarily bad, but it could get messy and cause a lot of repeated code. Imagine:
public class MyDataModel {
[Required]
public CurrencyType BudgetRange { get; set; }
public PositiveOnlyCurrencyType PaymentAmount { get; set; }
[Required]
public StripNonDigitsIntegerType SquareFootage { get; set; }
Not the ugliest model code I've ever seen, but not the prettiest either.
Custom, External scrubber class
This has the fewest questions for me, but it has the most drawbacks as well. I've done a few things like this before, only to really regret it for one of the following reasons:
Being separate from the controller and model, it is nigh impossible to elegantly extend its validation rules to the client side.
It thoroughly obfuscates what is and what isn't an acceptable input for the different model fields.
It creates some very cumbersome hoops for displaying errors back to the user. You have to pass in your model state to the scrubber service, which makes your scrubber service uniquely tied to the MVC framework. OR you have to make your scrubber service capable of returning errors in a format that the controller can digest, which is rather more logic than is usually recommended for a controller.
The Question
Which approach would you take (or, have you taken) to accomplish this type of sanitization? What problems did it solve for you? What problems did you run into?
I would take ModelBinder approach.
When form data comes in - it goes to model binders infrastructure. There you can override decimal model binder to refine input. After that you can send it to validation routines without neeed to write specific validation attributes or something like that.
Also you can use one intelligent model binder that will do type switch internaly or override ModelBinderProvider, so your code wont be bloated with ModelBinderAttribute. Here is Jimmy Bogart article about this. Also you will get some flexibility, because you can use attributes to declare if model uses strict or adaptive binding.
In overall, IMHO, validation attributes are not suposed to alter input. They should validate it. Model binders are in fact responsible for converting all weird stuff that comes in into something usable in your system and your third approach duplicates Model binder functionality)
Hope this helps and sorry for my english)
I'm facing a key design question related to how to attach custom fields to entities in my system. The entities are represented in C# and persisted in RavenDB. We are roughly following tenants of Domain Driven Design and our entities are aggregate roots.
[Note: I would like to avoid any debate around the appropriateness of a generic feature like custom fields in a DDD approach. Let's assume we have a legitimate user need to attach and display arbitrary data to our entities. Also, I have made my examples generic for illustrating the design challenges. :)]
My question is concerning how best to lay out the field definitions and the field value instances.
Imagine a domain where we have aggregate roots of Book and Author. We want users to be able to attach arbitrary data attributes to instances of Books and Authors. So, we might define a custom field with a class like this:
public enum CustomFieldType
{
Text,
Numeric,
DateTime,
SingleSelect,
MultiSelect
}
public class CustomFieldDefinition
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public CustomFieldType Type { get; set; }
public Collection<string> Options { get; set; }
}
A CustomFieldDefinition (CFD) that attached to Book might have values like:
Id: "BookCustomField\1"
Name: "FooCode"
Type: Text
Description: "Foo Corp's special identifier."
Type: Text
Options: null
The first question I'm facing is what to store on each instance of a Book. The choices range from...
the low end:
store just the CFD Id and the instance value
to
the high end:
store the entire CFD along with the value
The "low end" is bad because I cannot display a Book without pulling in the CFD, which is in another document. Also, if I change the CFD in any way, I've change the meaning of values in historical documents.
The "high end" is bad because there would be a lot of duplication. The CFD could be pretty heavy for select list CFDs because the definition contains all of the selectable options.
The first question is... How much should be stored in the document for each Book? Just enough to display the Book (and I'd have to go back to the CFD to display the options and description if I'm going to allow the user to edit the CF value)?
The second question is... Should I store I store the entire collection of CFDs for one entity type in one document or keep each CFD in it's own document?
Each CFD as a document keeps things simple for each CFD (especially when I start to do things like deactivate definitions), but then I need a way to separate Book CFDs from Author CFDs. This also forces me to load 1 document for each CF attached to the entity whenever I want to edit the entity.
All of the CFDs for a given type in one document allows me to load just one document, but then I'm loading all of the deactivated definitions as well.
Third question... Is there a better way to implement this altogether?
Fourth question... Are there any sample or open source solutions out there so I don't have to reinvent this wheel?
Since you said in comments:
... a Book from a year ago should show the custom fields as of a year ago.
There are only two viable options I can see.
Option 1
Custom field definitions exist in their own documents.
Every book contains a copy of the custom field definitions that apply to that book, along with the selected values for each custom field.
They are copied when the book is first created, but could be copied again as your logic sees fit. Perhaps on edit, you might want to take a new copy, potentially invalidating the current selections.
Advantages: Self-contained, easy to index and manipulate.
Disadvantages: Lots of copies of the custom field definitions. Storage requirements could be very large.
Option 2
Use the Temporal Versioning Bundle (disclaimer: I am its author).
Custom field definitions still exist in their own documents, but they are tracked temporally. This means that revisions to the custom fields will be maintained in a usable history.
Books only contain the selected values. They don't contain copies of the definitions.
Books don't need to be tracked temporally, but they do need some kind of effective date in their data. Perhaps an "entered on" date. Use whatever makes sense for you.
The Book-to-CFD relationship is an Nt:Tx type. You can find another example of this relationship type here. You might want to get an overview of temporal relationships in order to make some sense of this. Beware, this is a tricky subject and gets complicated quickly.
Advantages: Much less storage required, since there are not many duplicate copies of the custom field definition data.
Disadvantages: Learning curve. Complexity of working with temporal data. Requirement to install a custom bundle on your database server.
With either option, I would simply keep a property on the custom field definition that says what type(s) it applies to (Book, Author, etc).
I am building a view (web form) that will display various messages based on the state of a persons License. There are approximately 10 messages that the user will see. I don't really want to create multiple panels and show/hide and populate form fields based on the state...I would rather set a single property on the page...lets just call it:
public String Message
{
get;
set;
}
The message will include html formatting and some of the messages are much longer than other messages...I guess I am looking for a decent pattern to follow so this will be easily manageable...so my presenter will just return the formatted message based on the state of the license.
I am thinking I will create a abstract MessageTemplateBaseClass and classes for each message that build the message...The presenter will return the correct instance of the template based on the license state...
Does this sound like a decent approach?
Yes that would work, or potentially define an IKeyMessage interface that has this definition, and each presenter checks if its view defines this interface, casts it, and sets it appropriately.
HTH.