2011-09-15 2 views
0

알다시피, 그것은 곡식에 맞선 것입니다. 모든 사람들이 MVC 패턴에 대해 강의하기 전에 이것은 극단적 인 측정입니다. ViewState가 필요한 MVC에서 작동하도록 가져와야하는 ASP.NET 컨트롤이 있으며이를 유지하는 데 초점을 맞춰 주셔야합니다. 나는 load a classic ASP.NET pages in MVC by a trick of routes을 사용할 수 있다는 것을 알고 있지만 MVC 프레임 워크 내에서 적합한 통합 솔루션이 필요합니다.MVC ViewUserControl에서 ViewState 지원

ViewState 게임이나 필터 또는 속성과 함께 재생하거나 ViewState 객체를 조롱하여 요청을 구문 분석하고 파이프 라인의 초기에 무언가를 재정 의하여 LoadViewState를 호출하도록 ViewUserControl을 확장하는 방법이 있어야합니다 .

아아, 나는 고전적인 ASP.NET에 대해 충분한 지식이 없기 때문에이 작업을 수행하는 방법을 알고 있습니다. ViewUserControl에는 SaveViewState 및 LoadViewState 메서드와 함께 UserControl 개체에서 파생 된 ViewState 속성이 있으므로 여기에 몇 가지 희망이 있습니다.

<%@ Control Language="C#" CodeBehind="RadGridExample.ascx.cs" Inherits="MvcApplication5.Views.Shared.RadGridExample" %> 
<form runat="server"> 

    <telerik:RadScriptManager ID="scriptmanager2" runat="server"></telerik:RadScriptManager> 

    <telerik:RadGrid runat="server" ID="RadGrid1" AutoGenerateColumns="false" AllowMultiRowSelection="true" ShowGroupPanel="true"> 
     <MasterTableView TableLayout="Fixed" > 
      <Columns> 
       <telerik:GridBoundColumn DataField="Name" HeaderText="Name" DataType="System.String" /> 
       <telerik:GridBoundColumn DataField="Age" HeaderText="Age" DataType="System.String" /> 
      </Columns> 
     </MasterTableView> 
     <ClientSettings AllowDragToGroup="true" > 
     </ClientSettings> 
    </telerik:RadGrid> 

</form> 

다음은 부분보기위한 뒤에 코드 : 여기

는 내가 지금까지 무엇을 가지고

namespace MvcApplication5.Views.Shared 
{ 
    public class RadGridExample : ViewUserControl 
    { 
     protected void Page_Init() 
     { 
      HomeIndexViewModel viewModel = this.Model as HomeIndexViewModel; 

      RadGrid grid = this.Controls[0].FindControl("RadGrid1") as RadGrid; 

      grid.DataSource = viewModel.Animals; 

      grid.DataBind(); 
     } 

     protected override void LoadViewState(object savedState) 
     { 
      base.LoadViewState(savedState); 
     } 

     protected override object SaveViewState() 
     { 
      return base.SaveViewState(); 
     } 
    } 
} 

재미 일의 SaveViewState가 호출되는,하지만 LoadViewState은하지 않았다.

+0

그래서 나는 당신이 MVC 프로젝트에서 웹 폼 페이지를 가질 수 있기 때문에, 당신은 웹 양식을 되돌릴 수 없다는 것을 가정 이 하나의 컨트롤에 대한 접근? 또한 ASP.NET 사용자 지정 컨트롤이므로 사용자 또는 타사 공급 업체입니까? –

+0

