我的强类型视图继承自使用Linq to SQL创建的“Person”对象。在我的“编辑”视图中,我必须显示当前的旧值:
<%= 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 :(得分:1)
这里有些奇怪。
Model.FirstName不应为null;模型绑定器足够智能,可以将空输入字段(文本框)设置为“”。确保您的模型与您使用的文本框之间的属性名称匹配。
您使用的是哪个版本的MVC? 1还是2?我在VS 2008中运行MVC 1版本,并且我将FirstName设置为null的唯一方法是不将其包含在表单中。
我可以看到你是否初始GET Edit视图引发了这个错误,并且你的dbml和数据库中的FirstName设置为可为空但由于它是一个帖子,这对我来说现在没有意义。 ;)
<强>更新强>
我已经证实了这一点:
使用空格式:
哦,哦......这会破坏很多代码......
守则:
查看(两者相同):
<% 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”)]它们保持“”。
这是在某处记录的吗?
答案 1 :(得分:1)
尝试自定义模型绑定器。
请参阅:ASP.NET MVC: Best way to trim strings after data entry. Should I create a custom model binder?
答案 2 :(得分:0)
在Models.Person中,默认值为String.Empty,它至少应该消除null错误。
如果要将其自动化,则可以将其添加到dbml文件中。附加了一个designer.cs文件,每个字段都有一个getter和setter。如果您愿意,可以在那里添加代码。
您还可以根据您的表创建一个分部类,并在其中处理修剪。这意味着如果您对dbml文件进行了更改,那么您不会丢失更改。
如果您没有使用dbml文件,请告诉我们。
修改强>
如果你的dbml文件中有一个名为person的类,那么这将被声明为partial。
在同一个项目中创建另一个类,并执行以下操作;
public partial class Person
{
public string NewName
{
get { return this._name.Trim(); }
}
}
所以从那时起你可以使用.NewName而不是名字,它会回来修剪。你也可以在那里添加代码以确保它不是空的,不是红色,不是什么,并返回适当的值。
答案 3 :(得分:-1)
我不知道有这样做的扩展方法,如果其他人这样做,请告诉我。
我为可能为空的字段创建一个简单的HTML帮助器。
public static string TrimOrDefault(string value)
{
return (value == null ? "" : value.Trim());
}
然后在您的代码中,您可以使用
<%= Html.TextBox("FirstName", Helpers.TrimOrDefault(Model.FirstName)) %>
它可以在以后的可空字段中重复使用并轻松读取。