1

I'm trying to get some information from a table in my database whenever a select-field changes.

I'm able to do the response and the Ajax jQuery function return success(function)
The problem is i don't know how to return the data from my database using ASP.net MVC.
The response i'm getting from my Ajax call on success is this text:

ProduktWebKort.Models.WarehouseCustomer[]

This is the part of my controller with the function called via Ajax

[HttpPost]
public string OnChange(int id)
{
    return db.Customers.Where(C => C.CustomerID == id).ToString();
}

My Ajax call looks like this:

<script type="text/javascript">
$(function () {
    // Document.ready -> link up remove event handler
    $("#CustomerID").change(function () {
        alert("Hej");
        var option = $('option:selected', this).val();
        $.ajax({
            type: "POST",
            url: '@Url.Action("Index/1", "Session")',
            contentType: "application/json; charset=utf-8",
            data: { id: 1 },
            dataType: "html",
            success: function (success) {
                alert('Success');
                console.log(success);
                for (var i = 0; i < success.length; i++) {
                    $(".form-horizontal").append("<li>" + success[i] + "      </li>");
                    console.log(success);
                }
            },
            error: function (e, text, string) {
                alert(e.message + text + string);
                console.log(e);
            }
        });
    });
});
</script>

I want to return every entry from WarehouseCustomer with the CustomerID of id from my select field.

VMAtm
  • 27,943
  • 17
  • 79
  • 125
  • 2
    Generally for responding to AJAX calls in an MVC 5 application, you'd actually use [Web API](http://www.asp.net/web-api). What is the current function returning, and what did you want it to return? – mason Mar 09 '15 at 13:54
  • what are you trying to do? Get one customer with particular ID? Or get a list of customers? – teo van kot Mar 09 '15 at 13:59
  • What are you actually looking for? If you're just looking for suggestions then as @mason said, you should use `Web API` and return some JSON to bind it with your dropDown, if you've any other issue then update your question. – Mox Shah Mar 09 '15 at 13:59
  • It currently returns a string like this: ProduktWebKort.Models.WarehouseCustomer[] I'm trying to return a list of all the WarehouseCustomers with a CustomerID of what is choosen by the select – Søren Fritzbøger Mar 09 '15 at 13:59
  • 2
    @SørenFritzbøger You should edit your question to include the results. Information vital to the question such as expected output and actual output is a vital part of the question, and therefore belongs in the question itself instead of the comments. – mason Mar 09 '15 at 14:00

3 Answers3

1

The default implementation of the .ToString() method in .NET is returning the type of an object. So the resulting text you've got is exactly what are you dealing with: array of the WarehouseCustomer objects:

The default implementation of the ToString method returns the fully qualified name of the type of the Object, as the following example shows.

To get data from your server you should serialize the data object, either in XML or JSON form (preferred variant) to resolve them on the client side.

The ways you can do it are numerous, so you should just select the one you're comfortable with. I suggest you to see after @mason's answer as it looks like the best way to solve your problem.

VMAtm
  • 27,943
  • 17
  • 79
  • 125
1

In an MVC 5 project, you use Web API to respond to AJAX requests. Web API examines the request for what is being requested and what format the client supports. It then serializes to JSON or XML or other formats appropriately. It also follows the MVC architecture closely, and has been merged into the MVC framework as of the upcoming MVC 6.

Install Web API in your project via NuGet. Enable attribute routing.

[RoutePrefix("api/customers")]
public class CustomerController : ApiController
{
    [Route("byid/{id}")]
    public List<Customer> GetCustomers(int id)
    {
        return db.Customers.Where(C=>C.CustomerID==id).ToList();
    }
}

That should return a list of customer objects in the data format requested by the client (by default JSON).

The URL you request should be an HTTP GET request to ~/api/customers/byid/{id}, ex: ~/api/customers/byid/5. I often use the MVC Helper @Url.Content() for mapping to Web API on the client side.

Your success handler should be like this:

success: function (customers) {
            alert('Success');
            console.log(customers);
            for (var i = 0; i < customers.length; i++) {
                $(".form-horizontal").append("<li>" + customers[i].Name + "</li>");
                console.log(success);
            }
        },
