5

First off, I've been looking through all posts I could find that handles this error on JQuery Ajax calls, but most of them as due to wrong dataTypes expected back, and I'm pretty sure that's not my problem since this code has worked before.

What I'm trying to do is when I click one of my checkboxes, I want to retrieve a partial view with a model and populate it in #selectedProductContainer on my main view.

This is my main view (Shortened quite a bit) with the scripts that's running:

@model ProductMainViewModel
<div class="product-list-wrapper">
        @Html.CheckBoxListFor(m => m.PostedProducts.ProductIds,
            m => m.AvalibleProducts,
            entity => entity.Id,
            entity => entity.Name,
            m => m.SelectedProducts,
            m => new { @class = "productCheckboxList productSelected" + m.Id, data_price = m.Price.ToString() })
  </div>
  <div id="selectedProductContainer">

  </div>

<script>
 $(".productCheckboxList[type='checkbox']").change(function () {
        var isChecked = $(this).is(":checked");
        var value = $(this).val();
        if (isChecked) {
            ProductChange(this);
        }

function ProductChange(element) {
        var value = {
            Value: element.value
        }
        var container = $("#selectedProductContainer");
        $.ajax({
            url: "@Url.Action("ProductCalcSelection", "Home")",
            type: "POST",
            data: JSON.stringify(value),
            contentType: "application/json",
            dataType: "html",
            success: function(data) {
                container.append(data);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                alert("error: " + errorThrown);
            }
        });
}
<script>

The controller action for this call looks like this:

[HttpPost]
    public ActionResult ProductCalcSelection(string value)
    {
        var convertValue = Convert.ToInt32(value);
        var product = db.Products.FirstOrDefault(p => p.Id == convertValue);
        var accessories = db.Accessories.ToList();

        var productViewModel = new ProductFormViewModel
        {
            Product = product,
            Accessories = accessories
        };

        return PartialView("_ProductForm", productViewModel);

Here is first my View model for my partial view:

public class ProductFormViewModel
{
    public Product Product { get; set; }
    public List<Accessory> Accessories { get; set; }
}

And here is my partial view (Short version):

@model ProductFormViewModel

<div>
    <span>Hello</span>
</div>

The issue is that from the ajax-call I get back "error: Internal Server Error" in my alert box for the error handling. I've debugged through this entire call, and all my values are correct. It seems to freak out when the controller sends back the partial view and my view model.

In the back of my mind I feel like this is due to wrong dataType as response, but I expect html back, and that's what I should get, right? This worked earlier, but we had to make some small changes to the Accessory model and I'm aware that the problem should be connected to this change, but I can't seem to find the connection. I'll post my classes here too if they would be needed:

public class Product : IProduct
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public long Price { get; set; }
    public bool HasAccessories { get; set; }
}

public class Accessory : IAccessory
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public string CodeName { get; set; }
    public string AccessoryType { get; set; }
    public long Price { get; set; }
    public bool IsMultiplied { get; set; }
    public int ProductId { get; set; }
    //public virtual ICollection<ProductId> ProductIds { get; set; }
}

The change we made on Accessory was that we decided that we only need one ProductId per Accessory, earlier we use the virtual ICollection to store multiple Id's. That class looked like this:

public class ProductId
{
    [Key]
    public int Id { get; set; }
    public int ProductIdHolder { get; set; }

    [ForeignKey("Accessory")]
    public int AccessoryId { get; set; }
    public virtual Accessory Accessory { get; set; }
}

We're not using this at all now, but instead uses the regular int ProductId.

Any ideas to what could have gone wrong?

EDIT: I'm adding my browser devtools error message:

POST http://localhost:54213/Home/ProductCalcSelection 500 (Internal Server Error) send @ jquery-2.1.3.js:8625 jQuery.extend.ajax @ jquery-2.1.3.js:8161 ProductChange @ offert.js:113 (anonymous function) @ Offert:179 jQuery.event.dispatch @ jquery-2.1.3.js:4430 elemData.handle @ jquery-2.1.3.js:4116

Line 113 in offert.js is where my $.ajax begins. Line 179 for anonymous function is my call to ProductChange() function.

Martin Johansson
  • 773
  • 1
  • 11
  • 27
  • Change Value: element.value to value: element.value. – Mairaj Ahmad Apr 21 '15 at 09:17
  • 1
    This is the error on server. Debug the request using developer tools. – Tushar Apr 21 '15 at 09:17
  • The problem is with the ProductCalcSelection function. Put a breakpoint at the beginning of it and check what 'value' is set to by the AJAX call. Then let it run and it will break where the actual error is. What is that error? – gamesmad Apr 21 '15 at 09:18
  • Remove contentType and dataType and see what happens. – Inspector Squirrel Apr 21 '15 at 09:22
  • 1
    Why are you sending the parameter as JSON, if it is only an integer value? – ssilas777 Apr 21 '15 at 09:24
  • You have an error in your application and it has created a 500 error. If you use your browsers dev tools you should be able to see the error message being returned. You mentioned that you changed a model so I'm going to make an educated guess and say you haven't updated/migrated your database to reflect this change. If you were to enumerate the results in the action instead of in the view you will see the exception being thrown. – heymega Apr 21 '15 at 09:24
  • I've put breakpoints in the beginning of the ProductCalcSelection. the value into the controller is correctly the value-tag in the html. I've also set breakpoint at end of the action method and it fills out my view model correctly. I don't get any exception in VS. I'll add my devtools error to my question. – Martin Johansson Apr 21 '15 at 09:25
  • @heymega I have migrated. Otherwise I get a error saying that my database does not correspond to my model etc. You mean to do a foreach loop through the list in the controller? I'll try and see if I get an error, but the list looks ok at debug. – Martin Johansson Apr 21 '15 at 09:27
  • You've posted tons of code (too much really), but the most interesting piece is missing: The partial view (not short version, but important version). – Mackan Apr 21 '15 at 09:29
  • In developer tools, click on Network. Refresh the page. You will see the error 500 for ProductCalcSelection line appear in red. Click it. Then click preview. What is the error message it says there? – gamesmad Apr 21 '15 at 09:32
  • @ssilas777 If I'm not mistaken Ajaxcalls always send data with json. – Martin Johansson Apr 21 '15 at 09:34
  • @Mackan yeah I've posted everything that has to do with the call itself. You want the full partial view? It's pretty long and I thought since I get error in ajax call it doesn't use the html code inside it. I might be wrong there though. – Martin Johansson Apr 21 '15 at 09:34
  • Your action by default will return an error page with the response. Your error message is inside it – heymega Apr 21 '15 at 09:38
  • No, not the whole thing then. But some bits and pieces would help. If this generates errors when getting bound by .net, the ajax error would get hit (instead of success) with a generic 500 error. If you'd like to debug it properly include your partial without the use of ajax (with some generic id), and see if it renders at all. – Mackan Apr 21 '15 at 09:38
  • @MartinJohansson I just noticed you are making post, still its wrong if you believe ajax calls always send data with Json. – ssilas777 Apr 21 '15 at 09:39
  • @gamesmad ah, I see! I was looking in the console for the error. Now I see that it's looking for my old ICollection of ProductIds. The error is in Swedish, but I see now where my error is. I had not updated the modelbindings for the form. Not sure what to use as an Answer though. If you write one I will accept. Thanks everyone for the input and sorry for missing the obvious! – Martin Johansson Apr 21 '15 at 09:39
  • @Mackan yeah you're correct! I just looked for the error in the wrong place. :) Thanks! – Martin Johansson Apr 21 '15 at 09:40
  • @ssilas777 oh? is that only for posts? I've only used JQuery ajax for posts and I've always had to make my routevalues Json. – Martin Johansson Apr 21 '15 at 09:44
  • For post since data is posted as content body, but while using Ajax Get call you don't have to use datatype JSON, it can be changed as depends. – ssilas777 Apr 21 '15 at 10:10

1 Answers1

11

As @Mackan and @gamesmad pointed out in the comments, I was looking at the wrong error. When I opened Network in devtools and clicked the call->Preview I got an asp.net error message that gave me all information I needed. In my case I had forgotten to update the partial view I send back with the updated model.

Martin Johansson
  • 773
  • 1
  • 11
  • 27
  • 1
    For anyone else still having issues, check out this [solution](http://stackoverflow.com/a/16916600/4896260). It provides a more detailed error that Fiddler and such were not able to provide. – usr4896260 Mar 06 '17 at 15:18