문제

나는 이것에 대해 많은 질문을 보았지만, 내가 필요로하는 답을 얻지 못했습니다.

상당히 큰 웹 응용 프로그램을 웹 양식에서 MVC로 변환하고 잠시 후에는 데이터를 뷰로 전달하는 데 문제가 발생했습니다. 조치에서 나는 코드를 실행한다.

//This is just an example ViewData["QProducts"] = from p in db.Products select new{Name = p.Name, Date = p.ToShortDateString() } ViewData["QUsers"] = from u in db.Users select u;

html의 객체를 반복하기 위해 Foreach 루프를 사용합니다.

foreach(var q in (IEnumerable)ViewData["QEvents"])
{ 
    /*Print the data here*/
}

MVC를 사용하기 전에 방금 사용했습니다 asp:Repeater, 그러나 이것은 MVC이므로 ASP.NET 컨트롤을 사용할 수 없습니다.

이 데이터를 어떻게보기에 전달해야합니까? 여기서 익명 유형을 사용하지 않는 옵션이 없습니다. <%#ViewData.Eval()%> 분명히 작동하지 않습니다.

어떤 아이디어?

도움이 되었습니까?

해결책

익명 유형이 아닌 이름과 날짜를 보유 할 유형을 만듭니다.

public class NameDate
{
  public string Name { get; set; }
  public DateTime Date { get; set; }
}

그런 다음 LINQ 쿼리에서 사용하십시오.

from p in db.Products select new NameDate { Name = p.Name, Date = p.Date }

견해를 강력하게 입력하십시오 MyView<IEnumerable<NameDate>> 그리고 그냥 a foreach ( var nameDate in ViewData.Model )...

다른 팁

조금 게으른 느낌이 들면 여기 에서이 코드를 사용할 수 있습니다 ... 조금 길지만 기본적으로 반사 래퍼입니다 ...

var something = { Name = "Jim", Age = 25 };
AnonymousType type = AnonymousType.Create(something);

//then used...
string name = type.Get<string>("Name");
int age = type.Get<int>("Age", -1 /* optional default value */);

