代码之家  ›  专栏  ›  技术社区  ›  gremo

模型绑定和显示修剪后的字符串属性

  •  0
  • gremo  · 技术社区  · 16 年前

    我的强类型视图继承自使用Linq to SQL创建的“Person”对象。在我的“编辑”视图中,我必须显示旧值:

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

    “firstname”是nchar,所以需要修剪。所以我最终得到了:

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

    这是可行的。但是,当表单提交(发布后)并且出现一些错误时,我需要再次显示:

    [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变为 无效的 model.firstname.trim()引发异常(对象引用未设置为对象的实例)。

    有什么方法可以修改绑定并在默认情况下修剪所有字符串?或者有什么办法来解决这个问题 ?

    更新: 似乎证实是MVC 2的行为。仍然在寻找一个好的方法来处理这个问题。实际使用扩展方法:

    public static string TrimOrDefault(this string value)
    {
        return value != null ? value.Trim() : string.Empty;
    }
    
    4 回复  |  直到 16 年前
        1
  •  1
  •   John Farrell    16 年前

    这里有点奇怪。

    model.firstname不应为空;模型绑定器足够智能,可以将空输入字段(textbox)设置为“”。确保您的属性名称在模型和使用的文本框之间匹配。

    您使用的是哪种版本的MVC?1还是2?我在VS 2008中运行MVC 1版本,唯一能使firstname为空的方法是完全不将其包含在表单中。

    我可以看到,如果您的初始get edit视图抛出了这个错误,并且在您的DBML和数据库中将firstname设置为nullable,但是由于它是一个post,所以我现在不理解它。;)

    更新:

    我已经确认:

    使用空表单:

    • 与2008年相比-MVC 1-firstname=“”
    • vs 2010-MVC 2-名字=空

    哦…这会破坏很多代码…

    代码:

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

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

    没有干净的自动取款机。模型绑定器实际上正在将这些属性设置为空。在构造函数中将First和Last设置为“”,并从绑定中排除这些属性:[bind(exclude=“firstname,lastname”)]它们保持为“”。

    这里有文件记录吗?

        3
  •  0
  •   griegs    16 年前

    在models.person中,默认值为string.empty,这至少会消除空错误。

    如果您想让它自动化,那么您可以将其添加到DBML文件中。附加了一个designer.cs文件,每个字段都有一个getter和setter。如果愿意,可以在其中添加代码。

    还可以基于表创建分部类,并在其中处理修剪。这意味着,如果您更改了DBML文件,那么您不会丢失所做的更改。

    如果您不使用DBML文件,请通知我们。

    编辑

    如果在DBML文件中有一个名为Person的类,那么这个类已经声明为分部。

    在同一个项目中创建另一个类,并执行如下操作:

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

    从那时起,你可以用.newname代替name,它会被修剪掉。您还可以在其中添加代码,以确保它不为空、不为红色、不为任何内容,并返回适当的值。

        4
  •  -1
  •   Odd    16 年前

    我不知道有什么扩展方法可以做到这一点,如果有人做到了,请告诉我。

    我为可能为空的字段创建了一个简单的HTML助手。

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

    然后在代码中可以使用

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

    它可用于将来可以为空的字段,并且易于读取。