Я столкнулся со странной проблемой ... когда я использую UpdateModel() или TryUpdateModel(), все работает нормально. Когда я пытаюсь связать себя (например, MyObject.FirstName = collection["FirstName"]), я получаю ошибку "Object reference not set to an instance of an object".

Это немного сложно объяснить, поэтому я представлю код:

    [HandleError]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(FormCollection collection)
    {
        try
        {
            Model.Event evnt = new Redline.RedlineTimeAttack.Model.Event();

            //When this is uncommented everything works fine.
            //TryUpdateModel<Model.Event>(evnt);

            //this will eventually lead to problems
            evnt.Description = collection["Description"];
            evnt.EndDate = enddate;
            evnt.EventName = collection["EventName"];
            evnt.IsActive = collection["IsActive"].Contains("true");
            evnt.StartDate = startdate;
            evnt.TrackId = trackId;
            evnt.WebContent = collection["WebContent"];


            if (!evnt.IsValid)
            {
              foreach (var error in evnt.GetRuleViolations())
              {
                ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
              } 
            }

            //If there are no validation issues then no problem, redirecttoaction
            //works properly
            if (ModelState.IsValid)
            {
                model.Events.InsertOnSubmit(evnt);
                model.SubmitChanges();
                ViewData["ControlMode"] = "Edit";
                return RedirectToAction("Edit");
            }
            else //returning to View so that user can correct issues causes a null reference error in the view (bombs at first Html.Textbox("ControlName"))
            {
                ViewData["Tracks"] = GetTracks();
                return View("Create", evnt);
            }
        }

Вот трассировка стека:

System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Source="System.Web.Mvc"
StackTrace:
   at System.Web.Mvc.HtmlHelper.GetModelStateValue(String key, Type destinationType)
   at System.Web.Mvc.Html.InputExtensions.InputHelper(HtmlHelper htmlHelper, InputType inputType, String name, Object value, Boolean useViewData, Boolean isChecked, Boolean setId, Boolean isExplicitValue, IDictionary`2 htmlAttributes)
   at System.Web.Mvc.Html.InputExtensions.TextBox(HtmlHelper htmlHelper, String name, Object value, IDictionary`2 htmlAttributes)
   at System.Web.Mvc.Html.InputExtensions.TextBox(HtmlHelper htmlHelper, String name)
   at ASP.views_event_create_aspx.__RenderContent2(HtmlTextWriter __w, Control parameterContainer) in d:\TFSProjects\Redline Time Attack\Main\Source\Redline.RedlineTimeAttack.Web\Views\Event\Create.aspx:line 18
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.Control.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
   at ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in d:\TFSProjects\Redline Time Attack\Main\Source\Redline.RedlineTimeAttack.Web\Views\Shared\Site.Master:line 29
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.Control.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.Page.Render(HtmlTextWriter writer)
   at System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
InnerException: 
13
Giovanni Galbo 15 Мар 2009 в 07:01

2 ответа

Лучший ответ

Я нашел здесь некоторую информацию: http://forums.asp.net/p/1396019/ 3006051.aspx

Если вы не хотите использовать встроенную привязку модели, а затем использовать Bultin Validation (SanjaySutar хочет использовать), для каждого добавляемого ModelError вам нужно будет добавить ModelValue: ModelState.AddModelError ("Name", "Bad Name" );

ModelState.SetModelValue ("Имя", ValueProvider ["Имя"]);

Итак, я обновил свой код так:

ModelState.SetModelValue("Description", new ValueProviderResult(ValueProvider["Description"].AttemptedValue, collection["Description"], System.Globalization.CultureInfo.CurrentCulture));
ModelState.SetModelValue("EventName", new ValueProviderResult(ValueProvider["EventName"].AttemptedValue, collection["EventName"], System.Globalization.CultureInfo.CurrentCulture));
ModelState.SetModelValue("EndDate", new ValueProviderResult(ValueProvider["EndDate"].AttemptedValue, collection["EndDate"], System.Globalization.CultureInfo.CurrentCulture));
ModelState.SetModelValue("StartDate", new ValueProviderResult(ValueProvider["StartDate"].AttemptedValue, collection["StartDate"], System.Globalization.CultureInfo.CurrentCulture));
ModelState.SetModelValue("TrackId", new ValueProviderResult(ValueProvider["TrackId"].AttemptedValue, collection["TrackId"], System.Globalization.CultureInfo.CurrentCulture));
ModelState.SetModelValue("WebContent", new ValueProviderResult(ValueProvider["WebContent"].AttemptedValue, collection["WebContent"], System.Globalization.CultureInfo.CurrentCulture));

Причина, по которой я это делаю, заключается в том, что я хотел. выполнить всю (или в максимально возможной степени) проверку в моем бизнес-объекте, включая обязательные поля, и b. Мне нужны мои собственные сообщения в сводке проверки (например, «Поле X является обязательным полем.» Вместо «Требуется значение»). Если есть лучший способ сделать это, см. Другой мой вопрос: ASP.NET MVC - настраиваемое сообщение проверки для типов значений

22
Community 23 Май 2017 в 13:29
Я столкнулся с этим в форме, где я объединял два поля вместе и проверял результат, но хотел сообщить об ошибках в отдельных (исходных) полях ... Спасибо - избавил меня от синяка на лбу!
 – 
GalacticCowboy
27 Апр 2009 в 19:21
4
Вот почему я люблю stackoverflow, я могу погуглить свои исключения и найти решение здесь :) Спасибо.
 – 
Zhaph - Ben Duguid
9 Сен 2009 в 04:36

Откуда берутся enddate, startdate и trackId? Это даже не должно компилироваться, но, может быть, я просто тупой и не вижу их деклараций. Я уверен, что это просто где-то вне поля зрения, правда?

Убедитесь, что во всех этих значениях формы действительно есть что-то в себе.

0
Samantha Branham 15 Мар 2009 в 08:24
Замедления не учитывались (ошибка копирования и вставки). Отсутствующие значения формы должны быть пойманы в GetRuleViolations ()
 – 
Giovanni Galbo
15 Мар 2009 в 08:39
В основном я думал о evnt.IsActive = collection ["IsActive"]. Contains ("true"); линия. Если collection ["IsActive"] имеет значение null, вы получите эту ошибку из-за попытки вызвать функцию для нулевого объекта. Тем не менее, рад видеть, что вы добились прогресса! :)
 – 
Samantha Branham
15 Мар 2009 в 10:32