初始化视图模型

时间:2013-04-02 09:31:46

标签: asp.net-mvc asp.net-mvc-3

我将举例说明的所有代码。 我有ViewModel

public class ViewModel
{
    public User SomeUser { get; set; }
    public ViewModel()
    {

    }
    public ViewModel(int id)
    {
        SomeUser = someservice.getUserById(id);
    }
}

我有控制器

    public partial class SomeController
    {
        public ActionResult Edit(int id)
        {
            var model = new ViewModel(id);
            return View("Documents/Edit", model);
        }

        [HttpPost]
        public ActionResult Edit(ViewModelmodel model)
        {
            if (ModelState.IsValid)
            {
                TempData["Save"] = true;
                return RedirectToAction("Edit", new { id = model.Id });
            }
            return View("someview", model);
        }
}

在视图中我有表格并在视图中显示

<b>Model.SomeUser.Name</b>

当我去SomeController / Edit / 3.在viemodel中,someUser属性在构造函数中初始化。但是当我回传我的viewmodel初始化构造函数而没有参数并且如果modelstate无效时,someUser属性为null。所以我得到null引用异常。 处理这种情况的最佳方法是什么?

3 个答案:

答案 0 :(得分:4)

您的ViewModel不应该真正负责呼叫服务,它应该只是您View中显示内容的简单表示。我会保持简单。

public class ViewModel
{
    public User SomeUser { get; set; }
}

因此,您的常规修改操作可以从您的服务初始化 SomeUser 属性。

public ActionResult Edit(int id)
{
    var model = new ViewModel()
    {
        SomeUser = someservice.getUserById(id);
    };
    return View("Documents/Edit", model);
}

现在发帖。提交表单时,id仍应位于查询字符串中,因此您可以在操作参数以及包含表单数据的模型中绑定它。

[HttpPost]
public ActionResult Edit(int id, ViewModel model)
{
    if (ModelState.IsValid)
    {
        TempData["Save"] = true;
        return RedirectToAction("Edit", new { id = id });
    }
    return View("someview", model);
}

现在,我现在确定你的View是什么样的,但是你的ViewModel不包含任何可以提交和绑定的属性。这是一个编辑用户页面,您可能在ViewModel之后表示您正在编辑的内容。

public class ViewModel
{
    public string Username { get; set; }
    public int Age { get; set; }
}

public ActionResult Edit(int id)
{
    var user = someService.getUserById(id)
    var model = new ViewModel()
    {
        Username = user.Username,
        Age = user.Age
    };
    return View("Documents/Edit", model);
}

现在,如果你在表单中使用Html助手......

@Html.TextBoxFor(m => m.Username)
@Html.TextBoxFor(m => m.Age)

...然后您的属性将自动绑定在后期操作中。

[HttpPost]
public ActionResult Edit(int id, ViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = someService.getUserById(id);

        user.Username = model.Username;
        user.Age = model.Age;

        TempData["Save"] = true;
        return RedirectToAction("Edit", new { id = id });
    }
    return View("someview", model);
}

答案 1 :(得分:0)

完全取决于您的要求。

对于问题中的代码,您可以重复使用GET方法:

[HttpPost]
public ActionResult Edit(int id, ViewModelmodel model)
{
  if ( !ModelState.IsValid ) return Edit( id );
  ...

答案 2 :(得分:0)

应该更详细地描述问题。你用什么模式?

1)如果MVC(因为SomeController类和ActionResult)那么:

[HttpPost]
public ActionResult Edit(int id, ViewModel model) {
if (ModelState.IsValid) {
TempData["Save"] = true;
return RedirectToAction("Edit", new { id = id });
}
return View("someview", model);
}

这应该有效。

2)如果是MVVM(因为ViewModel),那么你可以使用可以通过消息帮助你的MVVMlight:

//从您的ModelView发送:

Messenger.Default.Send(“Hello world”);

//在另一个ModelView中添加:

Messenger.Default.Register<string>(this, DoSomething);

//进一步

private void DoSomething(string message) {
// what to do with it...
}

但在这里我遇到了Galasoft的问题...... Win8.dll