Current filter:
                                You should refresh the page.
                                  • [DevExpress Support Team: CLONED FROM K18525: How to bind editors to XPO objects in an ASP.NET MVC application]
                                    I've used solution #1 satisfactorily except that the last line of the XpoModelBinder fails

                                    xpoController.XpoSession.GetObjectByKey(classInfo, result.ConvertTo(classInfo.KeyProperty.MemberType))My Xpo object is a simple XpoObject class, so has "Oid" as its key and "Name" as a string property.
                                    When I edit the record with Oid=1, the "result" variable returned here:
                                    ValueProviderResult result = bindingContext.ValueProvider.GetValue(classInfo.KeyProperty.Name);has a "AttemptedValue" property = ""1""
                                    When the result.ConvertTo function tries to convert this value to an "int" it fails.
                                    Is the GridView returning an incorrect type value to the "result" variable?

                                • Uriah (DevExpress Support) 12.25.2017

                                  Would you please provide a sample project showing this issue? We will research it and find a solution.

                                  If you cannot reproduce the incorrect behavior in a simple project, please send us the corresponding View and Controller source code. Also, clarify the ASP.NET MVC version you are using.

                                • chris petchey @ bluerock 12.25.2017

                                  Here is a sample MVC web application that demonstrates my issue.

                                  The MVCXPOLib project contains the XPO class "Customer"
                                  The DXWebApplication1 is a sample implementation of the first solution to the "How to use XPO in MVC"

                                  To run: Set the web.config file connectionstring "default" to a valid sqlserver and credentials.

                                  Run the website.
                                  Global.asax will create a "Customer"
                                  The grid will load .
                                  If you click "Edit" on the existing customer row, change the customer name and click "Update", the XpoModelBinder CreateModel method tries to get the model's (Customer) Key property value (in this case from the "Oid") using the "result.ConvertTo" method.
                                  However, the value in the result.AttemptedValue property has quote marks eg ""1"" which prevents the ConvertTo method working and throws an exception. It should return an int value.

                                  Also, in the grid, if you click "new" the edit row shows "Oid" as a required field. I've tried to set this as a ReadOnly field to prevent users changing the value. The user should not have to enter the Oid value but the empty Oid field fails validation. How do I make the Oid field avoid validation?

                                  Back in the XpoModelBinder, the code says "if (result==null) return classInfo.CreateNewObject(xpoController.XpoSession);

                                  I think this is supposed to handle the case of a new record. I find that if I make "Oid" on the grid readwrite, to workaround the validation issue above, when I click "update", the "result" is not null , but the "result.AttemptedValue" is a blank string.

                                  Please give me the extra advice on how to make XPO work with a GridView in MVC

                                  Thank you

                                1 Solution

                                Creation Date Importance Sort by

                                Hello Chris,

                                Thank you for the sample project. To make it work correctly, modify the XpoModelBinder.CreateModel method as shown below:

                                protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { IXpoController xpoController = controllerContext.Controller as IXpoController; if(xpoController == null) throw new InvalidOperationException("The controller does not support IXpoController interface"); XPClassInfo classInfo = xpoController.XpoSession.GetClassInfo(modelType); ModelBindingContext keyPropertyBindingContext = new ModelBindingContext() { ModelMetadata = bindingContext.PropertyMetadata[classInfo.KeyProperty.Name], ModelName = classInfo.KeyProperty.Name, ModelState = bindingContext.ModelState, ValueProvider = bindingContext.ValueProvider }; PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext); PropertyDescriptor keyProperty = properties.Find(classInfo.KeyProperty.Name, false); IModelBinder keyPropertyBinder = Binders.GetBinder(keyProperty.PropertyType); object keyValue = GetPropertyValue(controllerContext, keyPropertyBindingContext, keyProperty, keyPropertyBinder); if(keyValue == null) return classInfo.CreateNewObject(xpoController.XpoSession); else return xpoController.XpoSession.GetObjectByKey(classInfo, keyValue); }

                                We will update the Knowledge Base article accordingly.

                                • chris petchey @ bluerock 12.26.2017

                                  I found a solution to the Oid field failing validation in the case of clicking the "new" button on the grid.

                                  I found that I could mark the callback event handler with a binding exclusion, which ignores the Oid value being blank:

                                  public ActionResult GridViewPartialAddNew([ModelBinder(typeof(XpoModelBinder))][Bind(Exclude = "Oid")] XPOBusinessObjects.Customer item)

                                • Pavlo (DevExpress Support) 12.27.2017


                                  Thank you for letting us know that you were able to resolve this issue on your side. The approach you demonstrated is one of possible solutions. However, it is not clear to me why you need to render the 'Oid' field's column and its editor. This field is defined as an autoincrement key, so it should not be edited.

                                  [Key(AutoGenerate = true)] public int Oid { get; set; }

                                  Allow me to describe now why a validation error occurs: as you can see, the 'Oid' field has the 'int' type. An empty editor in the edit form results in the 'null' value for the corresponding field. Thus, when the 'null' value is passed to the 'Oid' field, a conversion error occurs and a validation error is thrown. As you mentioned in your previous comment, you can exclude the 'Oid' field editor value from the model binding and avoid the validation error.

                                  Note, however, that the best approach here is to completely hide an editor. This will prevent the validation error and will not confuse your end-users (an empty field which can't be editable might look confusing). You can hide an editor by setting the MVCxGridViewColumn.EditFormSettings.Visible property to 'DefaultBoolean.False'. In inline editing mode, you need to use a different approach: define a custom Edit Item template using the MVCxGridViewColumn.SetEditItemTemplateContent method and render a key value.

                                  settings.Columns.Add(column => { column.EditFormSettings.Visible = DefaultBoolean.False; // Does not work in the inline editing mode column.SetEditItemTemplateContent(t => { if (t.Grid.IsNewRowEditing) { ViewContext.Writer.Write("Id is generated automatically"); } else { ViewContext.Writer.Write(DataBinder.Eval(t.DataItem, t.Column.FieldName)); } }); column.FieldName = "Oid"; column.Caption = "Oid"; });

                                  Let me know if you have additional questions regarding this scenario.

                                • chris petchey @ bluerock 12.27.2017

                                  Thanks once again for your invaluable help

                                • Pavlo (DevExpress Support) 12.28.2017

                                  We are always happy to help! Feel free to ask if you have other questions regarding DevExpress components.