2009-12-03 4 views
0

Мое строго типизированное представление наследуется от объекта «Личность», созданного с помощью Linq to SQL. В моей «Edit» View, я должен показать, конечно, старые значения:Модель привязки и отображения обрезанного строкового свойства

<%= Html.TextBox("FirstName") %> 

«FirstName» является NCHAR, поэтому должны быть обрезаны. Так я закончил с:

<%= Html.TextBox("FirstName", Model.FirstName.Trim()) %> 

и это работает. Но когда форма отправлена ​​(после POST) и происходят какие-то ошибки, мне нужно, чтобы показать его еще раз:

[AcceptVerbsAttribute(HttpVerbs.Post), Authorize(Roles = "office"), HandleError] 
public ActionResult Edit(Models.Person person) 
{ 
    if (!(_personService.ValidatePerson(person))) // Persona non valida 
    { return View(person); } 
} 

Если по каким-то причинам пользователь оставил текстовое поле «FirstName» пустым, в результате Person.FirstName собственности null и Model.FirstName.Trim() выдает исключение (ссылка на объект не установлена ​​в экземпляр объекта).

Любой способ изменить привязку и все строки обрезаны по умолчанию? Или любые идеи, как исправить это?

Обновление: кажется подтвержденным как поведение MVC 2. все еще ищет хороший способ справиться с этим. На самом деле, используя метод расширения:

public static string TrimOrDefault(this string value) 
{ 
    return value != null ? value.Trim() : string.Empty; 
} 
+0

@gremo проверить мой выбор для частичного примера класса. – griegs

ответ

1

Здесь что-то странно.

Model.FirstName не должно быть null; модель связующего достаточно умна, чтобы установить пустое поле ввода (текстовое поле) на "". Убедитесь, что ваши имена свойств совпадают между вашей моделью и используемыми вами текстовыми полями.

Какую версию MVC вы используете? 1 или 2? Я запускаю версию MVC 1 в VS 2008, и единственный способ, которым я могу получить значение FirstName равным null, - это не включать его в форму вообще.

Я мог видеть, было ли вы, начальное представление GET Edit, выбросить эту ошибку, и у вас было задано значение FirstName в вашем dbml и базе данных, но поскольку это сообщение, это не имеет смысла для меня прямо сейчас. ;)

Update:

Я подтвердил это:

С пустой формы:

  • VS 2008 - Mvc 1 - FirstName = ""
  • VS 2010 - Mvc 2 - FirstName = null

Uh oh ... То сломает много кода ...

Код:

View (то же самое для обоих):

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

    <fieldset> 
     <legend>Fields</legend> 
     <p> 
      <label for="FirstName">FirstName:</label> 
      <%= Html.TextBox("FirstName", Model.FirstName) %> 
      <%= Html.ValidationMessage("FirstName", "*") %> 
     </p> 
     <p> 
      <label for="LastName">LastName:</label> 
      <%= Html.TextBox("LastName", Model.LastName) %> 
      <%= Html.ValidationMessage("LastName", "*") %> 
     </p> 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 

<% } %> 

VS 2010 - Mvc 2

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     ViewData["Message"] = "Welcome to ASP.NET MVC!"; 

     return View(); 
    } 

    public ActionResult About() 
    { 
     return View(); 
    } 

    public ActionResult AddPerson() 
    { 
     var person = new Person(); 

     return View(person); 
    } 

    [HttpPost] 
    public ActionResult AddPerson(Person person) 
    { 
     return View(person); 
    } 
} 

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

VS 2008 - Mvc 1

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     ViewData["Message"] = "Welcome to ASP.NET MVC!"; 

     return View(); 
    } 

    public ActionResult About() 
    { 
     return View(); 
    } 


    public ActionResult AddPerson() 
    { 
     var person = new Person(); 

     return View(person); 
    } 

    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult AddPerson(Person person) 
    { 

     return View(person); 
    } 
} 

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

Нет чистых исправлений. Связывание модели фактически устанавливает эти свойства равными нулю. Установите «Первый» и «Последний» в «» в конструкторе и исключите эти свойства из привязки: [Bind (Exclude = «FirstName, LastName»)] они остаются «».

Является ли это документированным где-то?

+0

Я думаю об этой идее. Вы отлаживали объект человека, поскольку он передается в метод «Редактировать» (т. Е. До того, как он попадает в службу проверки), чтобы увидеть, является ли первое имя пустым или пустым на этом этапе? Является ли объект человека изменен в службе проверки и установлен на него там? Вы добавляете ошибки проверки в состояние модели с помощью Model.ModelState.AddModelError? Если это так, вы также используете Model.ModelState.SetModelValue (они работают как пара и пренебрегают SetModelValue триггерами странных нулевых ошибок). –

+0

Debuggin показывает, что свойство person, например. «LastName» имеет значение null после отправки (если я установил его в соответствующем текстовом поле), сразу после первой строки кода. Имена совпадают. Версия 2 vs 2010 beta 1. LastName i nchar (30) not null ... Спасибо – gremo

+0

вот про null vs string.Empty: http://stackoverflow.com/questions/1263563/modelbinding-for-empty -QUERY-строка-параметры-в-Asp-нетто-2-MVC –

0

В Models.Person имеет значение по умолчанию будет String.Empty, который должен elminate нулевой ошибки по крайней мере.

Если вы хотите автоматизировать его, вы можете добавить его в свой файл dbml. Имеется файл designer.cs, и в каждом поле есть геттер и сеттер. вы можете добавить код там, если хотите.

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

Если вы не используете файл dbml, дайте нам знать.

EDIT

Если у вас есть класс с именем лица в файле DBML, то это уже будет объявлена ​​частичная.

создать другой класс в том же проекте и сделать что-то вроде следующего;

public partial class Person 
{ 
    public string NewName 
    { 
     get { return this._name.Trim(); } 
    } 
} 

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

+0

Кажется, все в порядке, но мне нужно знать, как создать частичный класс. Я действительно новичок в MVC и asp.net в целом ... может ли кто-нибудь указать мне правильное направление на то, как редактировать файл dbml или создавать частичный класс? – gremo

+0

Создается файл designer.cs. Изменив его, а затем изменив свой dbml, все ваши изменения исчезнут. – jfar

+0

да, я сказал это! поэтому я добавил бит о частичном классе. – griegs

-1

Мне не известно о методе расширения, который делает это, если кто-то еще это делает, пожалуйста, дайте мне знать.

Я создаю простой HTML-помощник для полей, которые МОГУТ быть нулевыми.

public static string TrimOrDefault(string value) 
{ 
    return (value == null ? "" : value.Trim()); 
} 

И тогда в вашем коде вы можете использовать

<%= Html.TextBox("FirstName", Helpers.TrimOrDefault(Model.FirstName)) %> 

Это многоразовые для будущих обнуляемого полей и легко читается.

+1

Вниз избирателя. Надеюсь, у вас есть решение, поэтому ваш downvote? Это действительно приемлемое решение. – griegs

+0

«Любой способ изменить привязку и все строки обрезаны по умолчанию?» Ваш ответ не имеет ничего общего с привязкой к модели, только для вывода HTML. Вы дали ему пример кода, который он уже использует, используя метод extention вместо Trim() на этот раз: <% = Html.TextBox («FirstName», Model.FirstName.Trim())%> – jfar

+0

«Или любые идеи о том, как почини это?" Помощник был простым решением для обработки поля с нулевым значением. – Odd

 Смежные вопросы

  • Нет связанных вопросов^_^