How to get a reference to a web form's ModelStateDictionary from inside a Web Forms MVP Presenter?

94 Views Asked by At

Using the Web Forms MVP framework in an ASP.NET 4.5 Web Forms application, how do I get a reference to a page's ModelStateDictionary object from inside the Presenter object for that page?

I'd like my presenter to be able to set model state errors when something goes wrong. For example: errors when attempting to insert records that violate a UNIQUE constraint.

try
{
    dbcontext.SaveChanges();
}
catch (DbUpdateException updateException)
{
    // how to get a reference to the model state?
    ModelStateDictionary state = null;

    // add the error to the model state for display by the view
    state.AddModelError("key", updateException.GetBaseException().Message);
}

A google search for "webformsmvp presenter modelstatedictionary" yields an alarmingly low number of relevant results.

1

There are 1 best solutions below

0
Steven Liekens On BEST ANSWER

One way is to pass the model state from the view to the presenter as an event argument.

First, the EventArgs class:

public class ModelStateEventArgs : EventArgs
{
    public ModelStateEventArgs(ModelStateDictionary modelState)
    {
        this.ModelState = modelState;
    }

    public ModelStateDictionary ModelState { get; private set; }
}

derive from this class if you need additional event arguments


Then, the IView that is implemented by the view:

public interface IDataContextView : IView<DataContextVM>
{
    event EventHandler<ModelStateEventArgs> Update;
}

Raising the event in the view itself:

  • MvpPage views

    this.Update(this, new ModelStateEventArgs(this.ModelState));
    
  • MvpUserControl views

    this.Update(this, new ModelStateEventArgs(this.Page.ModelState));
    

Finally, the Presenter, which can subscribe to the Update events and get the model state for each event as it happens:

public class DataContextPresenter : Presenter<IDataContextView>
{
    public DataContextPresenter(IDataContextView view)
        : base(view)
    {
        this.View.Update += OnUpdating();
    }

    private void OnUpdating(object sender, ModelStateEventArgs e)
    {
        var entity = ConvertViewModelToEntity(this.View.Model);
        dbcontext.Entry(entity).State = EntityState.Modified;
        try
        {
            dbcontext.SaveChanges();
        }
        catch (DbUpdateException updateException)
        {
            // add the error to the model state for display by the view
            e.ModelState.AddModelError(string.Empty, updateException.GetBaseException().Message);
        }
    }
}