그리고 여기 코드가 있습니다 ...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Code {

    /// <summary>
    /// A convenient method of accessing the values of an 
    /// anonymous type without needing to define a separate class
    /// </summary>
    public class AnonymousType {

        #region Constants

        private const string EXCEPTION_MISSING_PARAMETER_INFORMATION = 
            "Unable to match the parameter '{0}' to a property in the AnonymousType. This could be due to a casting problem or a Property that does not exist.";
        private const string EXCEPTION_COULD_NOT_ACCESS_FIELD =
            "Unable to find a field named '{0}' (of type {1})";
        private const string EXCEPTION_COULD_NOT_ACCESS_FIELD_AT_INDEX =
            "Unable to find a field named '{0}' at the requested index (of type {1})";

        #endregion

        #region Constructors

        /// <summary>
        /// Creates a new AutoType for methods that return Anonymus types
        /// </summary>
        public AnonymousType(object type) {
            this._Init(type, false);
        }

        /// <summary>
        /// Creates a new AutoType for methods that return Anonymus types and
        /// detetrmins if exceptions should be thrown if a type is missing
        /// </summary>
        public AnonymousType(object type, bool supressErrors) {
            this._Init(type, supressErrors);
        }

        /// <summary>
        /// Initalizes the data for the is type
        /// </summary>
        private void _Init(object type, bool supressErrors) {
            this.SupressExceptions = supressErrors;
            this.m_Type = type.GetType();
            this.m_TypeData = type; 
        }

        #endregion

        #region Static Routines

        /// <summary>
        /// Creates a new Anonymous Type from the provided object data
        /// </summary>
        public static AnonymousType Create(object data) {
            return new AnonymousType(data);
        }

        /// <summary>
        /// Creates a new Anonymous Type from the provided object data
        /// </summary>
        public static AnonymousType Create(object data, bool supressErrors) {
            return new AnonymousType(data, supressErrors);
        }

        #endregion

        #region Private Members

        /// <summary>
        /// The type that will be accessed via reflection
        /// </summary>
        private Type m_Type;

        /// <summary>
        /// The actual typs that is being used
        /// </summary>
        private object m_TypeData;

        #endregion

        #region Properties

        /// <summary>
        /// Determines if errors should be thrown if any casting errors take place
        /// </summary>
        public bool SupressExceptions { get; set; }


        /// <summary>
        /// Accessess a property by name and returns an object
        /// </summary>
        public object this[string property] {
            get {
                return this.Get<object>(property);
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Checks if this Anonymous Type has the specified property
        /// </summary>
        public bool Has(string property) {
            return ((m_Type.GetProperty(property) as PropertyInfo) != null);
        }

        /// <summary>
        /// Returns if this Anonymous type has the specified property and that
        /// the value matches the type specified
        /// </summary>
        public bool Has(string property, Type isType) {

            //try and get the property
            PropertyInfo prop = m_Type.GetProperty(property) as PropertyInfo;

            //If this type doesn't exist at all, just return false
            if (prop == null) { return false; }

            //if it does exist, verify the type
            if (prop.PropertyType.Equals(isType)) { return true; }
            return false;

        }

        /// <summary>
        /// Returns a type value using the specified type
        /// </summary>
        public T Get<T>(string property) {

            //return this value if needed            
            PropertyInfo prop = m_Type.GetProperty(property) as PropertyInfo;
            try {
                return (T)prop.GetValue(this.m_TypeData, null);
            }
            catch (Exception ex) {
                if (this.SupressExceptions) { return default(T); }
                throw new Exception(
                    string.Format(EXCEPTION_COULD_NOT_ACCESS_FIELD, property, typeof(T).Name),
                    ex
                    );
            }
        }



        /// <summary>
        /// Returns a type value using the specified type
        /// </summary>
        public T Get<T>(string property, object[] index) {

            //return this value if needed
            PropertyInfo prop = m_Type.GetProperty(property) as PropertyInfo;
            try {
                return (T)prop.GetValue(this.m_TypeData, index);
            }
            catch (Exception ex) {
                if (this.SupressExceptions) { return default(T); }
                throw new Exception(
                    string.Format(EXCEPTION_COULD_NOT_ACCESS_FIELD_AT_INDEX, property, typeof(T).Name),
                    ex
                    );
            }
        }



        /// <summary>
        /// Returns a type value using the specified type but includes a default value
        /// if one it missing
        /// </summary>
        public T Get<T>(string property, T defaultValue) {
            //return this value if needed
            PropertyInfo prop = m_Type.GetProperty(property) as PropertyInfo;
            if (prop == null) { return defaultValue; }
            try {
                return (T)prop.GetValue(this.m_TypeData, null);
            }
            catch (Exception ex) {
                if (this.SupressExceptions) { return defaultValue; }
                throw new Exception(
                    string.Format(EXCEPTION_COULD_NOT_ACCESS_FIELD, prop, typeof(T).Name),
                    ex
                    );
            }

        }



        /// <summary>
        /// Accepts a delegate that will use the names of the passed in
        /// parameters as properties to map to. If the property does not
        /// exist, then the method will fail.
        /// </summary>
        public void Use<T1>(Action<T1> with) {

            //set a default for each of the params
            T1 param1 = default(T1);

            //get the parameters for this method
            var paramList = with.Method.GetParameters();

            //update each of the parameters            
            string paramName = string.Empty;
            try {
                for (int i = 0; i < paramList.Length; i++) {

                    //find the correct matching property for this parameter
                    paramName = paramList[i].Name;
                    switch (i + 1) {
                        case 1:
                            param1 = this.Get<T1>(paramName);
                            break;
                    }
                }

            }
            catch (Exception ex) {
                throw new ArgumentException(
                    string.Format(EXCEPTION_MISSING_PARAMETER_INFORMATION, paramName),
                    ex
                    );
            }

            //otherwise, execute the method provided
            with(param1);

        }



        /// <summary>
        /// Accepts a delegate that will use the names of the passed in
        /// parameters as properties to map to. If the property does not
        /// exist, then the method will fail.
        /// </summary>
        public void Use<T1, T2>(Action<T1, T2> with) {

            //set a default for each of the params
            T1 param1 = default(T1);
            T2 param2 = default(T2);

            //get the parameters for this method
            var paramList = with.Method.GetParameters();

            //update each of the parameters            
            string paramName = string.Empty;
            try {
                for (int i = 0; i < paramList.Length; i++) {

                    //find the correct matching property for this parameter
                    paramName = paramList[i].Name;
                    switch (i + 1) {
                        case 1:
                            param1 = this.Get<T1>(paramName);
                            break;

                        case 2:
                            param2 = this.Get<T2>(paramName);
                            break;
                    }
                }

            }
            catch (Exception ex) {
                throw new ArgumentException(
                    string.Format(EXCEPTION_MISSING_PARAMETER_INFORMATION, paramName),
                    ex
                    );
            }

            //otherwise, execute the method provided
            with(param1, param2);

        }



        /// <summary>
        /// Accepts a delegate that will use the names of the passed in
        /// parameters as properties to map to. If the property does not
        /// exist, then the method will fail.
        /// </summary>
        public void Use<T1, T2, T3>(Action<T1, T2, T3> with) {

            //set a default for each of the params
            T1 param1 = default(T1);
            T2 param2 = default(T2);
            T3 param3 = default(T3);

            //get the parameters for this method
            var paramList = with.Method.GetParameters();

            //update each of the parameters            
            string paramName = string.Empty;
            try {
                for (int i = 0; i < paramList.Length; i++) {

                    //find the correct matching property for this parameter
                    paramName = paramList[i].Name;
                    switch (i + 1) {
                        case 1:
                            param1 = this.Get<T1>(paramName);
                            break;

                        case 2:
                            param2 = this.Get<T2>(paramName);
                            break;

                        case 3:
                            param3 = this.Get<T3>(paramName);
                            break;
                    }
                }

            }
            catch (Exception ex) {
                throw new ArgumentException(
                    string.Format(EXCEPTION_MISSING_PARAMETER_INFORMATION, paramName),
                    ex
                    );
            }

            //otherwise, execute the method provided
            with(param1, param2, param3);

        }



        /// <summary>
        /// Accepts a delegate that will use the names of the passed in
        /// parameters as properties to map to. If the property does not
        /// exist, then the method will fail.
        /// </summary>
        public void Use<T1, T2, T3, T4>(Action<T1, T2, T3, T4> with) {

            //set a default for each of the params
            T1 param1 = default(T1);
            T2 param2 = default(T2);
            T3 param3 = default(T3);
            T4 param4 = default(T4);

            //get the parameters for this method
            var paramList = with.Method.GetParameters();

            //update each of the parameters            
            string paramName = string.Empty;
            try {
                for (int i = 0; i < paramList.Length; i++) {

                    //find the correct matching property for this parameter
                    paramName = paramList[i].Name;
                    switch (i + 1) {
                        case 1:
                            param1 = this.Get<T1>(paramName);
                            break;

                        case 2:
                            param2 = this.Get<T2>(paramName);
                            break;

                        case 3:
                            param3 = this.Get<T3>(paramName);
                            break;

                        case 4:
                            param4 = this.Get<T4>(paramName);
                            break;
                    }
                }

            }
            catch (Exception ex) {
                throw new ArgumentException(
                    string.Format(EXCEPTION_MISSING_PARAMETER_INFORMATION, paramName),
                    ex
                    );
            }

            //otherwise, execute the method provided
            with(param1, param2, param3, param4);

        }

        #endregion

        #region Working With Arrays

        /// <summary>
        /// Returns the specified property as an array of AnonymousTypes
        /// </summary>
        public AnonymousType[] AsArray(string property) {
            object[] values = this.Get<object[]>(property);
            return values.Select(o => {
                if (o is AnonymousType) { return (AnonymousType)o; }
                return new AnonymousType(o);
            }).ToArray();
        }

        /// <summary>
        /// Performs the specified action on each value in an array of AnonymousTypes
        /// </summary>
        public void WithEach(string property, Action<AnonymousType> action) {
            foreach (AnonymousType value in this.AsArray(property)) {
                action(value);
            }
        }

        #endregion

        #region Static Methods

        /// <summary>
        /// Returns the type of data for the provided object
        /// </summary>
        public static T Get<T>(object data, string property) {
            return new AnonymousType(data).Get<T>(property);
        }

        /// <summary>
        /// Returns the type of data for the provided object
        /// </summary>
        public static T Get<T>(object data, string property, T defaultValue) {
            return new AnonymousType(data).Get<T>(property, defaultValue);
        }

        /// <summary>
        /// Returns the type of data for the provided object
        /// </summary>
        public static AnonymousType[] AsArray(object data, string property) {
            return new AnonymousType(data).AsArray(property);
        }

        /// <summary>
        /// Performs the following action on each of the values in the specified
        /// property value for a user
        /// </summary>
        public static void WithEach(object data, string property, Action<AnonymousType> action) {
            new AnonymousType(data).WithEach(property, action);
        }

        #endregion

    }
}

명시 적으로 목록으로 변환하고 ViewData를 캐스팅하는 것을 고려하십시오.

ViewData["QUsers"] = (from u in db.Users select u).ToList();

foreach(Users u in (List<Users>)ViewData["QUsers"]){ 

    /*Print the data here*/

}

위와 같이 ViewData를 사용하거나 동작 사이를 전달하기 위해 TempData를 몇 가지 방법으로 전달할 수 있습니다. ViewData.Model을 사용하여 강력하게 입력 한 모델을 포함 할 수도 있습니다. 뷰의 정의를 다음과 같은 것으로 변경해야합니다.

ViewPage<User>

멋진 리피터 교체는 시도해보십시오 http://www.codeplex.com/mvccontrib. 그들은 도움이 될 수있는 그리드 HTML 도우미가 있습니다.

하나의 프로젝션을 표시하기 위해 별도의 클래스를 만들지 않으려면 다음과 같은 사전 사용에 의지 할 수도 있습니다.

from person in personList select new Dictionary<string, string>
{ 
    { "Name", person.Firstname + " " + person.Lastname },
    { "Id", person.Id.ToString() }
};

그런 다음 뷰 페이지를 입력 할 수 있습니다

ViewPage<IEnumerable<Dictionary<string, string>>>

그리고 마지막으로보기에서 목록을 반복합니다.

<% foreach (Dictionary<string, string> p in (IEnumerable)ViewData.Model) 
{ %>
   <li> <%=p["Id"] %> - <%= p["Name"] %> </li>
<% } %>

말할 것도없이, 단점은 코드가 이제 "마법 문자열"으로 가득 차 있다는 것입니다. 컴파일 시간 점검이 없기 때문에 더 많은 오류가 발생합니다.

MVC의 Routevaluedictionary를 사용할 수 없습니까?

나는 당신이 찾고있는 것이 뷰 모델이라고 생각합니다. http://msdn.microsoft.com/en-us/vs201trainingcourse_aspnetmvc3fundamentals_topic7.aspx

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