1

I have an entity called Invoice that I am extending for data annotations

   [MetadataType(typeof(InvoiceMetadata))]
    public partial class Invoice
    {
        // Note this class has nothing in it.  It's just here to add the class-level attribute.
    }

    public class InvoiceMetadata
    {
        // Name the field the same as EF named the property - "FirstName" for example.
        // Also, the type needs to match.  Basically just redeclare it.
        // Note that this is a field.  I think it can be a property too, but fields definitely should work.

        [HiddenInput]
        public int ID { get; set; }

        [Required]
        [UIHint("InvoiceType")]
        [Display(Name = "Invoice Type")]
        public string Status { get; set; }


        [DisplayFormat(NullDisplayText = "(null value)")]
        public Supplier Supplier { get; set; }

    }

The Uhint[InvoiceType] causes the InvoiceType Editor Template to be loaded for this element.This templates is defined as

@model System.String

@{
      IDictionary<string, string> myDictionary = new Dictionary<string, string> { 
                                                                                        { "N", "New" }
                                                                                        , { "A", "Approved" },
                                                                                        {"H","On Hold"}
                                                                                        };

      SelectList projecttypes= new SelectList(myDictionary,"Key","Value");

       @Html.DropDownListFor(model=>model,projecttypes)     

 }

i have many such hardcoded status lists in my program.I say hardcoded because they are not fetched from the database. Is there any other way to create templates for drop downs? How do I declare an enum in the model and have the drop down load the enum without having to pass it through a view model ?

superartsy
  • 489
  • 1
  • 11
  • 27

1 Answers1

1

Rather than "hard coding" your statuses I would either create an Enum or a Type Safe Enum. For your example I would use the latter.

For each of your required "status lists" create a separate class with your desired settings:

public sealed class Status
{
    private readonly string _name;
    private readonly string _value;

    public static readonly Status New = new Status("N", "New");
    public static readonly Status Approved = new Status("A", "Approved");
    public static readonly Status OnHold = new Status("H", "On Hold");

    private Status(string value, string name)
    {
        _name = name;
        _value = value;
    }

    public string GetValue()
    {
        return _value;
    }

    public override string ToString()
    {
        return _name;
    }

}

Utilizing reflection you can now get the fields of this class to create your required drop down lists. It would be beneficial to your project to either create an extension method or a helper class:

var type = typeof(Status);
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);

Dictionary<string, string> dictionary = fields.ToDictionary(
    kvp => ((Status)kvp.GetValue(kvp)).GetValue(), 
    kvp => kvp.GetValue(kvp).ToString()
    );

You can now create your select list much like you are currently doing:

var list = new SelectList(dictionary,"Key","Value");

Which will create a drop down list with the following html:

<select>
  <option value="N">New</option>
  <option value="A">Approved</option>
  <option value="H">On Hold</option>
</select>
Jesse
  • 8,223
  • 6
  • 49
  • 81
  • If I was to create a HTML extension method where do I declare the Status class- in the model? if so I have to access the model from the HTMLextension(view) is that not against the rule? – superartsy Jun 18 '12 at 14:57
  • This is where your project would benefit from the creation of "ViewModels": http://stackoverflow.com/questions/664205/viewmodel-best-practices Within the ViewModel is where you would create a property for your statuses. – Jesse Jun 18 '12 at 16:28
  • i understand the ViewModel should have the status as a property. But where do you declare the Status class- in the model? if so - hows does the extension method access that class? – superartsy Jun 19 '12 at 18:17