我是新来的ASP.NET 视.工作后,与传统ASP.NET 模型长期以来它把一些时间我得到了解这种模式。

我要通过NerdDinner了解如何工作。

因此,我有一个对象,需要通过几个观点。类似的文章 NerdDinner步骤6:可视数据用和视图模型.

我保留将数据从那以后第一次,然后我把它放在TempData并将其传递给另一行动(AnotherAction).一旦我得到我的数据上获得我不能保留在职位。

这是我的代号:

public class DinnerFormViewModel
{
    public Dinner Dinner { get; private set; }

    public DinnerFormViewModel(Dinner dinner)
    {
        Dinner = dinner;
    }
}

public class DinnersController : Controller
{
    public ActionResult Action()
    {
        Dinner dinner = new Dinner();
        return View(new DinnerFormViewModel(dinner));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Action(Dinner dinner, FormCollection collection)
    {
        try
        {
            // Some code
            TempData["Dinner"] = dinner;
            return RedirectToAction("AnotherAction");
        }
        catch
        {
            return View();
        }
    }

    public ActionResult AnotherAction()
    {
        Dinner dinner = (Dinner)TempData["Dinner"]; // Got my dinner object
        return View(new DinnerFormViewModel(dinner));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult AnotherAction(Dinner dinner, FormCollection collection)
    {
        // Lost my dinner object, dinner comes in as null
    }
}
有帮助吗?

解决方案

根据此博客文章 TempData仅适用于设置后的单个请求。

以下是帖子的引用:

  

如果您设置TempData并且您的操作然后返回ViewResult,那么下一个请求,无论它是什么(AJAX请求,用户在另一个选项卡中打开的另一个页面等),都会看到TempData您设置的值,没有其他请求会看到它。

因此,鉴于我所看到的代码,您可以从 AnotherAction 获取来自TempData的晚餐,这是您在 Action 上设置后的第一个请求。然而,查看代码而没有看到 AnotherAction 的视图代码,目前还不清楚如何将数据传递给 AnotherAction 的帖子。晚餐实例不会在TempData中用于该请求,因为它是您在TempData中设置后的第二个请求。如果您没有在 AntoherAction 视图中设置正确的表单标签,则框架将没有正确的表单值来实例化帖子中的晚餐对象。

所以要么你必须用晚餐实例重置TempData,它是第一个 AnotherAction 调用,然后在post AnotherAction 中检索TempData中的晚餐,或者你可以遵循dm的建议并在视图中使用隐藏字段。

IMO,您应该使用DM方式来避免使用TempData。

编辑添加了在AnotherAction中重置TempData以在帖子中访问它的示例。

型号:

  public class Dinner
  {
    public string Name{get;set;}
  }

  public class DinnerFormViewModel
  {
    public Dinner Dinner {get;private set;}

    public DinnerFormViewModel( Dinner dinner )
    {
      Dinner = dinner;
    }
  }

控制器:

  public class DinnersController : Controller
  {
    public ActionResult Action()
    {
      Dinner dinner = new Dinner();
      return View( new DinnerFormViewModel( dinner ) );
    }

    [AcceptVerbs( HttpVerbs.Post )]
    public ActionResult Action( Dinner dinner, FormCollection collection )
    {
      try
      {
        // Some code
        TempData[ "Dinner" ] = dinner;
        return RedirectToAction( "AnotherAction" );
      }
      catch
      {
        return View();
      }
    }

    public ActionResult AnotherAction()
    {
      Dinner dinner = ( Dinner )TempData[ "Dinner" ]; // Got my dinner object
      TempData[ "Dinner" ] = dinner; // Reset the dinner object in temp data
      return View( new DinnerFormViewModel( dinner ) );
    }

    [AcceptVerbs( HttpVerbs.Post )]
    public ActionResult AnotherAction( Dinner dinnerFromPostedFormValues, FormCollection collection )
    {
      //dinnerFromPostedFormValues is null
      var dinnerFromTempData = TempData[ "Dinner" ] as Dinner; // Got my dinner object

      return View( "Action", new DinnerFormViewModel( dinnerFromTempData ) );
    }
  }

行动观点:

<h2>Action</h2>

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
           Name: <%= Html.TextBox("Name", Model.Dinner.Name ) %>
        </p>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>

<% } %>

AnotherAction View:

<h2>AnotherAction</h2>

<% using (Html.BeginForm()) {%>

  <fieldset>
      <legend>Fields</legend>
      <p>
          Name:
          <%= Html.Encode(Model.Dinner.Name) %>
      </p>

      <p>
          <input type="submit" value="Do Something" />
      </p>
  </fieldset>

<% } %>

其他提示

要获得您期望的格式,您可能需要在从各种视图中收集信息时填充一些隐藏字段。

此外,使用模型绑定可以使代码看起来更好,并避免在地方使用TempData:

public ActionResult Action()
{
    Dinner dinner = new Dinner();
    return View(new DinnerFormViewModel(dinner));
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Action(Dinner dinner)
{
    try
    {
        return RedirectToAction("AnotherAction", dinner);
    }
    catch
    {
        return View();
    }
}

public ActionResult AnotherAction(Dinner dinner)
{
    return View(new DinnerFormViewModel(dinner));

    //In this view is where you may want to populate some hidden fields with the Dinner properties that have already been entered... so when the Post action picks up the dinner object it will be fully populated
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AnotherAction(Dinner dinner)
{
    //work with fully populated Dinner object
}

所以在AnotherAction视图中你会有类似的东西:

<% using(Html.BeginForm()) { %>

    <%= Html.Hidden("dinnerProperty1") %>
    <%= Html.Hidden("dinnerProperty2") %>
    <%= Html.Hidden("dinnerProperty3") %>
    <%= Html.TextBox("dinnerProperty4") %>
    <%= Html.TextBox("dinnerProperty5") %>
    <%= Html.TextBox("dinnerProperty6") %>

<% } %>

上面的示例中没有用户友好性,但您明白了这一点。

你可以不通过原C#对象的意见,以控制器。

在ASP.NET 视,当一个行动的对象为一个参数,ASP.NET 视看起来在所有职位/获得数据,看起来价值观相吻合的财产上的姓名参数的对象。

public ActionResult SomeAction(Dinner myDinner)
{
        // do stuff
}

myDinner目将能填只有如果你的后来的行动的形式领域相对应的晚餐目的性质(地点、日期,等等)。 或如果你是地方的信息,获得网址(晚餐/SomeAction?位置=芝加哥和日期=12/1/2009等)。

如果你绝对不能使用的隐藏的领域(如DM建议),那么会议可能是你唯一的选择。

您应该从存储库中获得晚餐。你的行动应该是:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AnotherAction(int dinnerId, FormCollection collection)
{
    var dinner = dinnerRepository.Get(dinnerId);
    ... do something with dinner ...
    dinnerRepository.Save(dinner);
    return RedirectToAction("AnotherAction", ... pass dinner id ...);
}

GET操作也可以从存储库中获取,因此您只能传递id。

编辑

如果要创建向导样式页面,可以将先前输入的数据存储在Session对象中。

Session['CurrentDinner'] = dinner;

存储在Session中的数据会通过请求持续存在。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top