MVC how to set values metadata - asp.net-mvc

I am doing testing of a form, it has many fields. I want to set the value of the fields so I do not have to keep re-entering it. Is there a way to set it in the class metadata area, where I also set it as Required type.
[MetadataType(typeof(myMetaData))]
public partial class myClass
{
[Required]
[Display(Name = "Zip")]
public string Zip { get; set; }
[Required]
[Display(Name = "State")]
public string State { get; set; }
[Required]
[Display(Name = "City")]
public string City { get; set; }

Use DefaultValue attribute for this.
[Required]
[Display(Name = "City")]
[DefaultValue("London")]
public string City { get; set; }
This will resolve your concern.

Related

HowTo fetch data to viewmodel the quickest way

I have a simple problem with my site.
Inside my site, I'm using two different models, with some identical named fields.
Because of collision, I have to give them unique names and for not loosing the modelbinding, I decided to use viewModels.
So I have a Model like this:
namespace MySite.Models
{
public class Function : BaseEntity
{
//Beziehung zur Funktionsgruppe
[Required]
[Display(Name = "Übergeordnete Funktion")]
public int FunctionGroupId { get; set; }
public virtual FunctionGroup FunctionGroup { get; set; }
[Required]
[StringLength(200)]
[Display(Name = "Bezeichnung")]
public string Name { get; set; }
}
}
And I have a new ViewModel like this:
namespace MySite.ViewModels
{
public class FunctionViewModel
{
//Properties of BaseEntity
public int F_Id { get; set; }
[Display(Name = "Erstellt")]
public string F_Created { get; set; }
[Display(Name = "Bearbeitet")]
public string F_LastChange { get; set; }
[Display(Name = "Bearbeiter")]
public string F_ByUser { get; set; }
//Beziehung zur Funktionsgruppe
[Required]
[Display(Name = "Übergeordnete Funktion")]
public int F_FunctionGroupId { get; set; }
public virtual FunctionGroup F_FunctionGroup { get; set; }
[Required]
[StringLength(200)]
[Display(Name = "Bezeichnung")]
public string F_Name { get; set; }
}
}
Now my Question is, is there a way to automatically fetch the data of the corresponding model, while loading the ViewModel?
Something like a kind of function directly inside the { get; set; }?
Actually I load field by field form the model into the ViewModel.
Hope that I could have described Right, what I'd like to do.
Carsten
You can use Automapper for mapping or getting your data from Model to ViewModel or vice-versa. It will be hard for you to map/configure if your name of your property is different so have the same name in view model as well. (If possible)

Display different parts of model in EditorTemplate in MVC

When creating a form for a Store I have one ContactPerson and one EconomyPerson. For each of them I need the name to be required but the email should not even be visible in the form for the EconomyPerson.
I would like to use the EditorTemplate for my class Person. But can I hide input fields and change the validation requirements from the Store class?
public class Person
{
[Required]
public String FirstName { get; set; }
[Required]
public String LastName { get; set; }
[Required]
public String Email { get; set; }
[Required]
public String PhoneNumber { get; set; }
public String MobileNumber { get; set; }
}
public class Store
{
[Required]
public Person ContactPerson { get; set; }
[Required]
public Person EconomyPerson{ get; set; }
}

TryValidateModel not assigning object, returning all nulls, MVCStore Example

In the Checkout Controller I have the code
[HttpPost]
public ActionResult AddressAndPayment(FormCollection values)
{
var order = new Order();
TryValidateModel(order);
....
The model looks like this
[Bind(Exclude="OrderId")]
public partial class Order
{
[ScaffoldColumn(false)]
public int OrderId { get; set; }
[ScaffoldColumn(false)]
public string Username { get; set; }
[Required(ErrorMessage= "First Name is required")]
[DisplayName("First Name")]
[StringLength(160)]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last Name is required")]
[DisplayName("Last Name")]
[StringLength(160)]
public string LastName { get; set; }
[Required(ErrorMessage="Address is required")]
[StringLength(70)]
public string Address { get; set; }
[Required(ErrorMessage = "City is required")]
[StringLength(40)]
public string City { get; set; }
[Required(ErrorMessage = "State is required")]
[StringLength(40)]
public string State { get; set; }
[Required(ErrorMessage = "Postal Code is required")]
[DisplayName("Postal Code")]
[StringLength(10)]
public string PostalCode { get; set; }
[Required(ErrorMessage="Country is required")]
[StringLength(40)]
public string Country { get; set; }
[Required(ErrorMessage= "Phone is required")]
[StringLength(24)]
public string Phone { get; set; }
[Required(ErrorMessage="Email Address is required")]
[DisplayName("Email Address")]
[RegularExpression(#"[A-za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}", ErrorMessage="Email is not valid.")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[ScaffoldColumn(false)]
public decimal Total { get; set; }
[ScaffoldColumn(false)]
public DateTime OrderDate { get; set; }
public List<OrderDetail> OrderDetails { get; set; }
}
I can stop right before the TryValidateModel line and look at form values like
? Request.Form["FirstName"]
"Michael"
? values["FirstName"]
"Michael"
So why does TryValidateModel(order); return false and the order object does not get populated?
Update
To clarify my question I know false means it can not bind but I do not know why it can not bind. Or that it should through the TryValidateModel(or even the ValidateModel)
But what is interesting is that if I change my method signature to
public ActionResult AddressAndPayment(Order order)
order gets populated correctly. So if it is able to bind in the Method call why not TryValidateModel(or even the ValidateModel)?
I am using MVC 4
TryValidateModel returns false when validation of the Form Model against your Orders Model Fails, thus Binding fails.
I hate using
TryValidateModel(order);
and prefer
ValidateModel(order);
early on while developing my page, because binding is a delicate process. This way, if the model fails to bind, I get an exception and an indicative error msg.

One Model only update some fields in each view

I am wondering what is the correct way to approach this. I currently have one model - (shown below), which contains all the fields required for my record.
My issue is that when the record is created I only need to pass data for
CustomerID, EmployeeID, Date and ArrivalTime.
The remainder of the fields in the model will be populated when the record is updated at a later stage.
As some of my fields are required this will obviously cause validation errors if I don't post data for those fields.
I am wondering what is the best practice to achieve this?
Should I split the model into two?, or can I do partial validation?
public class CustomerSupportRecord
{
public int CustomerSupportRecordID { get; set; }
[Required]
public int CustomerID { get; set; }
[Required]
public string EmployeeID { get; set; }
[Required(ErrorMessage = "Please enter a Date")]
[DataType(DataType.Date)]
[Display(Name = "Date")]
public DateTime Date { get; set; }
[Required(ErrorMessage = "Please select an Arrival Time")]
[DataType(DataType.Time)]
[Display(Name = "Arrival")]
public DateTime ArrivalTime { get; set; }
[Required(ErrorMessage = "Please select a Departure Time")]
[DataType(DataType.Time)]
[Display(Name = "Departure")]
public DateTime DepartureTime { get; set; }
[Required(ErrorMessage = "Please select a Type")]
[Display(Name = "Type")]
public int CustomerSupportTypeID { get; set; }
[Display(Name = "Setting")]
public string ReflectionSetting { get; set; }
[Display(Name = "Advisor")]
public string ReflectionAdvisor { get; set; }
[Display(Name = "Notes")]
public string Notes { get; set; }
[Display(Name = "Comments")]
public string Comments { get; set; }
// Navigation Properties
public virtual Customer Customer { get; set; }
public virtual CustomerSupportType CustomerSupportType { get; set; }
public virtual Employee Employee { get; set; }
}
The correct approach would be to use different viewmodel classes for the different views and only include the properties you need on that view.
So your viewmodel for the first view look just like this:
public class CustomerSupportRecordForCreation
{
public int CustomerSupportRecordID { get; set; }
[Required]
public int CustomerID { get; set; }
[Required]
public string EmployeeID { get; set; }
[Required(ErrorMessage = "Please enter a Date")]
[DataType(DataType.Date)]
[Display(Name = "Date")]
public DateTime Date { get; set; }
[Required(ErrorMessage = "Please select an Arrival Time")]
[DataType(DataType.Time)]
[Display(Name = "Arrival")]
public DateTime ArrivalTime { get; set; }
}
You will have to map between that viewmodel classes and your domain/dal classes. This is where tools like AutoMapper comes in handy.
Edit Automapper:
Using Automapper is really simple.
You have to configure your mappings (i.e. in Application_Start). When the properties of the classes you want to map are named identically, its simple as this:
Mapper.CreateMap<CustomerSupportRecord,
CustomerSupportRecordForCreation>();
Then you can use the mapped in your app. When you have a CustomerSupportRecord and want to return the CustomerSupportRecordForCreation for your view write:
CustomerSupportRecord record = getRecordFromDb...
return View(Mapper.Map<CustomerSupportRecordForCreation>(record));
There is a good tutorial article on Codeproject: http://www.codeproject.com/Articles/61629/AutoMapper or just google

ASP.NET MVC 3 Complex Type Validation

I have a situation where I need to validate a child, but only if it exists. Basically the user can enter either a bank account or a credit card, and I only want to validate the one they enter.
Here are the Models:
public class AccountViewModel
{
[Required]
public bool isBankAccount { get; set; }
[RequiredIf("isBankAccount")]
public BankAccount BankAccount { get; set; }
[RequiredIf("isBankAccount",
IfNot = true)]
public CreditCard CreditCard { get; set; }
}
public class CreditCard
{
[Required]
[CreditCard]
public string CreditCardNumber { get; set; }
[Required]
[Range(1, 12)]
public int? ExpiryMonth { get; set; }
[Required]
[Range(2000, 3000)]
public int? ExpiryYear { get; set; }
[Required]
public string CardHolderName { get; set; }
}
public class BankAccount
{
[Required]
public string BSB { get; set; }
[Required]
[StringLength(10,
MinimumLength = 3)]
[NumbersOnly]
public string AccountNumber { get; set; }
[Required]
public string AccountHolderName { get; set; }
}
My problem is that the children's attributes are still being validated despite the parent attribute validating as true. Is there a way to stop the children from validating if the parent says so?
Why not make a property PaymentMode , derive both Bank and CC from PaymentMode, make the field required, and handle it in UI as to what user can select and enter.
Just a thought.

Resources