Ignoring an required field of an entity - asp.net-mvc-2

I got the following variable into my entity:
[DataType(DataType.Currency)]
[DisplayName("Value U$:")]
[Required(ErrorMessage = "Currency Required.")]
public decimal? CurrecyValue { get; set; }
Actually Im using this entity and I dont need this field. As soon as I post any information the ModelState becomes invalid because its required.
I know that I can use ModelState.Clear(); but, doing this I'll ignore all the other validations that I need.
Is there any way to just ignore this specific field without clearing my whole ModelState ?
Thanks !

Ugly and totally not recommended workaround:
ModelState.Remove("CurrecyValue");
Recommended solution:
Use view models. But real view models. Not some hybrids which you call view models and into into which you stick your domain entities and which you wonder how to get rid of simply because they are not adapted to the requirements of the given view. You should define a specific view model for each of your views. If you don't follow this very simple rule you will struggle a lot with ASP.NET MVC.

Related

Using PostCharp to dynamically generate a C# property

I hoping someone can provide some guidance as to how to solve the following challenge. I’ve done a fair amount of research but I’m not able to put all the pieces together. Thank you!
How I’d like to code my POCOs. Note that there will be many different properties each having a unique Guid "backing store" property who's name and ColumnAttribute will be a function of the SomeAspectAttribute annotation applied to the "main" property (e.g. CreatedBy).
[SomeAspectAttribute("_createdby_value")]
public User CreatedBy { get; }
I’d like the following to be generated:
[JsonIgnore]
[Column("_createdby_value")]
internal Guid _createdby_value { get; set; }
public User CreatedBy { get; set; }
So there looks to be a few things going on here. My struggle is putting it all together.
Add a property. IntroduceMember seems like it would work but I might have many of these where the original property Type and name will vary. Plus, given the need to introduce custom attribute upon this new property, I think I’m gonna need a dynamic, code-based means for creating this property.
Add custom attribute(s) to the dynamically added property.
I suspect I’ll need a TypeLevelAspect to find all my properties with the [SomeAspectAttribute] attribute (obviously with a better name) and do some CustomAttributeIntroductionAspect stuff.
Others?

Can I replace some of this with the Fluent Api?

Say I have the following property in a class (where I'm using Code First):
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
I'd rather not decorate my Password property with these annotations. I'd rather use the Fluent Api if possible. How many of these annotations could be done using the Fluent Api? I know Required can be, and StringLength. But I don't know about ErrorMessage, DataType and Display.
I take the View:
a)Decorate the POCO with genuinely useful business constraints. MVC and EF amongst others will check a few of the important constraints for You.
b) You can and should add checking for custom Annotations or other business rules to the POCO.
see sample bloew if interested:
c) DB specific annotations belong in EF fluent API. If they are DB specific that dont belong on the POCO in my view. Eg Table name, schema, Foreign key, association maps, column renames and ignores etc.
d) Error messages and Display texts belong on the Model View.Or at least abstracted from teh POCO example below. I know people dont like double effort and will use POCO as Model views and like easy text and error message handling. But I prefer a full error message/text handling solution that is multi-lingual and configurable. Sticking texts on a POCO, isnt the best solution in my view.
Clearly style and build size influence the choice and many will disagree with d) and I dont have a big issue with that . Im taken a big picture design pattern view and look to separate and abstract where it makes sense.
here a little POCO extra sample, not with annotations but it could have been. I have seen some nice examples with annotations as well. This style of error can be used in MVC and is better than texts in annotations in my view.
public class POCODemo : IValidatableObject //various ways to trigger this. Some for free
/// poco members .... bla bla
//Support Business rules...
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var vResult = base.Validate(validationContext).ToList();
if (Poco.property1 || poco.property is nasty or xyz issue)//psuedo code for your check
var memberList = new List<string> { "PropertyName1" };
var err = new ValidationResult("Some Text comes from your TEXTPOOL of choice that explains the error", memberList);
vResult.Add(err);
// }
}
return vResult;
}
I know Required can be, and StringLength.
And that's all.
Keep in mind that the same attributes can be used by different "frameworks" and for very different purposes. If you use - for example - the Required attribute in a context of ASP.NET MVC it will be used for MVC model validation - on client side by some Javascript injected into the page or on server side to set ModelState.IsValid.
The Required attribute is also used by Entity Framework Code-First to validate an entity, but this has actually nothing to do with the MVC model validation. If you replace the Required attribute by configuration with Fluent API you still influence Entity Framework, but for ASP.NET MVC you just have removed the attribute, i.e. the property is not required anymore for MVC validation. ASP.NET MVC doesn't care about Entity Framework's Fluent API.
The same is true for StringLength. ErrorMessage, DataType and Display play no role with Entity Framework, neither as attributes nor are there counterparts in Fluent API.

What is the best way to prevent updating on specific fields in Entity Framework

