This is a migrated thread and some comments may be shown as answers.

[Solved] MVC3 and Razor Grid editing Problem with Readonly property of a column

3 Answers 294 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Jyri
Top achievements
Rank 1
Iron
Jyri asked on 06 Mar 2011, 04:10 PM
Hi,

Telerik version ASP:NET MVC Version 2010.03.1318.340
ASP.NET MVC3
Razor view engine

When editing (updating) mode=inline the columns I have described as readonly show up correctly as readonly, but do not give the readonly values back to the controller.

when I make a breakpoint on a line (see bold line below) the readonly properties of my terminal object are null.

For not readonly properties all modified data is given back correctly to the controller.
 
I am puzzled, why?

Cheers,
Jyri

My view is Strongly typed
@model IEnumerable<CargoFlowPoco.Terminal>
...
...
@(Html.Telerik().Grid(Model)
        .Name("Grid")
        .DataKeys(keys => keys.Add(o => o.Id))
        .DataBinding(dataBinding => dataBinding
            .Server()
               .Select("Index", "Terminal")
               .Insert("Create", "Terminal")
               .Update("SaveUpdate", "Terminal")
               .Delete("Delete", "Terminal"))
        .Columns(columns =>
        {
            columns.Command(commands =>
            {
                commands.Edit();
                commands.Delete();
            }).Width(200);
            columns.Bound(o => o.Code).Width(100);
            columns.Bound(o => o.RegionName).Width(200);
            columns.Bound(o => o.InsertByUserId).Width(200).ReadOnly();
            columns.Bound(o => o.InsertTimestamp).Format("{0:g}").Width(120).ReadOnly();
        })
        .Sortable(sorting => sorting.Enabled(true))
        .Pageable(paging => paging.Enabled(true))
        .Footer(true)
)


My Terminal Controller

[HttpPost]
        public ActionResult SaveUpdate(int id, Terminal terminal)
        {
            try
            {
                    terminal.UpdateTimestamp = DateTime.Now;
                    _cRepository = new TerminalRepository(_uow);
                    _cRepository.Attach(terminal);
                    _uow.Save();
                    return RedirectToAction("Index");
            }
            catch
            {
                return RedirectToAction("Index");
            }
        }

        public ActionResult Index()
        {
            _cRepository = new TerminalRepository(_uow);
            return View(_cRepository.All());
        }

My objects are POCO and for validation I am using the "buddy object" approach suggested in ScottGu's blog
So I have auto generated class and its buddy class where validations are described 
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------


using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace CargoFlowPoco
{
    public partial class Terminal
    {
        #region Primitive Properties
    
        public virtual decimal Id
        {
            get;
            set;
        }
      
        public virtual string Code
        {
            get;
            set;
        }
    
        public virtual string RegionName
        {
            get;
            set;
        }
    
        public virtual string InsertByUserId
        {
            get;
            set;
        }
    
        public virtual System.DateTime InsertTimestamp
        {
            get;
            set;
        }
    
        public virtual string UpdateByUserId
        {
            get;
            set;
        }
    
        public virtual Nullable<System.DateTime> UpdateTimestamp
        {
            get;
            set;
        }
}

// Buddy class 
namespace CargoFlowPoco
{
    [MetadataType(typeof(TerminalValidator))]
    public partial class Terminal
    {
    }

    public class TerminalValidator
    {
        public virtual decimal Id
        {get;set;
        }
      
        [Required(ErrorMessage="Required field")]
        public virtual string Code
        {
            get;
            set;
        }

        [Required(ErrorMessage = "Required field")]
        [RegularExpression("^[a-zA-Z]+", ErrorMessage="Use only letters a-Z")]
        [StringLength(20,ErrorMessage="Max length is 20")]
        public virtual string RegionName
        {
            get;
            set;
        }

        [ReadOnly(true)]
        public virtual string InsertByUserId
        {
            get;
            set;
        }
    
        public virtual System.DateTime InsertTimestamp
        {
            get;
            set;
        }
    
        public virtual string UpdateByUserId
        {
            get;
            set;
        }
    
        public virtual Nullable<System.DateTime> UpdateTimestamp
        {
            get;
            set;
        }
    }
}

3 Answers, 1 is accepted

Sort by
0
figueiredorj
Top achievements
Rank 1
answered on 04 Apr 2011, 07:52 AM
Hi.

Have you found a solution?
I am having the same issue... while "inLine" is okay with ReadOnly properties, having PopUp mode does not format property as ReadOnly.

Any help appreciated...
Thanks 
0
Jyri
Top achievements
Rank 1
Iron
answered on 04 Apr 2011, 02:34 PM
My solution was to add hidden fields for read only properties to the view. This worked OK with inline editing. 
0
figueiredorj
Top achievements
Rank 1
answered on 04 Apr 2011, 03:43 PM
Actually I solved my problem with a EditorTemplate.

From my class i choose only properties I want to to edit.
Something like this:
Client.cshtml on Shared/EditorTemplates
@model Client
<fieldset>
    @Html.HiddenFor(model => model.Id)
    <table style="border-style: hidden">
        <tr>
            <td style="vertical-align: top">
                <div class="editor-label">
                    @Html.LabelFor(model => model.Code)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Code)
                    @Html.ValidationMessageFor(model => model.Code)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.Name)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Name)
                    @Html.ValidationMessageFor(model => model.Name)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.TaxNumber)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.TaxNumber)
                    @Html.ValidationMessageFor(model => model.TaxNumber)
                </div>
            </td>
            <td style="vertical-align: top">
                <div class="editor-label">
                    @Html.LabelFor(model => model.Address)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Address)
                    @Html.ValidationMessageFor(model => model.Address)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.PostalCode)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.PostalCode)
                    @Html.ValidationMessageFor(model => model.PostalCode)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.Country)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Country)
                    @Html.ValidationMessageFor(model => model.Country)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.Contact)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Contact)
                    @Html.ValidationMessageFor(model => model.Contact)
                </div>
            </td>
        </tr>
    </table>
</fieldset>

where my model is something like

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
 
namespace Model
{
    [MetadataType(typeof(ClientValidator))]
    public partial class Client
    {
        public Client()
        {
            Inserted = DateTime.Now;
            Updated = DateTime.Now;
        }
    }
    public class ClientValidator
    {
        [ReadOnly(true)]
        [ScaffoldColumn(false)]
        public object Id { get; set; }
 
        [Required]
        public object TaxNumber { get; set; }
 
        [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy HH:mm}")]
        [DataType(DataType.DateTime), Required]
        [ReadOnly(true)]
        public object Inserted { get; set; }
 
        [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy HH:mm}")]
        [DataType(DataType.DateTime), Required]
        [ReadOnly(true)]
        public object Updated { get; set; }
 
        [ScaffoldColumn(false)]
        public object Active { get; set; }
    }
}

Tags
Grid
Asked by
Jyri
Top achievements
Rank 1
Iron
Answers by
figueiredorj
Top achievements
Rank 1
Jyri
Top achievements
Rank 1
Iron
Share this question
or