Почему ошибки проверки сохраняются? - PullRequest
0 голосов
/ 02 декабря 2009

Пользователь отправляет регистрационную информацию в форму:

<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>

<% } %>

Контроллер:

[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();

    }

контроллер фабрики:

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
}

Сначала через контроллер с недопустимым значением, затем действительным, но сообщение об ошибке остается, а состояние модели остается недействительным. Почему это происходит? Я использую связующее по умолчанию для модели, но прилагаю фабрику контроллеров.

1 Ответ

2 голосов
/ 04 декабря 2009

Контроллер должен создаваться для каждого запроса. Представьте, что ControllerContext очень похож на HttpContext. Он представляет состояние одного запроса. Поскольку вы храните контроллеры в статическом словаре, вы не очищаете состояние контроллера для каждого запроса, поэтому он сохраняется в его состоянии модели.

В общем случае вам не следует использовать шаблон Singleton с контроллерами из-за этого. В противном случае вы несете ответственность за очистку его состояния при каждом запросе. Вы, вероятно, в любом случае не получите большую выгоду от этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...