Search code examples
c#asp.net-mvc-3razorwebgrid

Cannot convert from 'lambda expression' to 'system.func dynamic object ' MVC3 Razor


I'm getting the mentioned error and "Invalid arguments" for WebGrid.column error in my view page.

//View

@{
    WebGrid grid = new WebGrid(Model.LoadProductDetails());
     @grid.GetHtml(
         tableStyle: "grid",
         fillEmptyRows: false,
         headerStyle: "gvHeading",
         alternatingRowStyle: "gvAlternateRow",
         rowStyle: "gvRow",
         footerStyle: "gvFooter",
         mode: WebGridPagerModes.All,
         firstText: "<< First",
         previousText: "< Prev",
         nextText: "Next >",
         lastText: "Last >>",
         columns: new[] {
         grid.Column("ProductId",header: "ID"),
         grid.Column("ProductName",header: "Product"),
         grid.Column("Price"),
         grid.Column("Qunatity"),     
         grid.Column("ReorderLevel", header: "R.O.L."),
         grid.Column("ContactusId", header: "Action", canSort:false, format: @<text> @Html.Raw("<img src='/img/edit.png' title='Edit' onclick='EditProduct("+ item.ProductId  ")'  />") @Html.Raw("<img src='/img/delete.png' title='Delete' onclick='DeleteProduct("+ item.ProductId +")'  />") </text>)       
     })    
}

The errors are thrown in the last column(ContactUsId) near the format:. Where i'm wrong?

Kindly help.


Solution

  • From my comment: It looks like you are trying to inject client-side HTML into a server-side function call (which in turn generates client-side output). That is the opposite of how MVC works (code injects into the page HTML). You need to make those @<> into C# strings. Then it can be processed server-side and the resulting GetHtml method will inject the final result into the output.

    Example: Something like this

    @{
        string template = "<text><img src='/img/edit.png' title='Edit' onclick='EditProduct("+ item.ProductId + ")' /><img src='/img/delete.png' title='Delete' onclick='DeleteProduct("+ item.ProductId +")' /></text>";
        WebGrid grid = new WebGrid(Model.LoadProductDetails());
         @grid.GetHtml(
             tableStyle: "grid",
             fillEmptyRows: false,
             headerStyle: "gvHeading",
             alternatingRowStyle: "gvAlternateRow",
             rowStyle: "gvRow",
             footerStyle: "gvFooter",
             mode: WebGridPagerModes.All,
             firstText: "<< First",
             previousText: "< Prev",
             nextText: "Next >",
             lastText: "Last >>",
             columns: new[] {
             grid.Column("ProductId",header: "ID"),
             grid.Column("ProductName",header: "Product"),
             grid.Column("Price"),
             grid.Column("Qunatity"),     
             grid.Column("ReorderLevel", header: "R.O.L."),
             grid.Column("ContactusId", header: "Action", canSort:false, format: template)    
    }
    

    Apologies for any typos, but this is just to indicate what you should be doing instead of trying to inject HTML into C# using Razor syntax (which would never work).

    As a readability improvement I would use string.Format to replace markers in the template string.

    e.g.

        string template = string.format("<text><img src='/img/edit.png' title='Edit' onclick='EditProduct({0})' /><img src='/img/delete.png' title='Delete' onclick='DeleteProduct({0})' /></text>", item.ProductId);