문제

저는 ASP.NET MVC를 처음 사용합니다. 기존 ASP.NET 모델과 오랫동안 작업 한 후에이 모델을 이해하는 데 시간이 걸립니다.

나는 일이 어떻게 작동하는지 이해하기 위해 Nerddinner를 통과하고 있습니다.

그래서 몇 가지 조회수를 통해 전달 해야하는 객체가 있습니다. 기사와 비슷합니다 Nerddinner 6 단계 : ViewData 및 ViewModel.

데이터를 처음으로 게시하는 것부터 처음으로 데이터를 유지 한 다음 TempData에 넣고 다른 행동 (또 다른 행동)으로 전달합니다. 내 데이터를 얻으면 게시물에 데이터를 유지할 수 없습니다.

내 코드는 다음과 같습니다.

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는 설정 후 1 개의 단일 요청에 대해서만 있습니다.

다음은 게시물의 인용문입니다.

TempData를 설정하고 동작을 설정 한 다음 ViewResult를 반환하면 다음 요청이 발생하는 경우 (AJAX 요청, 다른 페이지가 다른 탭에서 열린 다른 페이지 등) 설정 설정된 TempData 값을 볼 수 있습니다. 그리고 다른 요청은 그것을 볼 수 없습니다.

그래서 내가보고있는 코드를 감안할 때, 당신은 Tempdata에서 저녁을 얻을 수 있습니다. AnotherAction 설정 한 후 첫 번째 요청입니다. Action. 그러나 코드를보고 AnotherAction 데이터를 게시물에 전달하는 방법은 확실하지 않습니다. AnotherAction. 저녁 식사 인스턴스는 TempData에서 설정 한 후 두 번째 요청이기 때문에 해당 요청에 대해 TempData에 있지 않을 것입니다. 그리고 당신이 적절한 양식 태그가없는 경우 AntoherAction 프레임 워크보기에는 게시물의 저녁 식사 객체를 인스턴스화하기위한 적절한 양식 값이 없습니다.

따라서 저녁 인스턴스로 TempData를 재설정해야합니다. AnotherAction 전화를 한 다음 게시물에서 Tempdata에서 저녁 식사를 회수합니다. AnotherAction, 또는 DM의 조언을 따르고 당신의 견해에서 숨겨진 필드를 사용할 수 있습니다.

IMO, DMS 방법을 사용하고 TempData를 사용하지 않아야합니다.

다른 ACTACTION에서 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>

<% } %>

다른 Action 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
}

따라서 또 다른 Actions보기에는 다음과 같은 것이 있습니다.

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

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

<% } %>

위의 예에는 사용자 친근감이 없지만 요점을 얻습니다.

뷰에서 컨트롤러로 원시 C# 객체를 전달할 수 없습니다.

ASP.NET MVC에서 작업이 매개 변수에 대한 객체를 사용하는 경우 ASP.NET MVC는 모든 게시물/GET 데이터를보고 매개 변수 객체의 속성 이름과 일치하는 값을 찾습니다.

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

MyDinner 객체는 저녁 식사 객체의 속성 (위치, 날짜 등)에 해당하는 양식 필드로 작업에 게시하거나 해당 정보를 Get URL (Dinners/SomeAction? Location = Chicago & Date에 배치 해야하는 경우에만 채워집니다. = 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 ...);
}

리포지토리에서 작업을 수행 할 수 있으므로 ID 만 전달할 수 있습니다.

편집하다

마법사 스타일 페이지를 만들려면 세션 객체에 이전에 입력 한 데이터를 저장할 수 있습니다.

Session['CurrentDinner'] = dinner;

세션에 저장된 데이터는 요청을 통해 지속됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top