안녕하세요 @ 브라이언, 네. 이 컨트롤에 대해 고전 asp.net 모드를 사용합니다 (http://weblogs.asp.net/rajbk/archive/2010/05/11/running-asp-net-webforms-and-asp-net-mvc). -side-by-side.aspx)가 나의 최후의 수단이다. 문제는 보안 속성과 모델 슬링이있는 광범위한 MVC 응용 프로그램의 일부입니다. 보안을 강화하고 모델을 전달할 때까지 asp.net 페이지를 가져 오기 위해 많은 개조 작업이 필요했습니다. MVC를 확장 할 수있는만큼, 채워진 Request에서 ViewState를 해킹하는 것을 거부하고 MVC를 함께 사용하는 것은 불가능합니다. – Levitikon

+0

그리고 30 개 파티 컨트롤 인 Telerik의 RadGrid입니다. 소스 코드에 액세스 할 수 있고 Control의 LoadViewState가 호출되지 않는다는 간단한 실현으로 되돌아가는 길을 따라갔습니다. – Levitikon

답변

0

여기에 들어오는 모든 사람들은 희망을 버리지 마십시오. 나는 그다지 예쁘지는 않지만 이것에 대한 해결책을 찾을 수 있었다. 객체의 트리에 약간의 반사 및 하드 코딩 된 매핑을 사용합니다. 다행히도 MVC에서 ViewState가 필요한 모든 사람들에게 좋은 시작점이 될 것입니다.

부분보기 : 뒤에

<%@ Control Language="C#" CodeBehind="RadGridExample.ascx.cs" Inherits="MvcApplication5.Views.Shared.RadGridExample" %> 
<form runat="server"> 

    <telerik:RadScriptManager ID="scriptmanager2" runat="server"></telerik:RadScriptManager> 

    <telerik:RadGrid runat="server" ID="RadGrid1" AutoGenerateColumns="false" AllowMultiRowSelection="true" ShowGroupPanel="true" AllowFilteringByColumn="True" > 
     <MasterTableView TableLayout="Fixed" > 
      <Columns> 
       <telerik:GridBoundColumn DataField="Name" HeaderText="Name" DataType="System.String" /> 
       <telerik:GridBoundColumn DataField="Age" HeaderText="Age" DataType="System.String" /> 
      </Columns> 
     </MasterTableView> 
     <ClientSettings AllowDragToGroup="true" AllowGroupExpandCollapse="false" > 
     </ClientSettings> 
    </telerik:RadGrid> 

</form> 

코드 :

using System.Reflection; 
using System.Web.Mvc; 
using System.Web.UI; 
using MvcApplication5.Models.ViewModels; 
using Telerik.Web.UI; 

namespace MvcApplication5.Views.Shared 
{ 
    public class RadGridExample : ViewUserControl 
    { 
     protected void Page_Init() 
     { 
      RadGrid grid = this.Controls[0].FindControl("RadGrid1") as RadGrid; 

      grid.NeedDataSource += new GridNeedDataSourceEventHandler(grid_NeedDataSource); 

      grid.DataBind(); 

      string viewState = Request.Form["__VIEWSTATE"]; 

      if (!string.IsNullOrEmpty(viewState)) 
      { 
       LosFormatter formatter = new LosFormatter(); 

       object savedStateObject = formatter.Deserialize(viewState); 

       MethodInfo method = grid.GetType().GetMethod("LoadViewState", BindingFlags.NonPublic | BindingFlags.Instance); 

       // TODO: Find a less brittle/more elegant way to isolate the appropiate viewstate object for this control 
       // In the case of Telerik's RadGrid, the key wasy find the tree that had an array of 13 objects 
       method.Invoke(grid, new object[] { (((((((((savedStateObject as Pair).First as Pair).Second as Pair).Second as System.Collections.ArrayList)[1] as Pair).Second as System.Collections.ArrayList)[1] as Pair).Second as System.Collections.ArrayList)[1] as Pair).First }); 
      } 

      string eventArgument = Request.Form["__EVENTARGUMENT"]; 

      if (!string.IsNullOrEmpty(eventArgument)) 
      { 
       grid.RaisePostBackEvent(eventArgument); 
      } 
     } 

     void grid_NeedDataSource(object sender, GridNeedDataSourceEventArgs e) 
     { 
      (sender as RadGrid).DataSource = this.Model as HomeIndexViewModel; 
     } 
    } 
} 
0

당신은 둥근 구멍에 사각형 말뚝을 맞추려고되지만 ....

가의 ViewState가 전체 작성된 페이지 (콘텐츠 마스터 + 컨트롤 +)를 작동시킬 당신이 모든 <form runat="server"> 포장이 있어야합니다 ViewState가 필요한 요소 WebForms에서는 페이지 중 하나만 가질 수 있습니다. 양식 요소가있는 동일한 페이지에 컨트롤이 있어야합니다. RenderPartial 등을 사용하여 호출되는 무언가에 넣으면 아마도 작동하지 않을 것입니다. 적절한 위치에 있으면 뷰 상태를 지속 /로드하기 위해 추가 페이지 이벤트가 호출되도록해야 할 수도 있습니다. 그리고 일단 컨트롤의 서버 측 클릭 이벤트가 올바르게 작동하는지 확인하는 것이 훨씬 어려울 수 있습니다.

나는 듣고 싶지 않지만 결국 WebForms 페이지를 사용하거나 Mvc 용으로 설계된 구성 요소를 사용하여 다시 작성하는 것이 좋습니다.

+0

롤, 둥근 구멍에 코끼리를 끼워 넣는 것보다 낫습니다. 이것은 고통 스럽다! 정보 btw 주셔서 감사합니다. runat 서버의 폼에서 ViewState 숨김 매개 변수를 사용하여 컨트롤을 렌더링하는 것으로 보았습니다. stinker는 PostState가 MVC 라이프 사이클 동안로드되지 않으므로 포스트 백에서 발생합니다 (우스꽝스러워서 MVC에서 포스트 백을 사용함). ViewState의 지속성을 어떻게 불러내시겠습니까? – Levitikon

0

Telerik은 MVC 프레임 워크에서 RadControl을 지원합니다. 나는 그들 중 몇 가지를 사용했다. 블로그 게시물은 여기에서 찾으실 수 있습니다 : http://blogs.telerik.com/aspnetmvcteam/posts/08-11-06/asp_net_ajax_controls_in_asp_net_mvc.aspx

오픈 소스 인 MVC 프레임 워크를 공개 한 이래 최근에 해본 적이 없습니다. 그러나 MVC에서 컨트롤을 사용하기 위해 도우미 확장 집합을 릴리스했습니다.이 확장은 어딘가에서 사용할 수 있어야합니다.

이렇게해서는 안됩니다. MVC의 ASP.NET AJAX 컨트롤을 사용하는 샘플 데모도 있습니다. 여기에서 사용할 수 있습니다. http://www.telerikwatch.com/2009/01/telerik-mvc-demo-app-now-available.html

HTH.

관련 문제