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

[Solved] Using a template for a dropdown produces DataType error for bound columns

15 Answers 216 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.
Carey
Top achievements
Rank 1
Carey asked on 07 Jul 2011, 09:42 PM
I am building an MVC grid with server binding using the Entity Framework and want to add a drop down for the selection of one of the foreign key values (a type ID) but want to show the type name in a drop down for ease of use.

I started off by setting the grid up to just insert, edit, delete and all works. I then wanted to introduce a dropdown to manage the selection of the ID so users can select a type name rather have to know what ID to use for a foreign key.

I have followed all the samples and the tutorials I can find.  All indicate I am doing the right thing.

I keep getting an error when the view renders complaining about a type System.Int32 is being passed to the Model but the model expects a type of PROCESS_OBJECT.  The OBJECT_TYPE_ID is of type Int32, however I fail to understand why it is complaing or how to resolve it.

I just need to show a Drop down for the Type_ID column that displays the type name but is bound to the id.

The relationship is between a PROCESS_OBJECT type and the PROCESS_OBJECT_TYPE entity in my model.

I will upload the entire project to make it eaier for you to look at but I will include a couple snippets here as well.

Main editable view EditingServerSide.cshtml.
Controller: JobController.cs
Display Template: PROCESS_OBJECT.OBJECT_TYPE_ID template: Process_Object_Type.cshtml in the DisplayTemplate folder
Edit Template (Dropdown): PROCESS_OBJECT.OBJECT_TYPE_ID template: Process_Object_Type.cshtml in the EditTemplate folder
Decorated EF model object property OBJECT_TYPE_ID for PROCESS_OBJECT_TYPE with the UIHInt: [UIHint("Process_Object_Type")]

Controller populates the ViewData with the object:
private void PopulateJobTypes()
        {
            ViewData["process_object_types"] = 
                    db.PROCESS_OBJECT_TYPE.Select(e => new
                        {
                          Id = e.OBJECT_TYPE_ID,
                          Name = e.OBJECT_TYPE_NAME
                        })
                    .OrderBy(e => e.Name);
        }

Display Template:
@model TelerikMvcApplication2.PROCESS_OBJECT
@Model.PROCESS_OBJECT_TYPE.OBJECT_TYPE_NAME

Edit Template:
@model TelerikMvcApplication2.PROCESS_OBJECT
  
@(Html.Telerik().DropDownList()
        .Name(ViewData.TemplateInfo.GetFullHtmlFieldName(string.Empty))
        .BindTo(new SelectList((IEnumerable) ViewData["process_object_types"], "Id", "Name", Model.OBJECT_TYPE_ID))
)

View:
@model IEnumerable<TelerikMvcApplication2.PROCESS_OBJECT>
  
@{
    ViewBag.Title = "EditingServerPaging";
}
  
<h2>ServerPaging</h2>
  
<p>
</p>
  
@{  OMITTED FOR BREVITY.............. }
  
@{Html.Telerik().Grid<TelerikMvcApplication2.PROCESS_OBJECT>(Model)
        .Name("Jobs")
        .ToolBar(commands => commands.Insert())
        .DataKeys(keys => 
            {
                keys.Add(c => c.OBJECT_ID);
            })
        .DataBinding(dataBinding => dataBinding
            .Server()
                .Select("EditingServerSide","Job", new { mode = mode, type = type})
                .Insert("Insert", "Job", new { mode = mode, type = type })
                .Update("Save", "Job", new { mode = mode, type = type })
                .Delete("Delete", "Job", new { mode = mode, type = type }))
        .Columns(columns =>
            {
               //columns.Bound(o => o.OBJECT_ID).Title("Object ID").ReadOnly(true);
               //columns.Bound(o => o.PROCESS_OBJECT_TYPE.OBJECT_TYPE_NAME).Title("Object Type");
               //columns.Bound(o => o.OBJECT_NAME).Title("Name");
                columns.Bound(o => o.PROCESS_OBJECT_TYPE.OBJECT_TYPE_ID).Title("Type ID").ReadOnly(true);
                columns.Command(commands =>
                    {
                        commands.Edit();
                        commands.Delete();
                    }).Width(200).Title("Action");
            })
        .Pageable(paging => paging.Style(pagerStyles).Position(position).PageTo(currentPage))
        .Editable(editing => editing.Mode(mode))
        .Sortable().Filterable().Render();
 }

