views:

42

answers:

1

A user submits registration information to the form:

<h2>Create</h2>

<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="Nbk">Nbk:</label>
            <%= Html.TextBox("Nbk",null, new  {Disabled="Disabled" })%>
            <%= Html.ValidationMessage("Nbk", "*") %>
        </p>
        <p>
            <label for="Name">Name:</label>
            <%= Html.TextBox("Name") %>
            <%= Html.ValidationMessage("Name", "*") %>
        </p>
        <p>
            <label for="Email">Email:</label>
            <%= Html.TextBox("Email") %>
            <%= Html.ValidationMessage("Email", "*") %>
        </p>
        <p>
            <label for="MailCode">MailCode:</label>
            <%= Html.TextBox("MailCode") %>
            <%= Html.ValidationMessage("MailCode", "*") %>
        </p>
        <p>
            <label for="TelephoneNumber">TelephoneNumber:</label>
            <%= Html.TextBox("TelephoneNumber") %>
            <%= Html.ValidationMessage("TelephoneNumber", "*") %>
        </p>
        <p>
            <label for="OrganizationId">OrganizationId:</label>
            <%= Html.TextBox("OrganizationId") %>
            <%= Html.ValidationMessage("OrganizationId", "*") %>
        </p>
        <p>
            <label for="OrganizationSponsorId">OrganizationSponsorId:</label>
            <%= Html.TextBox("OrganizationSponsorId") %>
            <%= Html.ValidationMessage("OrganizationSponsorId", "*") %>
        </p>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

<% } %>

Controller:

[Authorize]
 [AcceptVerbs(HttpVerbs.Post)]
 public ActionResult Create(DefectSeverityAssessmentBusiness.ModelRegistration registration)
 {
  registration.Nbk = StateController.GetNbk(Request);
  try
  {
   var errors = DataAnnotationsValidationRunner.GetErrors(registration);
   if (errors.Any())
    foreach (var item in errors)
    {
     if( ModelState[item.PropertyName].Errors.Count==0)
     ModelState.AddModelError(item.PropertyName, item.ErrorMessage);
     //ModelState.SetModelValue(item.PropertyName,ViewData[item.PropertyName].ToValueProvider());
    }
   if (ModelState.IsValid)
   {
    _RegistrationRepository.CreateRegistration(registration);
    return RedirectToAction("Index", "Assessment");
   }
  }
  catch (Exception exception)
  {
   ModelState.AddModelError("Exception", exception);
  }


  return View();

 }

controller factory:

ControllerBuilder.Current.SetControllerFactory(new Models.InMemoryRepositories.InMemoryControllerFactory());

public class InMemoryControllerFactory : IControllerFactory
{

 private readonly Dictionary<string, IController> _controllers = new Dictionary<string, IController>();

 private readonly Dictionary<string, Func<IController>> _controllerFactoryDictionary =
  new Dictionary<string, Func<IController>>();

 public InMemoryControllerFactory()
 {
  InitializeDictionary();
 }

 private void InitializeDictionary()
 {

  AddFactory(typeof(Controllers.HomeController), () => new Controllers.HomeController(
   new Models.InMemoryRepositories.Registration.InMemoryRegistrationRepository()));
  AddFactory(typeof(Controllers.RegistrationController),() => new Controllers.RegistrationController(
      new Models.InMemoryRepositories.Registration.InMemoryRegistrationRepository()));
  AddFactory(typeof(Controllers.AssessmentController),()=> new Controllers.AssessmentController(
   new Models.InMemoryRepositories.Registration.InMemoryDefectRepository(),
   new Models.InMemoryRepositories.Registration.InMemoryAssessmentRepository())
   );
 }

 private void AddFactory(Type type, Func<IController> creator)
 {
 const string Str_Controller = "Controller";
    var fullname = type.Name;
    Debug.Assert(fullname.EndsWith(Str_Controller));
    var controllerName= fullname.Substring(0, fullname.Length - Str_Controller.Length);

  Func<string, Func<IController>> controllerFactoryFunc = (_controllerName) =>
   {
    return () =>
     {
      //var controllerName=ControllerNameFunc(type);
      if (!_controllers.ContainsKey(_controllerName))
       _controllers.Add(_controllerName, creator());
      return _controllers[_controllerName];
     };
   };

  _controllerFactoryDictionary.Add(controllerName, controllerFactoryFunc(controllerName));
 }


 #region IControllerFactory Members



 public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
 {
  return _controllerFactoryDictionary[controllerName]();
 }

 /// <summary>
 /// Code via http://nayyeri.net/custom-controller-factory-in-asp-net-mvc
 /// </summary>
 /// <param name="controller"></param>
 public void ReleaseController(IController controller)
 {

  if (controller is IDisposable)
   (controller as IDisposable).Dispose();
  else
   controller = null;
 }

 #endregion
}

Through the controller with an invalid value at first, then a valid one, but the error message stays and modelstate stays invalid. Why does this happen? i'm using the default model binder, but the included controller factory.

+2  A: 

A Controller should be instantiated per request. Think of the ControllerContext being much like the HttpContext. It represents the state of a single request. Since you're storing controllers in a static dictionary, you're not clearing the state of the controller for each request, thus it holds onto its modelstate.

In general, you should not use the Singleton pattern with controllers because of this. Otherwise you're responsible for clearing its state on each request. You're probably not getting much of a perf benefit anyways by doing that.

Haacked
I imagine that's the problem, I'll try it out as soon as I get to work on tue.
Maslow