I am reading a book on ASP.NET MVC, and it refers to "members of a view model class"? Specifically what are "members"? An example would help greatly!
Thanks!
A class member could be property, field, method, constant, event, ...
Here's an example of a view model with a property (which is a member):
public class MyViewModel
{
public string FooBar { get; set; }
}
or with a property and a method:
public class MyViewModel
{
public string FooBar { get; set; }
public string FormatTheFoo()
{
return string.Format("{0} bazinga", this.FooBar);
}
}
As far as events are concerned, well, they are indeed members, but in terms of an ASP.NET MVC view model, they are probably not something commonly used.
Related
I have the same problem as this question and tried the suggested solutions but no luck.. Any help will be very appreciated.
Bind Exclude not working Model Binding for child objects in ASP.Net MVC
The problem is as following:
I got into a issue in Model Binding in Asp.Net MVC. I have view model like below,
public class ArticleViewModel : BaseViewModel
{
public Article art { get; set; }
public List<ArticleAttachment> attachments { get; set; }
}
I am trying to exclude model binding a property on the "Article" child object as seen below in my action method,
[HttpPost]
[ValidateInput(false)]
public ActionResult New([Bind(Exclude = "art.Abstract")]ArticleViewModel articleVM)
{
But the model binder populates the property called Abstract even with the above setting.
To make this work, you need to apply the [Bind] attribute the ArticleAttachment class.
[Bind(Exclude="Abstract")]
public class ArticleAttachment
{
public string Abstract { get; set; }
....
}
However, any time you use either the [Bind(Include="..")] or [Bind(Exclude="..")] attributes, delete them and do it properly using a view model to represent what you want to edit.
I have a question relating to best practices on validation using MVC and POCO. From what I can tell, the best practice is to have a ViewModel that mirrors the POCO and then use something like AutoMapper to parse the ViewModel to the POCO after it (the view model) is validated.
That's all well and good, but I'm wondering if there are any problems with inheriting from the POCO and over ridding only properties I wish to validate in the View Model?
POCO:
public partial class Sector
{
public virtual int SectorId { get; set; }
public virtual string Name { get; set; }
}
My ViewModel might look like this:
public class SectorDTO : Sector
{
[Required]
[StringLength(10)]
public override string Name {get; set;}
}
UPDATE
This solution ended up not working, mostly due to the way my business layer and data layer's are setup. My solution was instead to create a ViewModel that contained a DTO with all the validation, and then use AutoMapper to change the object back to the POCO type.
I did like below:
public partial class SectorMetaData
{
[Required(ErrorMessage="Required Filed")]
public int SectorId{ get; set;}
[Required(ErrorMessage="Required Filed")]
public string Name{get; set;}
}
[MetadataType(typeof(SectorMetaData))]
public partial class Sector
{
public int SectorId{ get; set;}
public string Name{get; set;}
}
This class should be same namespace as POCO class.
Hope this helps!
I have very simple question that I cannot find the answer to.
In the razor view there's a Model of interface type. That interface have multiple subclasses implementing it.
The question is: How can I cast the model to its actual type?
I MUST have variable of actual type but don't know how to get it from the reflection
I.E.
#model IInterface
#{
var actualType1 = Model as Model.GetType(); // doesn't work :(
var actualType2 = (Model.GetType()) Model; // doesn't work :(
}
As you can imagine I am not interested in Model as ActualType or (ActualType) Model because I don't know what actual type is coming in advance. Its a question about the technique rather than architecture.
Thanks in advance!
You are really on the wrong path here. You can't really do what you're looking to do here, because you are not really thinking it through. A statement like this:
var actualType1 = Model as Model.GetType();
Won't work because var is not a dynamic type, it's a static type that is typed at compile time, not at runtime. So even if you could somehow manage to get it to work, it would only work for one type, ever (until it was recompiled again).
In addition to that, interfaces are a poor choice for this, because interface attributes are seperate from implementation attributes. So regardless of what attributes you have on your classes, you will not get them via an interface to that class.
Sounds like you have, according to your OP comments, some data annotation problems. I would highly suggest completely recreating some models and interfaces that use the MetadataType.
public SomeViewModel
{
public string FormField { get; set; }
public string FormField2 { get; set; }
}
public interface IAnonymousSomeViewModel
{
[Required]
public string FormField { get; set; }
[Scaffold(false)]
public string FormField2 { get; set; }
}
public interface IUserSomeViewModel
{
[Scaffold(false)]
public string FormField { get; set; }
[Required]
public string FormField2 { get; set; }
}
[MetadataType(typeof(IAnonymousSomeVieModel)]
public AnonymousViewModel : SomeViewModel { }
[MetadataType(typeof(IUserSomeVieModel)]
public UserViewModel : SomeViewModel { }
In your View you pass either AnonymousViewModel or UserViewModel, then there is NO logic in the view:
#model SomeViewModel
#Html.EditorFor(m => m.FormField)
#Html.EditorFor(m => m.FormField2)
I've seen somewhere how to do this before on a blog but I forgot where or how. Lets say I have a domain in a class library. I'd like to data annotate the properties of this domain as my viewmodel in the web project.
How do I accomplish this?
For example. This domain is in my class library:
public class Person {
public int Id {get; set;}
public string FirstName {get; set;}
}
In my web project, there is this:
//Do i need to set some attribute here?
public class CreatePersonViewModel{
[Required()]
[DisplayName("First Name")]
public string FirstName {get; set;}
}
This code can be mapped to Person without a tool. Probably partial or something.
The whole idea of using a view model is to decouple it from your domain model and to have something which is adapted to the needs of the view. The view model should be declared in the web project and contain all the necessary properties and formatting attributes that this particular view might require. The domain model shouldn't be polluted with any view specific data annotations. So if your model looks like this:
public class Person {
public int Id { get; set; }
public string FirstName { get; set; }
}
You could have the following view model:
public class CreatePersonViewModel {
[Required]
[DisplayName("First Name")]
public string FirstName { get; set; }
}
and then have the controller fetch the model from some repository, map it to the view model (AutoMapper can help you here) and pass the view model to the view.
Do you mean annotate your Domain objects or your view model objects?
Using the System.ComponentModel.DataAnnotations validation attributes (and deriving any of your own from ValidationAttribute, you can validate values bound to the properties of your viewmodel at the point of model binding.
Scott Guthrie has a detailed blog post about Model validation with data annotation validation attributes.
EDIT: you say in a comment to another poster that your types already exist. You can add the MetadataTypeAttribute to the existing type to indicate another type that holds the validation logic to be applied to the properties of your existing type.
You can create a 'buddy' class for your data annotation attributes
[MetadataType(typeof(ResourceMetadata))]
public partial class Resource
{
public object Value { get; set; }
}
public class ResourceMetadata
{
// The metadata class can define hints
[UIHint("ResourceValue")]
public object Value { get; set; }
}
Are you talking about this type of thing?:
using System.ComponentModel.DataAnnotations;
public MyClass
{
[DisplayName("Street Address")]
public string StreetAddress { get; set; }
}
EDIT:
If you need to add Data Annotations to generated class like an Entity do this:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
namespace Something
{
[MetadataType(typeof(MetaMyClass))]
public partial class MyClass
{
//You can just leave this empty if you have nothing additional to add to the class
}
public class MetaMyClass
{
[DisplayName("Street Address")]
public string StreetAddress { get; set; }
}
}
I have an application that have EF 16 classes that share this information: They all are classes only with a key field and a description.
I think it should be a waste if I make a controller with just 1 method just to present a form to fill these classes info, then I was thinking in to make a generic form(with key, description) and dynamically fill the right class through a sort of selection the selected info in any way, any good suggestion or pattern to do that? Where the generic methods should be located.
Have you looked into MVC templates? You should be able to use templates to automatically "generate" your Edit and Display Views. No need to create a distinct View for each of your classes.
I had similar situation and did it almost like that:
interface IKeyDescription
{
int Key { get; set; }
string Description { get; set; }
}
public partial class Class1 : IKeyDescription;
public partial class Class2 : IKeyDescription;
public abstract class BaseKeyDescriptionController<T> where T : IKeyDescription
{
[Inject]
public IKeyDescriptionService<T> Service { get; set; }
[HttpGet]
public ActionResult List()
{
//View is stored in shared folder
return View("List",Service.List());
}
[HttpPost]
public ActionResult List(IList<T> elements)
{
Service.Save(elements);
....
}
}
public class Class1Controller : BaseKeyDescriptionController<Class1>
{
}
public class Class2Controller : BaseKeyDescriptionController<Class2>
{
}
View will inherit from System.Web.Mvc.ViewPage<IKeyDescription>.