Custom Part fields cleared on post-back

Topics: Writing modules
Oct 3, 2013 at 7:46 PM
I have an Address part that doesn't re-populate the fields if a post-back causes an error on a required field. For instance if I populate all the fields except Line1 in the form, because Line1 is Required in the model, I get an error message on the page but the other fields I filled in previously are empty. Do I have to somehow populate the fields in my Driver when I detect a model error?

Here's my Address Part Code
  public class AddressPart : ContentPart<AddressRecord>
  {
    [Required]
    public string Line1 {
      get { return Record.Line1; }
      set { Record.Line1 = value; }
    }
    public string Line2 {
      get { return Record.Line2; }
      set { Record.Line2 = value; }
    }
    [Required]
    public string City {
      get { return Record.City; }
      set { Record.City = value; }
    }
    [Required]
    public string State {
      get { return Record.State; }
      set { Record.State = value; }
    }
    [Required]
    public string PostalCode {
      get { return Record.PostalCode; }
      set { Record.PostalCode = value; }
    }
  }
Here's the Content Handler
  public class AddressHandler : ContentHandler
  {
    public AddressHandler(IRepository<AddressRecord> repository)
    {
      Filters.Add(StorageFilter.For(repository));
    }
  }
Here's the Driver
public class AddressPartDriver : ContentPartDriver<AddressPart>
  {
    private readonly IAddressService _addressService;

    public Localizer T { get; set; }
    protected override string Prefix
    {
      get
      {
        return "Address";
      }
    }

    public AddressPartDriver(IAddressService service)
    {
      _addressService = service;
      T = NullLocalizer.Instance;
    }

    protected override DriverResult Display(AddressPart part, string displayType, dynamic shapeHelper)
    {
      // Detail, Summary, Summary_Admin
      return ContentShape("Parts_Address", () =>
        shapeHelper.Parts_Address(AddressPart: part));
    }

    // GET
    protected override DriverResult Editor(AddressPart part, dynamic shapeHelper)
    {
      return ContentShape("Parts_Address_Edit", () =>
        shapeHelper.EditorTemplate(TemplateName: "Parts/Address", Model: BuildEditorViewModel(part), Prefix: Prefix));
    }

    // POST                                     posted model?, controller that handled post
    protected override DriverResult Editor(AddressPart part, IUpdateModel updater, dynamic shapeHelper)
    {
      var viewModel = new AddressEditViewModel();

      updater.TryUpdateModel(viewModel, Prefix, null, null);

      _addressService.UpdateAddress(viewModel, part);
      return Editor(part, shapeHelper);
    }
    
    private AddressEditViewModel BuildEditorViewModel(AddressPart part)
    {
      var viewModel = new AddressEditViewModel()
      {
        City = part.City,
        State = part.State,
        PostalCode = part.PostalCode,
      };
      

      if (!string.IsNullOrEmpty(part.Line2))
      {
        viewModel.Address = part.Line1 + ", " + part.Line2;
      }
      else
      {
        viewModel.Address = part.Line1;
      }

      return viewModel;
    }
  }
And lastly here's the Service
public class AddressService : IAddressService
  {
    public void UpdateAddress(ViewModels.AddressEditViewModel viewModel, Models.AddressPart part)
    {
      // verify address value before parsing
      if (!string.IsNullOrEmpty(viewModel.Address))
      {
        string[] addressChunks = viewModel.Address.Trim().Split(',');

        part.Line1 = HttpUtility.HtmlEncode(addressChunks.First());
        part.Line2 = (addressChunks.Length > 1) ? HttpUtility.HtmlEncode(addressChunks.Last()) : string.Empty;
      }

      part.City = HttpUtility.HtmlEncode(viewModel.City);
      part.State = HttpUtility.HtmlEncode(viewModel.State);
      part.PostalCode = HttpUtility.HtmlEncode(viewModel.PostalCode);
    }
  }
Thanks much!
Coordinator
Oct 4, 2013 at 3:04 AM
Might be a bug.