I am having trouble with the with mvc2.
I am using the Entity Framework as my ORM. I have used the POCO Entity Generator to create POCO objects. I moved the generated objects to a separate project. I followed steps outlined here(Tutorial). This is my project structure
Sports.Data - Entity Frmework and Data Access
Sports.Entities - The poco objects generated and buddy classes
Sports.Web - The web application
In the Sports.Entities project I have created buddy classes for the generated pocos.
The problem I am having is that the attributes are being ignored by the mvc. The validation is not working and the correct label text is not being displayed. Instead of 'Shirt Size', 'ShirtSize' is displayed.
What am I doing wrong?
Thanks for any help.
Here is the code.
<div>
<%: Html.LabelFor(m => m.Player.ShirtSize)%>
</div>
<div class="editor-field">
<%: Html.EditorFor(m => m.Player.ShirtSize) %>
<%: Html.ValidationMessageFor(m => m.Player.ShirtSize)%>
<div>
namespace Sports.Entities
{
[MetadataType(typeof(PlayerMetadata))]
public partial class Player
{
public double PointsPerGame {
get { return (double) this.Points / this.MatchesPlayed; }
}
}
public class PlayerMetadata
{
[Required(AllowEmptyStrings = false, ErrorMessage = "First Name is required.")]
[StringLength(50, ErrorMessage = "First Name must be 50 characters or less")]
[DataType(DataType.Text)]
object FirstName { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Last Name is required.")]
[StringLength(50, ErrorMessage = "First Name must be 50 characters or less")]
[DataType(DataType.Text)]
object LastName { get; set; }
[Required(ErrorMessage = "Shirt Size is required.")]
[EnumDataType(typeof(ShirtSizeEnum), ErrorMessage = "Shirt Size is invalid.")]
[DisplayName("Shirt Size")]
object ShirtSize { get; set; }
[Required(ErrorMessage = "Gender is required.")]
[EnumDataType(typeof(GenderEnum) , ErrorMessage = "Gender is invalid.")]
object Gender { get; set; }
[Required(AllowEmptyStrings = false , ErrorMessage = "Date of birth is required.")]
[DataType(DataType.Date)]
object DateOfBirth { get; set; }
}
}
Thanks for your answer. I figured out the problem. The properties in the buddy classes need to be public. Everything started working after I made the properties public.
public object ShirtSize { get; set; }
Hmm, the code you posted look pretty solid. Is your view strongly typed and inheriting the appropriate class?
Inherits="System.Web.Mvc.ViewPage(Of YourWebApp.Sports.Entities.Player)
also, this might sound like a dumb question, but are you passing the populated Player object back to the view both when you first populate the view and when you post it back? and finally are you making sure to check
if ModelState.IsValid?
Related
I have a razor view with the following:
#Html.EditorForModel()
It displays the properties in the model in the order they appear in the model. Is it possible to order them using some kind of annotation that is already built into the MVC framework (ASP.NET MVC 5.2.6)?
Try setting an order on your display attributes within your model for each property, like so:
public class Person
{
[Display(Name = "First Name", Order = 0)]
public string FirstName { get; set; }
[Display(Name = "Last Name", Order = 1)]
public string LastName { get; set; }
}
More information about the DisplayAttribute.Order property can be found here:
https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.displayattribute.order?redirectedfrom=MSDN&view=netframework-4.7.2#System_ComponentModel_DataAnnotations_DisplayAttribute_Order
I want to return empty string for my validation in ASP.NET MVC 5 project. I have created a property in my view model:
[Required(ErrorMessageResourceType = typeof(TestResources), ErrorMessageResourceName = "Empty_Message", ErrorMessage = null)]
public int? TestProperty { get; set; }
Inside a view:
#Html.ValidationMessageFor(x => x.TestProperty)
When I try this one I get the default message "This field is required.". I want it to be empty in this case, because I add a class to error message's span element that shows up some icon.
I tried something like that:
[Required(ErrorMessage = "")]
public int? TestProperty { get; set; }
...but got an error:
Either ErrorMessageString or ErrorMessageResourceName must be set, but
not both.
Try setting a space. Example "Space". That would solve your problem.
[Required(ErrorMessage = " ")]
public int? TestProperty { get; set; }
you can use the following code:
[DisplayFormat(ConvertEmptyStringToNull=false)]
Reference for more details:
RequiredAttribute with AllowEmptyString=true in ASP.NET MVC 3 unobtrusive validation
I have the following model:
public class Contact
{
public Contact()
{
Name = "Your Name";
Email = "Your Email";
Message = "Your Message";
}
[Required]
[StringLength(60,MinimumLength = 3)]
public string Name { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[RegularExpression(#"\b[A-Z0-9._%-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\b")]
public string Email { get; set; }
[Required]
[StringLength(2200, MinimumLength = 10)]
[DataType(DataType.MultilineText)]
public string Message { get; set; }
}
For Message and Name, their default values (in the constructor) actually pass validation, obviously that is bad. I know I could check for this and throw an error in the Controller, but I'm trying to find a way to do these in the model (as I assume that is the correct place to do it).
I wouldn't do this at all server side. Use a textbox watermark ala one of the many methods for ex.
http://code.google.com/p/jquery-watermark/
Those look like hints, not default values. You should implement these with javascript, instead of setting them as input values.
I have a model called Organisation, on the organisation I have a remote validation attribute:
[Required(ErrorMessage = "The organisation name is required")]
[Remote("NameCheck", "Manage", "Organisations", ErrorMessage="That organisation already exists")]
public string Name { get; set; }
This checks that the name of the organisation someone is adding doesn't already exists. If it does then they get an error message saying so.
I'm using a strongly typed view to render the organisation "edit" view. Because someone is editing, I don't want that remote validation to run because of course the organisation will exist.
Is there any way to achieve this? Basically, turn off the remote validation in some way when editing an organisation and have it turned on when creating an organisation.
You could/SHOULD use different view models for the two views. So for example you will have CreateOrganizationViewModel and UpdateOrganizationViewModel. On the first view model the Name property will be decorated with the remote attribute whereas on the second view model it will not.
public class BaseOrganizationModel {
public int ID {get; set;}
}
public class UpdateOrganizationModel : BaseOrganizationModel {
[Required(ErrorMessage = "The organisation name is required")]
public string Name { get; set; }
}
public class InsertOrganizationModel : BaseOrganizationModel {
[Required(ErrorMessage = "The organisation name is required")]
[Remote("NameCheck", "Manage", "Organisations", ErrorMessage="That organisation already exists")]
public string Name { get; set; }
}
I tried decorating the POCO class with [Display(Name="First Name")] Like follows...
public int Id { get; set; }
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
And also using the [DisplayName("First Name")] attribute.
No matter what, the default "List" view generated (using the "Add Controller" dialog box) always generates the table with the property names (like "FirstName") as the header text without honoring the attribute values. Create view works fine with the [Display(Name=...)] attribute though.
The List.tt T4 template actually has:
<th>
<#= property.AssociationName #>
</th>
whereas the Create.tt template has:
<#
if (property.IsForeignKey) {
#>
#Html.LabelFor(model => model.<#= property.Name #>, "<#= property.AssociationName #>")
<#
} else {
#>
#Html.LabelFor(model => model.<#= property.Name #>)
<#
}
#>
Is there anything else to do to make the default scaffolding use the Display attribute? Or should I edit the List.tt T4 template to use something else than <# property.AssociationName #>?
Of course I can edit the generated view. But I like to 'fix' this in the template itself so that ALL the views generated will be correct without modifying.
Thanks in advance for the answers.
The Display Data Annotation attribute is only honored by the Html.LabelFor method, so as your List.tt only "prints out" the particular AssociationName for each property, that's what you actually get.
If you want it to print out the Display name for each property, you will also have to spit out a LabelFor method there, just like in your Create.tt:
#Html.LabelFor(model => model.<#= property.Name #>)
Or even better, just copy the whole thing there, so the case when the property is a foreign key is also handled.