I simply am trying to declare partial classes for the tool-generated LLBLGenPro (partial) classes, so that I can use DataAnnotation for validation purposes. However, things don't seem to work here.
Following is how my code looks like :
namespace MyApp.DataLayer.EntityClasses
{
[Serializable]
public partial class LoginEntity : CommonEntityBase, ISerializable
{
.....
}
}
And for DataAnnotations ...
namespace MyApp.DataLayer.EntityClasses
{
[MetadataType(typeof(LoginEntityValidation))]
public partial class LoginEntity
{
}
public class LoginEntityValidation
{
[Required(ErrorMessage = "Required !")]
public string Username { get; set; }
}
}
// This gives me compile time errors "MyApp.DataLayer.EntityClasses.LoginEntity' does not contain a constructor that takes 1 arguments" and so on.
Any idea on how to make this working?
Thanks in advance !
You should not use your entity classes in views. You should use ViewModel classes and put validation there. For entity->viewmodel conversion you can use AutoMapper
Related
I have a problem using the ScriptIgnore tag on my partial view to stop a property from serializing.
var docs = #Html.Raw(Json.Encode(Model))
The funny thing is, when I add the attribute directly to the partial class in the .tt file, it works as expected, but because that file will be overwritten when I do a code-gen, I tried using MetadataType
[MetadataType(typeof(DocumentMeta))] //this is added so we can add meta data to our partial class..
public partial class Document
{
}
[MetadataType(typeof(DocumentCategoryMeta))] //this is added so we can add meta data to our partial class..
public partial class DocumentCategory
{
}
public class DocumentMeta
{
[ScriptIgnore] //We add the scriptignore here because we are serializing some of these entities in client code
public virtual ICollection<DocumentCategory> DocumentCategories { get; set; }
}
public class DocumentCategoryMeta
{
[ScriptIgnore] //We add the scriptignore here because we are serializing some of these entities in client code
public virtual DocumentCategory Parent { get; set; }
}
I still get the same error:
A circular reference was detected while serializing an object of type 'DocumentCategory'.
Because DocumentCategory contains hierarchical data.
Any help would be greatly appreciated!
Tribe84
try [ScriptIgnore(ApplyToOverrides = true)]
For all virtual Properties you should use the ScriptIgnore attribute, like this: [ScriptIgnore(ApplyToOverrides = true)]
This is my first question, and I've agonised over what to write for a couple of days while Ive been trying to solve this problem.
I bought the Dependency Injection in .NET book by Mark Seeman, and have been trying to follow that and the examples on the Ninject website for creating an abstract factory class. The general idea is that I have a form contains a list of answers to questions. Answers can be of various types, so I am using a factory to create the relevant answer type.
I'm getting the error:
Error activating IAnswerValue
No matching bindings are available, and the type is not self-bindable.
Activation path:
1) Request for IAnswerValue
Suggestions:
1) Ensure that you have defined a binding for IAnswerValue.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.
I initially tried with a parameter, but to simplify things for this example, Ive stripped it all out. None of the suggestions given in the error message seem to apply, the factory type is binding, as is the form service but the answervalue is apparently not.
This is the code from my NinjectWebCommon.cs
kernel.Bind<DomainModel.IAnswerValue>().To<DomainModel.AnswerValue>();
kernel.Bind<DomainModel.IAnswerValue>().To<DomainModel.StringAnswerValue>();
kernel.Bind<DomainModel.IAnswerValue>().To<DomainModel.DateTimeAnswerValue>();
kernel.Bind<IAnswerValueFactory>().ToFactory();
This is the answer class definition:
public class Answer
{
readonly IAnswerValueFactory answerValueFactory;
public int Id { get; set; }
public Question Question { get; set; }
public string Type { get; set; }
public Answer(IAnswerValueFactory answerValueFactory)
{
this.answerValueFactory = answerValueFactory;
}
public void GetAnswerValue()
{
var answer = this.answerValueFactory.GetAnswerValue();
}
public List<AnswerItem> PotentialAnswers { get; set; }
}
and the answer value:
public interface IAnswerValue
{
AnswerValue GetAnswerValue();
}
public class AnswerValue : IAnswerValue
{
readonly IAnswerValue answerValue;
public AnswerValue() { }
public AnswerValue(IAnswerValue answerValue)
{
this.answerValue = answerValue;
}
public AnswerValue GetAnswerValue()
{
// this will contain a switch statement to
// determine the type returned but I have
// omitted for this example
return new StringAnswerValue();
}
}
public class StringAnswerValue : AnswerValue
{
public string StringAnswer { get; set; }
}
and the factory:
public class AnswerValueFactory : IAnswerValueFactory
{
readonly IAnswerValue answerValue;
public AnswerValueFactory(IAnswerValue answerValue)
{
this.answerValue = answerValue;
}
public IAnswerValue GetAnswerValue()
{
return (IAnswerValue)this.answerValue.GetAnswerValue();
}
}
I feel like Ive exhausted my knowledge and Im just going around in circles trying the same thing over and over. There must be something quite simple Im missing, but I just cant see what it is.
I'm having a problem with display templates and dealing with interfaces and objects which implement the interface. In the example I have many objects, which I want to be rendered in a fixed way, I decided to create an interface and reference this in the view which I've decided to put into the shared display templates folder. DisplayFor doesn't seam to work for objects passed to it which implement the interface in the view, does any one know a solution to this.
Its probably easier to explain via code so I've wrote a quick example. The base interface and two classes which inherit from it:
public interface IPet
{
String Name { get; }
}
public class Dog : IPet
{
public String Name { get; set; }
}
public class Cat : IPet
{
public String Name { get; set; }
}
The example display template in shared display templates
#model IPet
<div>#Model.Name</div>
The example view model to be passed to the view
public class VM
{
public IPet Master { get; set; }
public IEnumerable<IPet> Minions { get; set; }
}
The controller (in this case to create mock information)
public ActionResult Index()
{
var viewModel = new VM();
viewModel.Master = new Cat(){Name = "Fluffy"};
var minions = new List<IPet>();
minions.Add(new Dog(){Name = "Dave"});
minions.Add(new Dog(){Name = "Pete"});
minions.Add(new Cat(){Name = "Alice"});
viewModel.Minions = minions;
return View(viewModel);
}
and finally the view which I would expect DisplayFor to work
#model ViewInheritance.Models.VM
<h2>Master</h2>
#Html.DisplayFor(x => x.Master)
<h2>Minions</h2>
#Html.DisplayFor(x => x.Minions)
Given that all the objects are are defined in the view model as the interfaces, howcome it fails to use the display template?
One solution I have found is to simply use the code
#Html.DisplayFor(x => x.Master, "IPet")
To recap, the question is:
Why does this happen?
Is there a way to make DisplayFor correctly work out that a type of Cat which implements IPet should in fact be looking at the common shared view IPet.cshtml?
Thanks
Starting a new MVC application and fixing the code to actually compile the view renders fine. It also renders fine when moving the view into the shared folder.
I Added setter to IPet:
public interface IPet
{
String Name { get; set; }
}
I updated implementation and added public accessors:
public class Dog : IPet
{
public String Name { get; set; }
}
public class Cat : IPet
{
public String Name { get; set; }
}
I left your VM alone and also did not change any code in your View.
Pressing F5, running the MVC application rendered the results as expected (See image).
Unfortunately, I don't think ASP.NET MVC currently supports automatically selecting templates based on implemented interfaces. I think this makes sense because a class could implement multiple interfaces, so if you had templates for more than one of those interfaces, which one should the framework choose?
You could use a base class instead of an interface if your design can cope with it:
Change IPet to a (possibly abstract) class.
Change IPet.cshtml to Pet.cshtml.
Otherwise I think you'll just need to explicitly tell the framework which template to use. Here are some options:
Decorate the view model properties with [UIHint].
Specify the template in your calls to your HtmlHelper methods such as DisplayFor.
Make your own ModelMetadataProvider and change the TemplateHint property of the resulting ModelMetadata.
I'd like to create a custom validation attribute for MVC2 for an email address that doesn't inherit from RegularExpressionAttribute but that can be used in client validation. Can anyone point me in the right direction?
I tried something as simple as this:
[AttributeUsage( AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false )]
public class EmailAddressAttribute : RegularExpressionAttribute
{
public EmailAddressAttribute( )
: base( Validation.EmailAddressRegex ) { }
}
but it doesn't seem to work for the client. However, if I use RegularExpression(Validation.EmailAddressRegex)] it seems to work fine.
You need to register an adapter for the new attribute in order to enable client side validation.
Since the RegularExpressionAttribute already has an adapter, which is RegularExpressionAttributeAdapter, all you have to do is reuse it.
Use a static constructor to keep all the necessary code within the same class.
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class EmailAddressAttribute : RegularExpressionAttribute
{
private const string pattern = #"^\w+([-+.]*[\w-]+)*#(\w+([-.]?\w+)){1,}\.\w{2,4}$";
static EmailAddressAttribute()
{
// necessary to enable client side validation
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(EmailAddressAttribute), typeof(RegularExpressionAttributeAdapter));
}
public EmailAddressAttribute() : base(pattern)
{
}
}
For more information checkout this post explaining the complete process.
http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx
The CustomValidationAttribute Class MSDN page has a few examples on it now. The Phil Haacked post is out of date.
Look at the universal Dependent Property Validator in this article
Have you tried using Data Annotations?
This is my Annotations project
using System.ComponentModel.DataAnnotations;
public class IsEmailAddressAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
//do some checking on 'value' here
return true;
}
}
This is in my Models project
namespace Models
{
public class ContactFormViewModel : ValidationAttributes
{
[Required(ErrorMessage = "Please provide a short message")]
public string Message { get; set; }
}
}
This is my controller
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ContactUs(ContactFormViewModel formViewModel)
{
if (ModelState.IsValid)
{
RedirectToAction("ContactSuccess");
}
return View(formViewModel);
}
You'll need to google DataAnnotations as you need to grab the project and compile it. I'd do it but I need to get outta here for a long w/end.
Hope this helps.
EDIT
Found this as a quick google.
Brad Willson has a great article on descripting how to use DataAnnotations. http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html What I would like to do is extend the available attributes that I can use. Something like [ PastDate(you must enter a date in the past)] or [InvoiceNumber( all invoices start with INV and end with 002)]. I know that I could use the Regular expression attribute to accomplish this. However having more descriptive attributes would be a cleaner solution.
You need to create a class that inherits from System.ComponentModel.DataAnnotations.ValidationAttribute and then use that attribute like this :
public class yourModel {
[CustomValidation(typeof(yourClass), "yourMethod")]
public int yourProperty { get; set; }
}
Haven't tried it but it should work.
I have a few of these in my project - some still use regular expressions, but at least this way they're only in one place:
public class TelephoneAttribute : RegularExpressionAttribute
{
public TelephoneAttribute()
: base(#"^\(?(\d{3}\)?)((-| )?\d{3})(-?\d{4})$") { }
}
And more like what your example:
public class MinimumDateAttribute : RangeAttribute
{
public MinimumDateAttribute(string MinimumDate)
: base(typeof(DateTime), MinimumDate, DateTime.MaxValue.ToShortDateString()) { }
}