为什么验证错误仍然存​​在?

时间:2009-12-02 20:07:46

标签: asp.net-mvc validation

用户将注册信息提交到表单:

<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 个答案:

答案 0 :(得分:2)

应根据请求实例化Controller。可以认为ControllerContext与HttpContext非常相似。它表示单个请求的状态。由于您将控制器存储在静态字典中,因此您不会为每个请求清除控制器的状态,因此它会保留在其模型状态中。

通常,您不应该将Singleton模式与控制器一起使用。否则,您有责任在每个请求中清除其状态。通过这样做,你可能无法获得很多好处。