I'm using an ObjectDataSource to perform CRUD operations. For some reason I am getting an "ObjectDataSource 'ObjectDataSource1' has no values to insert. Check that the 'values' dictionary contains values."
Any suggestions?
I understand that this control inherits from the ObjectDataSource Control. According to the documentation http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.objectdatasource.insertmethod.aspx
If the DataObjectTypeName property is set, the method is resolved in a different way. The ObjectDataSource looks for a method with the name that is specified in the InsertMethod property that takes one parameter of the type that is specified in the DataObjectTypeName property.
That's how my ObjectDataSource Control is setup.
<asp: ObjectDataSource ID="ObjectDataSource1" runat="server"
DataObjectTypeName="MyApplication.Entities.Domain.MyObject" ConflictDetection="CompareAllValues"
OldValuesParameterFormatString="original{0}" SelectMethod="GetUserDisplays"
InsertMethod="CreateMyObject" UpdateMethod="UpdateMyObject" DeleteMethod="DeleteDisplay">
</asp:ObjectDataSource>
I set a breakpoint on the InsertMethod, but the application does not even hit it when I try to save my form. I suspect the DataObjectType is not being instantiated properly for some reason.
I'm trying to perform the Insert operation in the EditForm of an ASPxGridview control and the DataObjectType is an EF POCO which has some additional properties (marked virtual) in it to load related entities from the ObjectContext. I think this may be the problem but don't know how to fix it (have looked everywhere!!!).
Any help would be greatly appreciated!
Although I have not been able to determine exactly why the DataObjectType is not being instantiated automatically, I realized that there was an input parameter that needed to be added prior to calling the InsertMethod on the ObjectDataSource. To do this, I needed to add the input parameter (in my scenario anyway) in the Inserting event. Thanks to another post on StackOverflow I was able to figure out that I needed to remove the 'DataObjectTypeName' attribute from the ObjectDataSource for the Inserting event to fire.
I didn't notice a "TypeName" attribute in your ObjectDataSource definition. The DataObjectTypeName according to MSDN is used to identify the class "that the ObjectDataSource control uses for a parameter in an update, insert, or delete data operation, instead of passing individual values from the data-bound control." If the classes are the same (i.e. the CRUD methods class and the data object definition class) then both attributes should be assigned to the same class. If however, your methods are contained in a separate class from your DTO then you would identify each individually.
This helpful post solved the issue for me:
http://dyslexicanaboko.blogspot.com/2012/09/objectdatasource-has-no-values-to.html
Related
I have an ObjectDataSource on an ASP.NET WebForms page, that also has a data-bound control. The declarative syntax for the ODS looks like this:
<asp:ObjectDataSource runat="server" ID="ods"
TypeName="Transaction"
SelectMethod="GetTransactionList"
SelectCountMethod="GetTransactionListCount"
DataObjectTypeName="Transaction.TransactionViewModel"
UpdateMethod="UpdateTransaction"
>
</asp:ObjectDataSource>
Data is successfully retrieved from the data source; however, when an Update operation is attempted, this error occurs:
The data object type specified in the DataObjectTypeName property of ObjectDataSource 'ods' could not be found
The type Transaction.TransactionViewModel is public, and it is visible from the code-behind of this page. Why can't the ObjectDataSource find it?
Your type specification is incorrect for an inner class. To specify an inner class, you need to use +, not ., this:
DataObjectTypeName="Transaction+TransactionViewModel"
u must write the Object type used in there..
ie is u want all carts to be set to ObjectcontainerDS then..
Bind the corresponding Business entity to that container..
I want to verify that a generated class (single entity or collection) from an O/RM tool is data binding compatible.
I read that supported data binding types in WCF are: one time, one way, two way, one way from source in WCF. But how about "old school" .NET 1.1 data binding ?
It looks kind of difficult to check in code what kind of data binding support there is. You also have difference in runtime and design time data binding support. When reading some webpages I read different kind of implementations: implement IList, IComponent, INotifyPropertyChanged, IBindingList.... pffffff I don't know exactly where to look for...
You can databind to virtually any class. Let's imagine you create a very simple class, with a few properties, say for instance, Person with a Name and Age. I am talking about a plain simple class with absolutely nothing fancy about it.
If you create an instance of Person, you can do several things with it, and I will assume you are working with Windows Forms, but this mostly applies to other frameworks:
- You can bind its properties to properties of controls.
- You can bind it to datagrids, lists, etc. In the former case you can set mappings of which properties bind to which columns. In the latter, which property is displayed in the list, which property is the value selected by the user.
- Even better, you can bind it to a bindingSource.
Binding a single instance to a grid or a list isn't that useful, so what usually is done is that you create a list of instances and bind those to the grid. Even more correct is to bind the list to a bindingsource and the grid to the bindingsource also.
You can see a good article here about how to do all this.
Now, about all the interfaces you mention, they all only add more value to the databinding experience. Let's talk about a few of them.
INotifyPropertyChanged. Person is not less "databindable" than any other object if it does not implement this interface. What instances of Person are not able to do, however, is notify the controls their properties are bound to that the latter have changed. Try this: Bind the Name property of a Person instance to the Text property of a TextBox. Create a button that when clicked changes the value of that instance's Name. You will see the TextBox does not update after clicking the button. If, on the other hand, you implement INotifyPropertyChanged and have the setter of the Name property raise the PropertyChangedEvent that is defined by the interface, after repeating the experience, you will see that the textbox is updated automatically.
IEnumerable. If instead of a single Person, you want to databind not to a set of people, you can create a list of people and databind to that list. Let's take for instance, List lst = new List(); How do the databinding controls like datagrid, bindingSource, etc., know you want to bind to a set of Person(s) and not to the properties of lst itself? It is because List implements IEnumerable. So, whenever you bind these controls to an instance of anything that implements IEnumerable, the controls know that you intend to bind not to the properties of the list, but to the instances the list refers to. How do they know the type of objects the list contains? To be more generic and support any type of IEnumerable implementation, they just check the type of the first element in the list and assume all others are equal.
IBindingList: Even if Person implements IPropertyChanged, if you group instances of Person into a List bind that list to a control and, by code, change the value of a property of one of the instances, you will see nothing happen in the screen. This happens because Person is notifying, not the binding source, but the list. But the list wasn't made for databinding, so it is not listening, nor propagating the event to the control. Lists that implement IBindingList, like BindingList, offer a better databinding support precisely by listening to the PropertyChangedEvent events of their contents and propagating them up to the databound control.
I am affraid I have given you no way of determining if an object is databoundable, because virtually all them are, but I hope I've given you a way of determining different levels of databinding support (INotifyPropertyChanged and IBindingList). I am assuming you know how to check for these via reflection.
Any instance of a class with properties is data bindable. (in fact instances of any class with fields or properties at all are data bindable)
Using reflection in .NET makes it very easy to discover/use data in an object. (at a small performance cost)
In order to answer this question you'd need to provide the specific usage scenarios you'll be encountering.
Rui gives some good explanation of different common data binding patterns, but each of them is for solving specific problems.
The right answer is always dependent on the context.
:)
I use a lot of repeaters for different elements of our sites, and I've always wondered if there was a way to have the repeater skip an element if an exception occurs instead of having the whole page crash?
In particular, I've inherited a system from another developer that using a similar design, however he didn't include any kind of validation for his business objects, and it a single property is missing, the whole thing goes up in smoke.
Any suggestions?
Thanks in advance!
The simplest suggestion I can offer is the check the validity of the data before it's passed to the repeater. I don't believe there's any way to get the stock repeater to skip a data element on error.
The other approach is to build your own repeater, inheriting from the base Repeater, to add that functionality but I've no sample code to offer. Perhaps someone else may be able to help there.
The way I see it, you have at least three options.
You could create a custom repeater control that inherits System.Web.UI.WebControls.Repeater and override the databinding behaviour to be more try-catchy (probably fail silently on databinding errors). You couldd then easily replace all instances of the standard Repeater with this new one.
You could filter your datasources before databinding to remove items you know are going to cause problems beforehand. This option may be quite laborious and something of an iterative process.
You could try adding default values to the business objects, so that the properties you're binding to return a default instance rather than null (not nice either).
That's my thoughts anyway.
One question - you say "when a property is missing". Do you mean he's using a style of databinding syntax that offers no compile-time checking and is referencing properties that don't exist, or is referecing properties that are null?
Edit
OK, so you're referencing properties that are null. If you have access to the code for the business objects you could modify them so they return a new, non-null instance (this is the third option I gave).
You don't say if you're using .net 3.5, but I'll assume you are. You could add a new property "IsValidForDataBinding" on to each of your business objects. In the getter logic you could check each of the necessary properties and sub-objects to check for validity, non-nullness etc and return a bool. When you come to bind your repeater, write a simple linq statement that filters-out the invalid items (i.e. where IsValidForDataBinding = false). Having said that, I still think that writing a derived repeater control could be your easiest option.
Have you tried using string.isnullorempty("the string") to check for a value before referencing the property?
Here's a reference: MSDN
I've got a Linq 2 SQL object I'm trying to update. Two of the properties on this object are related to each other, and setting one sets the other.
So if I do:
Foo.Code = BEER;
The Foo.CodeID property will automatically be set to 5 (or whatever.)
The problem is that LinqDataSource sets Foo.Code, then immediately sets Foo.CodeID... which is not bound to anything since we want the users to set just Code. This immediately sets them both back to null.
I know I can use Parameters to default values, but is there any way to just tell LinqDataSource to not even set a property?
EDIT: Worked around issue by creating a hidden field, and assigning the correct value to that in the formview's ItemUpdating event. Would still like to avoid doing the same lookup four times though...
Would it be an option to make the Code property private (select the Code property in the dbml and set the access property in the Properties window) and create a new public property over which you have more control?
I personally have have written a generator that generates the necessary files for me (like sqlmetal), giving me full control over the code. Perhaps this is an option for you as well, if you do not like the generated dbml.
Does anybody know the logic behind making DataSourceSelectArguments sealed?
I've implemented a custom DataSource (and related classes) for some custom business objects and custom WebControls. When thinking in filters (like in a grid) I discovered that the DataSourceSelectArguments is sealed. Surely, I'm missing something. (Maybe the logic is related to the fact that is nonsense to ask the DB again, just for filtering?, just a guess.)
Sorry for the delay, I was on holydays. :)
The problem is that a DataBoundControl such as ListView has a SortExpression property, but not a FilterExpression. It is fine to implement a sortable grid/list with a ListView by means of a IButtonControl WebControl that fires a PostBack and a Command event. Then you use the SortExpression or the Sort method and pass a sort expression that will fill the DataSourceSelectArguments.SortExpression and pass it to the DataSource which can construct the apropiate SQL statement (in my case) to retrieve the Data from the DB. This allows for separation between the Data and the WebControl that displays it, IMHO.
Following this pattern I was about to implement a filter by filling an extra parameter object in my DataSourceSelectArguments with the requested filter and I will have called Sort, which would have passed this arguments object to the DataSource, where I would have constructed the appropiate select clause.
I've finally solve it by "coding" the filter information in the SortExpression, but I find it ugly (for the name, in the first place: sort != filter), and I was wondering if there's a more appropiate way of doing this or if I'm missing something that is more subtle.
Edit:
Maybe a better approach would be to override ListView's PerformSelect method and ask my own implementation of the DataSourceView if it can filter, then call a special ExecuteSelect method that accepts a special DataSourceSelectArguments with a filter object. Taking care not to do anything that will break when someone use the custom ListView with a non-enhanced DataSourceView, of course.
My guess is because the class is a dumb data transfer object merely used to pass arguments to a method.
This class itself doesn't have any operations defined on it, thus what sort of polymorphism would you expect? For example, the existing methods will only know about the properties of this class, which are all settable, so there's no need to override the properties. If you added new properties, they would get ignored.
For your own method, can you create your own Arguments class that just happens to have all the same properties?