0

我有两页:

  • 创建使用数据注释验证的页面。
  • 编辑页面。

两个页面使用不同的模型。我必须为编辑页面使用特定模型才能显示所选行的值。我如何能:

  1. 让编辑控制器使用相同的验证,或者
  2. 如果我使用与创建页面相同的模型,获取编辑页面以显示当前行的值?

例如:

我的创建页面:

@model Test.Models.NewPerson
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true, "Failed. Please fix the errors.")

        <div class="editor-label">
            @Html.LabelFor(m => m.FirstName)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(m => m.FirstName)
            @Html.ValidationMessageFor(m => m.FirstName)
        </div>
        <div class="editor-label">
            @Html.LabelFor(m => m.LastName)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(m => m.LastName)
            @Html.ValidationMessageFor(m => m.LastName)
        </div>
    <input type="submit" value="Submit" />
}

我的模型:

public class NewPerson 
{
    [Required(ErrorMessage = "*")]
    [Display(Name = "First name")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "*")]
    [Display(Name = "Last name")]
    public string LastName { get; set; }
}

然后是我的编辑页面:

@model Test.Person

using (Html.BeginForm())
{
    @Html.ValidationSummary(true, "Please fix the errors below.")

        <div class="editor-label">
            @Html.LabelFor(m => m.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(m => m.FirstName)
            @Html.ValidationMessageFor(m => m.FirstName)
        </div>
        <div class="editor-label">
            @Html.LabelFor(m => m.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(m => m.LastName)
            @Html.ValidationMessageFor(m => m.LastName)
        </div>
    <input type="submit" value="Update" />
}

编辑

在我的控制器中,编辑操作,我有:

var context = new MyContext();          
var person = context.Person.Single(m => m.ID == id);

if (Request.IsAjaxRequest())
{
    return PartialView("Edit", person);
}
return View(person);

当我在该函数中放置断点时,我看到了 var person 的结果。但是,它在视图中不返回任何内容。为什么不?

编辑

这是我的操作代码:

[HttpPost]

public ActionResult Create(NewPerson model)
{
if (ModelState.IsValid)
{
    string UID = Membership.GetUser().ProviderUserKey.ToString();
    System.Guid myUID = System.Guid.Parse(UID);

    using (var context = new MyContext())
    {   
       Person newPerson = new Person();
       newPerson.UserId = myUID;
       newPerson.FirstName = model.FirstName;
       newPerson.LastName = model.LastName;
       context.Person.AddObject(newPerson);
       context.SaveChanges();
    }
    }

和编辑动作:

[HttpGet]

    public ActionResult Edit(int id)
    {
        var context = new MyContext();

        //recently edited: accidentally had "camper" instead of "person"
        var person = context.Person.Single(m => m.ID == id);

        if (Request.IsAjaxRequest())
        {
            return PartialView("Edit", person);
        }
        return View(person);

    }

我的观点:

@foreach (var person in Model)
{
@Html.DisplayFor(modelItem => person.LastName), @Html.DisplayFor(modelItem => person.FirstName)

@Html.ActionLink("Edit", "Edit", new { id = person.ID }, new { @class = "openDialog", 
    data_dialog_id = "emailDialog", data_dialog_title = "Edit Person" })
}
4

2 回答 2

0

It's a little confusing here as to what you have and haven't done, and what does and doesn't work. However there are a few things that you should fix.

First, you should not be passing the Person object that comes from your database directly to the view. Instead, you should have your own specific Person ViewModel. This ViewModel should have your data annotations for your view on it. When you get the Person from the database, you project them into your ViewModel like this:

var camper = context.Person
    .Select(m => new ViewModel.Person
         { Firstname = m.Firstname, Lastname = m.Lastname}).Single(m => m.ID == id);

This prevents your Data model's Person from being bloated by View requirements (for instance, your data model might allow nulls, but you want to set your View to be Required.)

Second, you're not using a using statement in the edit view. Something like this:

using (var camper = ..) {
    ...
}

Using a ViewModel helps here as well, since this allows the context to be destroyed without conflicting with the entities which are change tracked.

Third, you should probably use DisplayTemplates a little better. Rather than having the foreach statement in your view, do this:

@Html.DisplayForModel()

Then create a folder called DisplayTemplates in Views\Shared (or in the folder your view is in) and create a new .cshtml file called Person.cshtml, in that have this code:

@model Person
@Html.DisplayFor(m => m.LastName), @Html.DisplayFor(m => m.FirstName)

@Html.ActionLink("Edit", "Edit", new { id = person.ID }, new { @class = "openDialog", 
    data_dialog_id = "emailDialog", data_dialog_title = "Edit Person" })

I also notice some discrepancies in your namespaces. In one place you have Test.Person, in another you have Test.Models.NewPerson. Is it possible that you also have a Test.Models.Person and you're getting confused about which is which, so you end up populating the wrong one?

于 2012-09-19T17:48:06.540 回答
0

两个视图可以使用相同的模型。这是创建/编辑函数的常见做法,将解决问题 1,具有相同的验证规则。

要在编辑视图的输入字段中显示现有数据,您需要在控制器中检索该数据并将其传递给视图(即填充模型)。

据推测,在 Edit 上,您将拥有某种 ID。使用它从数据源中获取正确的记录,然后在模型中设置 FirstName 和 LastName 值。然后,当您渲染视图时(当然是在传入模型之后),您将在文本框中看到现有值。

于 2012-09-19T16:04:51.503 回答