Привязка модели и отображение свойства обрезанной строки - PullRequest
0 голосов
/ 03 декабря 2009

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

<%= 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» blank , результирующее свойство Person.FirstName станет null , а Model.FirstName.Trim () вызовет исключение (Object ссылка не установлена ​​на экземпляр объекта).

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

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

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

Ответы [ 4 ]

1 голос
/ 18 января 2010
1 голос
/ 03 декабря 2009

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

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

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

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

Обновление:

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

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

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

Э-э-э ... Это сломает много кода ...

Код:

Просмотр (одинаково для обоих):

<% 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; }
}

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

Это где-то задокументировано?

0 голосов
/ 03 декабря 2009

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

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

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

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

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

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

0 голосов
/ 03 декабря 2009

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

Если вы хотите автоматизировать его, вы можете добавить это в свой dbml-файл. К нему прикреплен файл designer.cs, и в каждом поле есть геттер и сеттер. Вы можете добавить код там, если хотите.

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

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

EDIT

Если в вашем dbml-файле есть класс с именем person, тогда он уже будет объявлен как частичный.

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

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

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

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