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.
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);
}
}
}