15 Answers, 1 is accepted

Sort by
0
Atanas Korchev
Telerik team
answered on 08 Jul 2011, 07:35 AM
Hello Carey,

 The exception you are getting occurs if the partial view is passed a model of different type than the one expected. You have decorated an int property (OBJECT_TYPE_ID):

[UIHint("Process_Object_Type")]
public global::System.Int32 OBJECT_TYPE_ID
{

 with an editor template whose expected model is ProcessObject:

@model TelerikMvcApplication2.PROCESS_OBJECT


It is entirely expected to receive such error. You need to either change the model of the partial view to int32 or decorate a different property of ProcessObject type with the UIHInt attribute.

Atanas Korchev
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Carey
Top achievements
Rank 1
answered on 08 Jul 2011, 08:25 AM
I am not sure I understand how this is suposed to work then.  How does the model get passed to the partial view?

I changed the model on the partial view to Int32, but I still get this error:

"The model item passed into the dictionary is of type 'System.Int32', but this dictionary requires a model item of type 'TelerikMvcApplication2.PROCESS_OBJECT'."

This error is being generated from the main view EditingServerside.cshtml where the grid is declared.

I was under the impression that the model is inherited from the view it is hosted in?  ALso how does the partial view get the value to set the dfault then if it is not the same model as the parent?

In every example, the Model of the partial view is the same as the class that the parent view uses.  For example, the editable server side grid with the employees list clearly shows the Employee class in both the partial view and the parent view.

Can you sugest a fix to the code I uploaded that will do what I need and maybe I might understand a bit better.


Thanks
0
Atanas Korchev
Telerik team
answered on 08 Jul 2011, 08:30 AM
Hello Carey,

 I cannot suggest a fix because I was not able to run your code because I don't have the database.

Our editing templates online demo shows how to use a dropdown during grid editing. Perhaps you can use it as a basis.

Regards,
Atanas Korchev
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Carey
Top achievements
Rank 1
answered on 08 Jul 2011, 08:47 AM
Its late...I looked at the sample again and I see the property for the column refers to the object Employee on Order.  I changed this to be similar on my example, and what d'ya know :-)

I moved the UIHint to the property PROCESS_OBJECT_TYPE on the PROCESS_OBJECT entity.

Changed the EditingServerSide.cshtml view grid column to just be PROCESS_OBJECT_TYPE and also made the partial view models of the same type.

Works now.

Thanks!!
0
Carey
Top achievements
Rank 1
answered on 08 Jul 2011, 09:11 AM
Now, how to get the value of the selected item from the edit/insert o the grid view into the controller insert or save methods?

The PROCESS_OBJECT_TYPE property of PROCESS_OBJECT no longer contains any data and I can no longer see the value selected from the dropdown when in the controller now :-(

Because of this the TryUpdateModel now fails and when the grid is refreshed in edit mode the validation error "value" is no longer valid apears.

I tried to simply use a string for both the DIsplay member and the data member of the dropdown but it always comes back with invalid value error on validation.
0
Atanas Korchev
Telerik team
answered on 08 Jul 2011, 09:27 AM
Hi Carey,

 You can check the client edit template demo as well. It shows a similar case to yours. 

Regards,
Atanas Korchev
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Carey
Top achievements
Rank 1
answered on 08 Jul 2011, 09:37 AM
I am using server binding though.

This is the controller Save method:
[AcceptVerbs(HttpVerbs.Post)]
       public ActionResult Save(int id, string name, GridEditMode mode, GridButtonType type, bool? pageInput, bool? nextPrevious, bool? numeric, GridPagerPosition? position, int? currentPage, bool? pageSize)
       {
           setViewData(mode, type, pageInput, nextPrevious, numeric, position, currentPage, pageSize);
           PROCESS_OBJECT process_object = new PROCESS_OBJECT();
           //Perform model binding (fill the product properties and validate it).
           //Exclude "PROCESS_OBJECT_TYPE from the list of updated properties
           if (TryUpdateModel(process_object)) //, null, null, new[] { "PROCESS_OBJECT_TYPE" }))
           {
               //Need to get this cloned object to update the real one in the entity context.

I added the string name but it is alwasys null...If I ignore the PROCESS_OBJECT_TYPE for the validation it works, BUT I have no way to get the value from the dropdown...
Does that work the same as the Client binding example?

I am also using Razor...
0
Atanas Korchev
Telerik team
answered on 08 Jul 2011, 11:15 AM
Hi Carey,

 I am not sure how to help you further. Both examples that I linked before show a working implementation of a dropdown editor - in server and client binding mode. I suggest you check the sample project which is available in the distribution.

Regards,
Atanas Korchev
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Carey
Top achievements
Rank 1
answered on 08 Jul 2011, 04:34 PM
Hi, Sorry I am not that familiar with how that Java Script function is supposed to work or what I am supposed to do to make it work with my scenario (i.e. what parts I need to modify).

I understand it is supposed to take the dropdown value and do something, just what and how is not clear and it is not explained anywhere that anyone can read to understand engouhg of what to change.

If you could explain it to me that I can probably figure out what I need to do.

Thanks
0
Carey
Top achievements
Rank 1
answered on 11 Jul 2011, 05:44 AM
When the script to return the selected item value from the dropdown is added to the view you get the following error:
 

Server Error in '/' Application.

The following sections have been defined but have not been rendered for the layout page "~/Views/Shared/_Layout.cshtml": "HeadContent".

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.


I have removed anything innoculous and it still gives an error.

The script I added is this modified to match my grid name and dropdown name:

@section HeadContent {   
 <script type="text/javascript">
     function onEdit(e) {
         $(e.form).find('#Jobs').data('tDropDownList').select(function (dataItem) {
             return dataItem.Text == e.dataItem['Id'];
         });
     }   
  </script>
 }
0
Atanas Korchev
Telerik team
answered on 11 Jul 2011, 08:57 AM
Hi Carey,

This exception is raised by the Razor view engine. You can find more info here.


 I cannot help you further unless you provide a sample project. You can attach a runnable version to this forum thread.

Regards,
Atanas Korchev
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Carey
Top achievements
Rank 1
answered on 11 Jul 2011, 05:35 PM
I will attach the project and the database MDF file for you BUT can I send it to you directly instead?

I did move the script into the actual head of the shared _Layout.cshtml and the page loads now.

HOWEVER, I still do not see where or how the dropdown value gets set and how to retrive it in my controller...

Can you explain please process of how this is supposed to happen?


Thanks...
0
Carey
Top achievements
Rank 1
answered on 12 Jul 2011, 06:23 AM
I ended up accessing the FormCollection directly in the controller.  Not sure what the other method is doing but it doesn't work because the javascript event never gets called.  Even then, it is not setting the dropdown value in the model on the view from what I can see.

Maybe you can explain it?


Thanks
0
Accepted
Atanas Korchev
Telerik team
answered on 12 Jul 2011, 08:13 AM
Hi Carey,

I fixed the project for you. Now the update works as expected.

Best wishes,
Atanas Korchev
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Carey
Top achievements
Rank 1
answered on 12 Jul 2011, 05:22 PM
The only difference I could see is that the line in the Edit Template view in the version you changed shows:

@(Html.Telerik().DropDownListFor(m => m.OBJECT_TYPE_ID)


The event binding on the grid definition and the script is not required so I have removed them and all seems to be functioning as expected now...

Thank You Very Much!!

Is there some documentation on this that explains this?
Tags
Grid
Asked by
Carey
Top achievements
Rank 1
Answers by
Atanas Korchev
Telerik team
Carey
Top achievements
Rank 1
Share this question
or