Im writing an web application with MVC using Entity Framework for my backend logic. My problem is that I have an entity that has certain fields that should never be changed on an update. I am not really sure what the best way to solve this problem would be. There is going to be a lot of data processed in my application, so I cant afford to just hack up a solution.
Is it possible to just define the fields as readonly in the POCO entities ? Or should I write and entity framework extension class that validates all updates. Could it be done in the mapping files between EF and the actual database?
I am relatively new with EF, so I hope some of you might be able to give me some pointers!
Thanks!
If you are using .NET 4.5 and EF 5 (i.e. MVC 4), you can simply set IsModified = false on the individual properties in question. This has the benefit of sticking close to the default out-of-the-box MVC conventions.
For example, if you have a CreatedBy field that shouldn't be touched when the record is updated, use the following in your controller:
[HttpPost]
public ActionResult Edit(Response response)
{
if (ModelState.IsValid)
{
db.Entry(response).State = EntityState.Modified;
db.Entry(response).Property(p => p.CreatedBy).IsModified = false;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(response);
}
Note that the IsModified line is the only change from the default controller action.
You MUST put this line AFTER setting .State = EntityState.Modified (which applies to the record as a whole and adds the record into the db context).
The effect is that EF will not include this column in the SQL UPDATE statement.
I am still (very) shocked that there are no [InsertOnly] or [UpdateOnly] attributes similar to [ReadOnly]. This seems like a major oversight by the MVC team. Am I missing something?
I'm not fully satisfied with this solution because it's a hack: You're telling EF that no change was made when what you really mean to say is "HANDS OFF". It also means that you have to use this code anyplace where the field could be updated. It would be better to have an attribute on the class property.
(Apologies for posting to an older thread, but I've not see this solution anywhere else. ViewModels are robust but a lot of work, and EF was supposed to make things easier, not harder...)
Well I would advice against ever using the EF classes in the View. You're best bet is to construct ViewModel classes and use Automapper to map them from the EF classes.
When you are updating records in the database though, you can control which fields in the ViewModel are used to update the existing fields in the EF class.
The normal process would be:
Use the Id to get the latest version of the existing object out of the database.
If you are using optimistic concurrency control then check that the object has not been updated since the ViewModel was created (so check timestamp for example).
Update this object with the required fields from your ViewModel object.
Persist the updated object back to the database.
Update to include Automapper examples:
Let's say your POCO is
public class MyObject
{
public int Id {get;set;}
public string Field1 {get;set;}
public string Field2 {get;set;}
}
and Field1 is the field you don't want updating.
You should declare a view model with the same properties:
public class MyObjectModel
{
public int Id {get;set;}
public string Field1 {get;set;}
public string Field2 {get;set;}
}
and Automap between them in the constructor of your Controller.
Mapper.CreateMap<MyObject, MyObjectModel>();
you can if you wish (although I prefer to do this manually, automap the other way too:
Mapper.CreateMap<MyObjectModel, MyObject>().ForMember(dest=>dest.Field1, opt=>opt.Ignore());
When you are sending date to your website you would use:
var myObjectModelInstance = Mapper.Map<MyObject, MyObjectModel>(myObjectInstance);
to create the viewModel.
When saving the data, you'd probably want something like:
public JsonResult SaveMyObject(MyObjectModel myModel)
{
var poco = Mapper.Map<MyObjectModel, MyObject>(myModel);
if(myModel.Id == 0 )
{
//New object
poco.Field1 = myModel.Field1 //set Field1 for new creates only
}
}
although I'd probably remove the exclusion of Field1 above and do something like:
public JsonResult SaveMyObject(MyObjectModel myModel)
{
var poco;
if(myModel.Id == 0)
{
poco = Mapper.Map<MyObjectModel, MyObject>(myModel);
}
else
{
poco = myDataLayer.GetMyObjectById(myModel.Id);
poco.Field2 = myModel.Field2;
}
myDataLayer.SaveMyObject(poco);
}
note I believe that best-practise would have you never Automap FROM the ViewModel, but to always do this manually, including for new items.
I just asked a very similar question, and I believe the answer to that one may help out a lot of folks who stumble across this one as well. The OP mentions that these are fields that should never change, and using PropertySaveBehavior.Ignore ensures this. With the existing answers to this question, you need to make custom save methods or introduce mapping where it might not make sense. By setting the AfterSave property behavior instead, you can prevent this from being possible in EF altogether.
In my project, I am generically accessing a property that is on an abstract class so I have to set it like this:
MyProperty.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);
If you're accessing it directly on a known class, you'd use this:
...
.Property(e => e.YourProperty)
.Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);

Use T4 DBContext Script to Write Display Name Attribute

My issue is simple: the code I'm writing is in English, but the interface is in Portuguese. Not a problem, as I can do this:
[Display (Name = "Símbolo")]
public string Symbol { get; set; }
This way, when I render my screen, it comes in Portuguese:
#Html.LabelFor(model => model.Symbol)
But...
As I am using Model First EF for my project, classes are constantly been changed by a T4 DbContext Generator. That way I can't use Display attribute, as it will be overwrited.
A solution given here is to extend partial classes automatically created. Kinda clumsy for me.
So my idea is to change the T4 script to get Documentation.Summary attribute from the EDMX model and add it as a Display Name attribute.
I found an article where someone explains how to extract this data, but I'm not succeding in making it work on DbContext Generator.
Has someone ever made this? Do you guys have better ideas?
Thanks!

Model View Presenter - how to implement complex Properties in an IView interace

I am finding it difficult understanding how best to implement 'IView' interface properties which are not simple types, and was wondering how others approach this in a Model View Presenter application.
The articles i've read are really good but none of them seem to approach more complex Views where you have List<> properties which are of an interface type which represent a class in your domain model, i.e. IPerson, or IName etc.
I will try to outline a scenario as briefly as i possibly can.
Presume i have a requirement for a View to ultimately persist a list of names, each consisting of 3 properties 'Forename', 'Surname', and 'Title'.
Typically i will have a domain model with a class called 'Name' with the 3 properties. This domain model will implement an Interface (in a separate 'Interfaces' class Library) called 'IName'.
Now in the 'Views' namespace in my 'Interaces' library i have an interface called 'IViewNames'. This is the view interface which any view which wants to ultimately persist the list of names will implement.
How to define this 'IViewNames' interface puzzles me. If i give it a property like so:
public List<IName> Names {get;set;}
then my implementing concrete view will ultimately have a complex property 'Names' which will need a 'getter' which loops through the fields on the View, somehow instantiate an instance of 'IName', set its properties, add to a List, before returning the List. The 'setter' will be just as complex, receiving a list of 'INames' and iterating through them setting fields on the View.
I feel like this is breaking one of the major goals of the MVP approach, which is being able to thoroughly test the application code without any concrete View implemntations. After all, i could easily write a presenter which looks at the 'View.Names' property and sends it on to a Service Layer, or set the 'View.Names' property when receiving a list of 'Name' objects back from the Service Layer. I could easily write a lot of tests which ensure everything works, everything except from that COMPLEX property in the View.
So my question is, how do others approach IView properties which are not simple types, but are in fact types of your domain model? (well types of interfaces which represent your domain model, as i clearly dont want a reference from my Presentation Layer to my Domain Model layer).
I'm more than certain there is a known technique to achieving this in an elegant way, which adheres to the Model View Presenter goals, more than my example approach does.
Thanks in advance for any help people.
I have not worked much on the MVP design pattern but will surely try my hands on it.
Approach1 : DataBinding
In this case you can also create individual properties in IView and bind these properties in presenter to the model properties. This way, your view will not get complicated. The experience is fast and seamless as the values from UI can be directly used in model. Changing the property value in model will reflect in UI immedietly. You may have to use NotifyPropertyChange events for this.
Approach 2 : Complex Types
You can try creating List or Tuples to store these values and use the values in the presenter. You may have to use events or actions to reflect the value from model to view and vice versa.
Please let me know if it helped you. Thanks.
I have lifted this explanation from one of the articles I am writing on my website
Presenter to View Communication
There are two styles utilised for populating the View with data from the Presenter and Model that I have used. The only difference between them is how tightly coupled you mind your View being to the Model. For the example of this, we will have the following as our Model:
public class Person
{
public int ID { get; private set; }
public int Age { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
Public Genders Gender { get; set; }
}
Method 1: Using the Model
Now our View code:
public interface IEmployeesView
{
void ClearList();
void PopulateList(IEnumerable<Person> people);
}
And finally the Presenter:
public class IEmployeesPresenter
{
public void Display()
{
_view.ClearList();
_view.PopulateList(_model.AllEmployees);
}
}
This method of population produces a link between the Model and the View; the Person object used as a parameter in PopulateList.
The advantage of this is that the concrete implementation of the IEmployeesView can decide on what to display in its list of people, picking from any or all of the properties on the Person.
Their are two disadvantages of this method. The first is that there is nothing stopping the View from calling methods on the Person, which makes it easy for lazy code to slip in. The second is that if the model were to change from a List<Person> to a List<Dog> for instance, not only would the Model and the Presenter need to change, but so the View would too.
Method 2: Using Generic Types
The other method population relies on using Tuple<...>, KeyValuePair<,> and custom classes and structs:
Now our View code:
public interface IEmployeesView
{
void ClearList();
void PopulateList(IEnumerable<Tuple<int, String> names);
}
And finally the Presenter:
public class IEmployeesPresenter
{
public void Display()
{
var names = _model.AllEmployees.Select(x => new Tuple<int, String>(x.ID, x.FirstName + " " + x.LastName));
_view.ClearList();
_view.PopulateList(names);
}
}
The advantages of this method of population is that the Model is free to change without needing to update the View, and the View has no decisions to make on what to display. It also prevents the View from calling any extra methods on the Person, as it does not have a reference to it.
The down sides to this method, are that you loose strong typing, and discoverability - It is quite obvious what a Person is but what a Tuple<int, String> is less obvious.