1

I often find myself in the situation where I only want to present and edit some fields from my model. Let's say I have a model that represts an address, perhaps I just want the form to update the city and post code fields (bad example, but hopefully it explains the scenario).

I know of two methods:

1) Persist the unwanted fields in hidden input elements on the form, or... 2) Create a dedicated view model that just defines the fields I need.

I favour option #2, but I don't have a nice clean way of merging the data from the view model back into the 'real' model within the controller action. At the moment, I follow this approach...

1) Store the record I'd in a hidden field on the view model 2) When the page posts back, the controller retrieves the original record and I manually assign each field from the view model to the real model 3) Save the real model back to the data store.

This works, but it is quite a lot of work and very easy to miss an assignment/reassignment and I was wondering if anyone knew of another approach?

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Neilski
  • 4,385
  • 5
  • 41
  • 74
  • Are you opposed to using Session? – Erik Philips Sep 01 '11 at 21:37
  • We generally try to avoid using session, but do not have any real reason for doing so other than we've found it difficult to manage (in terms of clean-up) – Neilski Sep 02 '11 at 04:44
  • I'm experimenting now with a custom model binding where identity properties are bound first, triggering the VM to load up from the repository, then, the remaining binding process functions like a merge. [See my S.O. question and proposed answer here](http://stackoverflow.com/questions/19280598/best-way-to-do-partial-update-to-net-mvc-4-model/19297099#19297099) – bkwdesign Oct 10 '13 at 15:50

1 Answers1

1

Use the System.ComponentModel.DataAnnotations.MetadataType.

Something like:

public class BaseClassOfProperties
{
   public string Name { get; set; }
}

public interface INameViewableProperties
{
   [Display(name = "Your Name")]
   string Name { get; set; }
}

public interface INameHiddenProperties
{
   //[scaffoldColumn(false)] this completely hides the fields
   [UIHint("Hidden")] // i think...
   string Name { get; set; }
}

[MetadataType(typeof(INameViewableProperties)]
public class NameViewAbleProperties : BaseClassOfProperties
{
}

[MetadataType(typeof(INameHiddenProperties)]
public class NameHiddenProperties : BaseClassOfProperties
{
}
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • Thank you Erik, I've not seen this approach before and it looks very clean/flexible. I'm not quite sure though how it helps me manage the actual update process in terms of saving the data back to the underlying database (we're using Linq to Sql). Perhaps you could expand a little further if you have the time? – Neilski Sep 02 '11 at 04:45
  • Yeah I've createded wizards were each page is a different MetadataType requiring only the fields and validation I want. Then all the other fields are just hidden input fields. I went this route because options available for the next part of the wizard required to know the previous user values. At the ends I have one really big interface to validate all my fields. One Model with multiple scaffolding and validations. – Erik Philips Sep 02 '11 at 16:46
  • Thanks Erik. I'll play wityh this approach and see how it fits my application. Either way, I've learnt something as I did not know you could apply attributes to an interface class :-) – Neilski Sep 02 '11 at 17:32