problem with how I use ActionResult / trying to return List of simple class def

Last post 09-10-2008 12:52 AM by pkellner. 4 replies.

Sort Posts:

  • problem with how I use ActionResult / trying to return List of simple class def

    09-09-2008, 1:03 PM
    • All-Star
      23,801 point All-Star
    • pkellner
    • Member since 11-12-2004, 5:42 AM
    • San Jose, California
    • Posts 3,560
    • Moderator
      TrustedFriends-MVPs

    Following Scott Guthrie's example from preview 5, I've tried to create my own controller that returns a list of generic items.  I'm getting the error "can not convert..." as below

    My business class is just a simple list of 

     

     

     

     

    /// <summary>

    /// This is the DataItem that is used in the methods of the class above

    /// </summary>

    public class BusinessObjectItem

    {

    private bool approved;

    private DateTime createDate;

    private string email;

    private int id;

    private string name;public BusinessObjectItem()

    {

    }

    public BusinessObjectItem(BusinessObjectItem bo)

    {

    id = bo.id;

    name = bo.name;

    email = bo.email;

    approved = bo.approved;

    createDate = bo.createDate;

    return;

    }

    public BusinessObjectItem(int id, string name, string email, bool approved, DateTime createDate)

    {

    this.id = id;

    this.name = name;

    this.email = email;

    this.approved = approved;

    this.createDate = createDate;return;

    }

    [DataObjectField(true)]

    public int Id

    {

    get { return id; }set { id = value; }

    }

    [DataObjectField(false)]

    public string Name

    {

    get { return name; }

    set { name = value; }

    }

    Peter Kellner
    http://73rdstreet.com and blogging at
    http://PeterKellner.net
    MVP, ASP.NET
  • Re: problem with how I use ActionResult / trying to return List of simple class def

    09-09-2008, 1:16 PM
    Answer
    • Member
      115 point Member
    • freechoice
    • Member since 08-21-2008, 2:25 AM
    • Xiaman FuJian China
    • Posts 43

    As you see,the Return for the Index in the Controller is ActionResult

    So you need to return an ActionResult type,right?

    maybe you could try that

     

    1    public ActionResult Index()
    2    {
    3        ContactList member = yourBusiness.GetMembers();
    4        return View("Index",member);
    5    }
    6    
    7    You could use ModelData in your View Page
    
      Hope that can help you.

     

    Johnathan Cheung
  • Re: problem with how I use ActionResult / trying to return List of simple class def

    09-09-2008, 2:07 PM
    • All-Star
      23,801 point All-Star
    • pkellner
    • Member since 11-12-2004, 5:42 AM
    • San Jose, California
    • Posts 3,560
    • Moderator
      TrustedFriends-MVPs

     Thanks FreeChoice1 (interesting name BTW).  Your solution worked great.

    I'm wondering if there is another way that works somehow with the [bind] attribute.  On Preview 5 from ScottGu's blog, his example has a class which I'm pasting below.  It is specifically for product, but maybe it has relevance to the general case.

     using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using MvcApplication49.Models;

    namespace MvcApplication49.Controllers
    {
        //
        // This file shows an example of a custom IModelBinder.  This implementation creates a Product object
        // from form post values.  Note that you typically wouldn't create a custom IModelBinder per type.  
        // Instead you'd use a more generic binder like [Bind] which would handle all of your types.  
        //

        public class ProductBinder : IModelBinder
        {
            //
            // Helper Methods
            //

            private static string Concat(string modelName, string propertyName)
            {
                return (String.IsNullOrEmpty(modelName)) ? propertyName : modelName + "." + propertyName;
            }

            private static T LookupValue<T>(ControllerContext controllerContext, string propertyName, ModelStateDictionary modelState)
            {
                IModelBinder binder = ModelBinders.GetBinder(typeof(T));
                object value = binder.GetValue(controllerContext, propertyName, typeof(T), modelState);
                return (value is T) ? (T)value : default(T);
            }


            //
            // IModelBinder Member Implementation
            //

            public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState)
            {
                if (controllerContext == null)
                {
                    throw new ArgumentNullException("controllerContext");
                }
                if (modelType != typeof(Product))
                {
                    throw new ArgumentException("This binder only works with Product models.", "modelType");
                }

                // Instantiate an product object, then bind values to each property
                Product e = new Product()
                {
                    ProductName = LookupValue<string>(controllerContext, Concat(null, "ProductName"), modelState),
                    UnitPrice = LookupValue<Decimal>(controllerContext, Concat(null, "UnitPrice"), modelState),
                    ReorderLevel = LookupValue<short>(controllerContext, Concat(null, "ReorderLevel"), modelState),
                    Discontinued = LookupValue<Boolean>(controllerContext, Concat(null, "Discontinued"), modelState)
                };
                return e;
            }
        }
    }

    Peter Kellner
    http://73rdstreet.com and blogging at
    http://PeterKellner.net
    MVP, ASP.NET
  • Re: problem with how I use ActionResult / trying to return List of simple class def

    09-09-2008, 9:40 PM
    Answer
    • Member
      115 point Member
    • freechoice
    • Member since 08-21-2008, 2:25 AM
    • Xiaman FuJian China
    • Posts 43

    Hi

        Scott has said that:"Preview 5" doesn't have a built-in [Bind] attribute like above just yet (although we are considering adding it as a built-in feature of ASP.NET MVC in the future).  However all of the framework infrastructure necessary to implement a [Bind] attribute like above is now implemented in preview 5. The open source MVCContrib project also has a DataBind attribute like above that you can use today.

        So you can not use the Bind attribute in this version(Maybe the next version,and the version maybe a first beta version), But that dosn't means that you could not use ModelBinder in this version,If you wanna use ModelBinder,You need to do the following steps.

    1,Write your own ModelBinder,Here is Mine(Thanks to chsword)

     

    1    using System;
    2 using System.Collections.Generic;
    3 using System.ComponentModel;
    4 using System.Globalization;
    5 using System.Linq;
    6 using System.Web.Mvc;
    7
    8 namespace CMS.Models
    9 {
    10 public class CMSModelBinder:IModelBinder
    11 {
    12 #region IModelBinder Members
    13
    14 public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState)
    15 {
    16 //Instant Model Type
    17 object model = Activator.CreateInstance(modelType);
    18 //Get the Object property collections
    19 IEnumerable<string> keys = modelType.GetProperties().Select(c => c.Name);
    20 //Object Prefix,if the passing modelName is content,Will check name="content.ID" name="content.title"
    21 string objectPrefix = modelName;
    22 //Property Collections
    23 PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(model);
    24 var dictionary = new Dictionary<string, PropertyDescriptor>();
    25
    26 foreach (string str in keys)
    27 {
    28 if (!string.IsNullOrEmpty(str))
    29 {
    30 PropertyDescriptor descriptor = properties.Find(str, true);
    31 if (descriptor == null)
    32 {
    33 throw new ArgumentException(
    34 string.Format(CultureInfo.CurrentCulture,"Property dosn't exists:{0},{1}",new object[]{model.GetType().FullName,str}),"modelName");
    35
    36 }
    37 //Link the object and property names

    38 string str3 = string.IsNullOrEmpty(objectPrefix) ? str : (objectPrefix + "." + str);
    39 dictionary[str3] = descriptor;
    40 }
    41 }
    42 foreach (var pair in dictionary)
    43 {
    44 string key = pair.Key;
    45 PropertyDescriptor descriptor2 = pair.Value;
    46 object obj2 = ModelBinders.GetBinder(descriptor2.PropertyType).GetValue(controllerContext, key, descriptor2.PropertyType, modelState);
    47 if (obj2!=null)
    48 {
    49 try
    50 {
    51 //Set the Property Value
    52 descriptor2.SetValue(model, obj2);
    53 continue;
    54 }
    55 catch
    56 {
    57 //If we have a Vaildation Helper,It will shown in Html.ValidationSummary中
    58 string errorMessage = string.Format(CultureInfo.CurrentCulture, "Validation failed{0}:{1}", new[] { obj2, descriptor2.Name });
    59 string attempedValue = Convert.ToString(obj2, CultureInfo.CurrentCulture);
    60 modelState.AddModelError(key, attempedValue, errorMessage);
    61 continue;
    62 }
    63 }
    64 }
    65 //At last return the object
    66 return model;
    67 }
    68
    69 #endregion
    70 }
    71 }
     
    2) you need to register ModelBinders 
     
    1            [AcceptVerbs("POST")]
    2 public ActionResult Create([ModelBinder(typeof(CMSModelBinder))]ArticleAdd article)
    3 {}
      

      3) The View Page

    <span class="message">
        <%= ViewData["Message"]%>
    </span>
    <%= Html.ValidationSummary() %>
        <% using (Html.Form("Article","Create",FormMethod.Post)) { %>
            <table width="98%">
                <tr>
                    <td>Title:</td>
                    <td>
                        <%= Html.TextBox("article.title") %>
                        <%=Html.ValidationMessage("title","*") %>
                    </td>
                </tr>
                <tr>
                    <td>Alias:</td>
                    <td><%= Html.TextBox("article.alias") %></td>
                </tr>

    </table>   

    Johnathan Cheung
  • Re: problem with how I use ActionResult / trying to return List of simple class def

    09-10-2008, 12:52 AM
    • All-Star
      23,801 point All-Star
    • pkellner
    • Member since 11-12-2004, 5:42 AM
    • San Jose, California
    • Posts 3,560
    • Moderator
      TrustedFriends-MVPs

    Thanks!  I appreciate all the time you spent answering my questions.  Very helpful.

     

    Peter Kellner
    http://73rdstreet.com and blogging at
    http://PeterKellner.net
    MVP, ASP.NET
Page 1 of 1 (5 items)