mason
  • 31,774
  • 10
  • 77
  • 121
  • just don't understand why use WebAPI, espesially download something if you don't need WebAPI at all for this task? – teo van kot Mar 09 '15 at 14:19
  • 1
    @teovankot What do you mean "don't need Web API at all for this task"? Web API is *the* standard way of responding to AJAX requests in an MVC project. It's simple to add and integrates well. Are you sure your answer works? And why did you decorate your action method with `HttpPost` attribute when it's not modifying data? That should be an `HttpGet`. And `OnChange` is not a good way of naming a function that's supposed to return a collection of customer objects. – mason Mar 09 '15 at 14:25
  • [JSON Hijacking](http://stackoverflow.com/questions/8464677/why-is-jsonrequestbehavior-needed/8464685#8464685) is a reason why i decorate this method with POST. I just don't get what is the difference between WebAPI and Controller method for this case. And if you need to download something when you can not doing why you should? About naming methods it's to author of question. – teo van kot Mar 09 '15 at 14:29
  • @teovankot Did you downvote? Care to explain why? Web API does use controllers, perhaps you mean you don't understand the difference between MVC and Web API? They're similar, but Web API is geared towards programmatic server/client interaction while MVC is geared towards returning HTML to the client. They're both part of ASP.NET, and should be used in conjunction. – mason Mar 09 '15 at 14:49
0

Your problem on both server and client side. If you want to get List of customers on server side you should write your Controller like this:

[HttpPost]
public JsonResult OnChange(int id)
{
    return Json(db.Customers.Where(C => C.CustomerID == id).ToList());
}

On client side you should change your ajax code like this if you want to work with IEnumerable result:

     $.ajax({
        type: "POST",
        url: '@Url.Action("OnChange", "Session")',
        data: { id: 1 },
        dataType: "json",
        success: function (success) {
        alert('Success');
        console.log(success);
        $.each(success, function (i, item) {
           $(".form-horizontal").append("<li>" + item.CustomerID  + "</li>");                                              
           }); 
        },
        error: function (e, text, string) {
            alert(e.message + text + string);
            console.log(e);
        }
    });

I hope your OnChange method is in Session Controller. You can access other properties of your list elements like this (item.CustomerID), as you understand.

teo van kot
  • 12,350
  • 10
  • 38
  • 70
  • The code seems to work, but i am having a problem with the Json data. i get a 500 response, and this error is in the response from the console: invalid json primitive: id – Søren Fritzbøger Mar 09 '15 at 14:30
  • actually whoule your `$.ajax` method is a mess... I add all corrections to answer. So you shold use `dataType: 'json'` and `url` should send data to your controller method. – teo van kot Mar 09 '15 at 14:38
  • Now i'm getting a `syntaxerror unexpected token s` and i have no idea why i'm getting this And the response is: `"SELECT [Extent1].[CustomerID] AS [CustomerID], [Extent1].[Name] AS [Name], [Extent1].[Customer_CustomerID] AS [Customer_CustomerID] FROM [dbo].[Customer] AS [Extent1] WHERE [Extent1].[CustomerID] = @p__linq__0"` – Søren Fritzbøger Mar 09 '15 at 14:43
  • For some reason ASP.NET just won't allow me to return any kind of database data `Uncaught TypeError: Cannot use 'in' operator to search for '64' in System.Collections.Generic.List`1[ProduktWebKort.Models.Customer]` – Søren Fritzbøger Mar 09 '15 at 14:51
  • that's not ASP.NET problem, it problem of ORM that you are using. What DB are you using? And what ORM provider do you using? – teo van kot Mar 09 '15 at 14:56
  • I'm just using the localDB that comes with Visual Studio 2013 – Søren Fritzbøger Mar 09 '15 at 14:58
  • than it's really wierd... Try to create mosc List without get data from db, if it works than you should search for local db issues... Again i repeat this problem is not ASP.NET. – teo van kot Mar 09 '15 at 15:00
  • 1
    You should probably modify the method signature to return an ActionResult, and add `return Json(db.Customers.Where(C => C.CustomerID == id).ToList());`, [as in this question](http://stackoverflow.com/questions/227624/asp-net-mvc-controller-actions-that-return-json-or-partial-html). – mason Mar 09 '15 at 15:14
  • YES! Thanks teo and Mason, changing it to ActionResult and using Json to encode it works. – Søren Fritzbøger Mar 09 '15 at 15:18
  • @SørenFritzbøger I know you got it working with this method and it works okay for ad hoc stuf, but if you need to do a lot of AJAX, you should look into Web API as in my example because it automatically handles content negotiation and the method signatures clearly define the type of content returned by the API call. – mason Mar 09 '15 at 15:25
  • I only need it for a single view, that's why i wanted to avoid looking into Web API @mason – Søren Fritzbøger Mar 09 '15 at 15:29