Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

Last post 07-07-2009 3:35 PM by alessandro. 9 replies.

Sort Posts:

  • Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

    07-04-2009, 12:07 PM
    • Member
      27 point Member
    • john.lam
    • Member since 07-04-2009, 3:45 PM
    • Posts 124

    Hi all, I'm working on a program which I need to show the roles with GridView. I added a button to delete particular record but I got the error message "Deleting is not supported by ObjectDataSourceunless the DeleteMethod is specified". Finally I figured out that I need to add the property DeleteMethod into ObjectDataSource and to add an empty method for to avoid the error. My questions are: whether I used the wrong approach for this function? In what way I can avoid to use DeleteMethod with the empty method?

    Codes:

    <asp:GridView ID="DepartmentListGridView" runat="server" AutoGenerateColumns="false" DataSourceID="objDataSource" OnRowCommand="OnRowCommand" DataKeyNames="RoleName">
    <Columns>
    <asp:BoundField HeaderText="Department" DataField="RoleName" />
    <asp:HyperLinkField Text="<img src='/Images/edit.gif' border='0' />" DataNavigateUrlFormatString="RoleUpdate.aspx?RoleName={0}"
    DataNavigateUrlFields="RoleName" />
    <asp:ButtonField CommandName="Delete" ButtonType="Image" ImageUrl="~/Images/delete.gif" />
    </Columns>
    </asp:GridView>
    <asp:ObjectDataSource ID="objDataSource" runat="server" TypeName="Project.BLL.Membership.Role"
    SelectMethod="GetAllRoles" DeleteMethod="Delete"></asp:ObjectDataSource>

    protected void OnRowCommand(object sender, GridViewCommandEventArgs e)
    {
    if (e.CommandName == "Delete")
    {
    DeleteRole(Convert.ToInt32(e.CommandArgument));
    }
    }

    protected void DeleteRole(int index)
    {
    string roleName = DepartmentListGridView.DataKeys[index].Value.ToString();
    bool isDeleted = false;
    try
    {
    Roles.DeleteRole(roleName);
    }
    catch (Exception err)
    {
    DepartmentListGridViewErrorMessage.Text = "Delete Error!";
    HttpContext.Current.Trace.Write("Error Message: ", err.Message);
    }
    }

    public void Delete(){}

    Thanks a lot!
    John
    John
  • Re: Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

    07-04-2009, 1:39 PM
    • All-Star
      60,792 point All-Star
    • anas
    • Member since 09-21-2006, 8:31 AM
    • Palestinian Territory, Occupied
    • Posts 6,848
    • Moderator

    john.lam:
    what way I can avoid to use DeleteMethod with the empty method?

    One way is to change the Delete button commandName from "Delete" to any other name like "DeleteItem"

    <asp:ButtonField CommandName="DeleteItem" ...

    Then in your code , you check if the CommandName is "DeleteItem" ,

    if (e.CommandName == "DeleteItem") ...




    This way , you will not have to specify the DeleteMethod because you are not using the specail "Delete" command which requires to specify the DeleteMethod :)


    Regards,

    Anas Ghanem | Blog

  • Re: Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

    07-04-2009, 3:51 PM
    Answer
    • Contributor
      6,788 point Contributor
    • alessandro
    • Member since 06-25-2002, 10:05 AM
    • Italy
    • Posts 1,103

    well yes, you have used the wrong approach. the problem in your approach is you are taking a long un-necessary route and aren't making use of your controls functionality. while what your doing will work, you are hacking to make it work (put in simple terms).

    Instead use the control as it was meant to function making use of everything it offers you eg, currently you have a gridview bound to an objectdatasource. This combo gives you quite a lot of power.

    Back to your question, your delete method needs to be in the class that represents the objectdatasource. In this case Project.BLL.Membership.Role, so move you code there. I'm not sure why you stopped half way and then decided to hack. The proper way is as follows, by defining this method in your Role class :

    public void Delete(string roleName)
            {
                
            Roles.DeleteRole(roleName);
            }

    in your ObjectDataSource, add the parameter :

     <DeleteParameters>
                <asp:Parameter Name="roleNameuserName" />
            </DeleteParameters>

    the value will be supplied automatically as you already made roleName userName a field in DataKeyNames on your gridview :

    <asp:GridView ID="DepartmentListGridView" runat="server" AutoGenerateColumns="false"
            DataSourceID="objDataSource" OnRowCommand="OnRowCommand" DataKeyNames="RoleName"..

    see, and thats it. No RowCommand method, finding the roleName username by index manually and calling a method in your codebehind etc etc..

    also about your error checking and handling, perhaps you want to move that to the deleted method exposed by your objectdatasource :

    subscribe to the event first, perhaps declaratively as below :

    <asp:ObjectDataSource ID="objDataSource" OnDeleted="objDataSource_Deleted"...


    protected void objDataSource_Deleted(object sender, ObjectDataSourceStatusEventArgs e)
    {
      if (e.Exception != null)
      {

        // Handle the specific exception type. The ObjectDataSource wraps
        // any Exceptions in a TargetInvokationException wrapper, so
        // check the InnerException property for expected Exception types.
        DepartmentListGridViewErrorMessage.Text = e.Exception.InnerException.Message;
        // Because the exception is handled, there is
       // no reason to throw it.
          e.ExceptionHandled = true;
      }
    }

    for a proper description of the deleted method, look it up on msdn :

    http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.objectdatasource.deleted.aspx


    now as you can see, everything should just work. No need for your RowCommand handler. Also be weary of the ButtonField you used with type image :

    <asp:ButtonField CommandName="Delete" ButtonType="Image" ImageUrl="~/Images/delete.gif" />

    This has a bug that causes the gridview to postback twice on IE, so perhaps you might want to use a templatefield and define an ImageButton or workaround and apply the easy fix as suggested on the bug report below :

    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=456295

    EDIT : made corrections, since I kept referring to userName when what I really meant was roleName :-)

    Alessandro Zifiglio
    www.jiffycms.net - opensource HTML Editor for ASP.NET
    http://weblogs.asp.net/alessandro


    In the land of the blind, the man with one eye is king!:x
  • Re: Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

    07-05-2009, 11:42 AM
    • Member
      27 point Member
    • john.lam
    • Member since 07-04-2009, 3:45 PM
    • Posts 124

    Hi Anas and Alessandro, thanks for your suggestions and Alessandro's way works perfectly.

    For the bug of ButtonField with type image, if I use a templatefield and define an ImageButton as mention above, should I apply the templatefield for all the fields of the GridView, or just for the ImageButton will do, as in the following code?



    <asp:GridView ID="DepartmentListGridView" runat="server" AutoGenerateColumns="false" DataSourceID="objAllDepartments" DataKeyNames="RoleName">
    <Columns>
    <asp:BoundField HeaderText="Department" DataField="RoleName" />
    <asp:HyperLinkField Text="<img src='/Images/edit.gif' border='0' />" DataNavigateUrlFormatString="RoleUpdate.aspx?RoleName={0}"
    DataNavigateUrlFields="RoleName" />
    <asp:TemplateField>
    <ItemTemplate>
    <asp:ImageButton ID="DeleteButton" runat="server" ImageUrl="~/Images/delete.gif" CommandName="Delete" />
    </ItemTemplate>
    </asp:TemplateField>
    </Columns>
    </asp:GridView>


    John

    John
  • Re: Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

    07-05-2009, 11:49 AM
    • Contributor
      6,788 point Contributor
    • alessandro
    • Member since 06-25-2002, 10:05 AM
    • Italy
    • Posts 1,103

    Your welcome Wink

    Define templatefield just for buttonfield or commandfield of type image. or workaround if you want to use a buttonfield. the workaround is there on the bug report.

     

     

    Alessandro Zifiglio
    www.jiffycms.net - opensource HTML Editor for ASP.NET
    http://weblogs.asp.net/alessandro


    In the land of the blind, the man with one eye is king!:x
  • Re: Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

    07-06-2009, 11:19 AM
    • Member
      27 point Member
    • john.lam
    • Member since 07-04-2009, 3:45 PM
    • Posts 124

    Thanks for your explaination. While I try to work on the update part (to update the department name), I try to use <asp:CommandField ShowEditButton="true"></asp:CommandField> together with UpdateParameters in <asp:ObjectDataSource></asp:ObjectDataSource>, I notice that everytime I click the Update button, the updated value will not pass to the UpdateMethod and I found that UpdateParameters passed null value to UpdateMethod. Did I do anything wrong in my coding?

    <asp:GridView ID="DepartmentListGridView" runat="server" AutoGenerateColumns="false" DataSourceID="objAllDepartments" DataKeyNames="RoleName">
                            <Columns>
                                <asp:BoundField HeaderText="Department" DataField="RoleName" />
                                <asp:CommandField ShowEditButton="true" ButtonType="image" EditImageUrl="~/Images/edit.gif" UpdateImageUrl="~/Images/OK.gif" CancelImageUrl="~/Images/Cancel.gif"  />
                                <asp:TemplateField>
                                    <ItemTemplate>
                                        <asp:ImageButton ID="DeleteButton" runat="server" ImageUrl="~/Images/delete.gif" CommandName="Delete" />
                                    </ItemTemplate>
                                </asp:TemplateField>
                            </Columns>
                        </asp:GridView>
                        <asp:ObjectDataSource ID="objAllDepartments" runat="server" TypeName="Project.BLL.Membership.Role"
                            SelectMethod="GetAllRoles" UpdateMethod="UpdateRole" DeleteMethod="DeleteRole" OnDeleted="DepartmentDeleted">
                            <UpdateParameters>
                               <asp:Parameter Name="Department" Type="String" />
                            </UpdateParameters>
                            <DeleteParameters>
                                <asp:Parameter Name="RoleName" />
                            </DeleteParameters>
                        </asp:ObjectDataSource>


    public static void UpdateRole(string Department, string RoleName){...}


    Actually the value of BoundField is the field RoleName of the table aspnet_Roles, as retrieved by Roles.GetAllRoles(). I'm thinking is that because I have to include RoleId into GridView to make it work?


    Sorry for the long questions as I really have no idea on that.

    John

    John
  • Re: Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

    07-06-2009, 12:06 PM
    • Contributor
      6,788 point Contributor
    • alessandro
    • Member since 06-25-2002, 10:05 AM
    • Italy
    • Posts 1,103

    A lengthy post with full description is a good post imho Laughing

    So, about your issue at hand, use OldValuesParameterFormatString Property of your objectdatasource control like this :

    <asp:ObjectDataSource ID="objAllDepartments" runat="server" TypeName="Project.BLL.Membership.Role"
                            SelectMethod="GetAllRoles" UpdateMethod="UpdateRole" DeleteMethod="DeleteRole" OnDeleted="DepartmentDeleted"
    OldValuesParameterFormatString="{0}_original" ConflictDetection="CompareAllValues">
                            <UpdateParameters>
                               <asp:Parameter Name="roleName_original" Type="String" />
          <asp:Parameter Name="roleName" Type="String" />
                            </UpdateParameters>
                            <DeleteParameters>
                                <asp:Parameter Name="RoleName" />
                            </DeleteParameters>
                        </asp:ObjectDataSource>

    in this way, since the value you need (the original rolename unmodified is still stored in datakeynames) and the new value will both have the same name, you can resolve the conflict and get both the parameters by applying OldValuesParameterFormatString="{0}_original" and ConflictDetection="CompareAllValues".

    note the value of OldValuesParameterFormatString="{0}_original" ; this will pass your fieldname from datakeynames unchanged as it was, renamed as fieldName_original as this is the format i chose to use {0}_original ;

    now make the change also in your function for clarity :

    public static void UpdateRole(string RoleName_original, string RoleName){...}

    and it should just work*

    msdn:

    Conflict Detection
    By setting the ObjectDataSource control's ConflictDetection property to true, you can specify that the ObjectDataSource control should include original values when calling update methods of the source data object.

    http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.objectdatasource.oldvaluesparameterformatstring.aspx

    http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.objectdatasource.conflictdetection.aspx

    Not much information provided on msdn i'm afraid, but that and the answer in this post will help you put 2+2 together Wink

     

    Alessandro Zifiglio
    www.jiffycms.net - opensource HTML Editor for ASP.NET
    http://weblogs.asp.net/alessandro


    In the land of the blind, the man with one eye is king!:x
  • Re: Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

    07-06-2009, 12:09 PM
    • Contributor
      6,788 point Contributor
    • alessandro
    • Member since 06-25-2002, 10:05 AM
    • Italy
    • Posts 1,103

     mm change also the delete parameter, I forgot to update that one.

    <asp:ObjectDataSource ID="objAllDepartments" runat="server" TypeName="Project.BLL.Membership.Role"
                            SelectMethod="GetAllRoles" UpdateMethod="UpdateRole" DeleteMethod="DeleteRole" OnDeleted="DepartmentDeleted"
    OldValuesParameterFormatString="{0}_original" ConflictDetection="CompareAllValues">
                            <UpdateParameters>
                               <asp:Parameter Name="RoleName_original" Type="String" />
          <asp:Parameter Name="roleName" Type="String" />
                            </UpdateParameters>
                            <DeleteParameters>
                                <asp:Parameter Name="RoleName_original" />
                            </DeleteParameters>
                        </asp:ObjectDataSource>

    Alessandro Zifiglio
    www.jiffycms.net - opensource HTML Editor for ASP.NET
    http://weblogs.asp.net/alessandro


    In the land of the blind, the man with one eye is king!:x
  • Re: Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

    07-07-2009, 2:15 PM
    • Member
      27 point Member
    • john.lam
    • Member since 07-04-2009, 3:45 PM
    • Posts 124

    yep, that works, thanks for your help!

    John
  • Re: Deleting is not supported by ObjectDataSource objDataSource unless the DeleteMethod is specified

    07-07-2009, 3:35 PM
    • Contributor
      6,788 point Contributor
    • alessandro
    • Member since 06-25-2002, 10:05 AM
    • Italy
    • Posts 1,103

     cool. np :-)

    Alessandro Zifiglio
    www.jiffycms.net - opensource HTML Editor for ASP.NET
    http://weblogs.asp.net/alessandro


    In the land of the blind, the man with one eye is king!:x
Page 1 of 1 (10 items)