Search code examples
returnclientodataaction

Return data from OData Action using OData Client


I am testing the OData Action using ODataActionsSample, which is downloaded from http://aspnet.codeplex.com/sourcecontrol/latest#Samples/WebApi/OData/v4/ODataActionsSample/ODataActionsSample/, as a server and calling the "CheckOut" action which is,

[HttpPost]
    public IHttpActionResult CheckOut(int key)
    {
        var movie = _db.Movies.FirstOrDefault(m => m.ID == key);
        if (movie == null)
        {
            return BadRequest(ModelState);
        }

        if (!TryCheckoutMovie(movie))
        {
            return BadRequest("The movie is already checked out.");
        }

        return Ok(movie);
    }

The action returns the movie with updated "DueDate" proprety in the sample program which is calling the action from javascript as below:

// Invoke "checkout" or "return" action. Both actions take no parameter data.
    function invokeAction(url) {
        ajaxRequest("post", url)
            .done(function (updated) {
                updateMovie(updated);
            })
            .fail(function (jqXHR, textStatus, errorThrown) {

                //parent.errorMessage(errorThrown);
                parent.errorMessage(url);
            });
    }

    self.update(data);

    // Update the model with new data from the server.
    function updateMovie(data) {
        var dueDate = data.DueDate ? new Date(data.DueDate) : null;
        self.dueDate(dueDate);

        if (data["#ODataActionsSample.Models.CheckOut"]) {
            self.checkoutUrl(data["#ODataActionsSample.Models.CheckOut"].target);
        }
        else {
            self.checkoutUrl(null);
        }
        if (data["#ODataActionsSample.Models.Return"]) {
            self.returnMovieUrl(data["#ODataActionsSample.Models.Return"].target);
        }
        else {
            self.returnMovieUrl(null);
        }
    }

However, the call from OData Client returns the movie without the DueDate updated. The client code is as below:

string serviceUri = "http://localhost:44221/OData/";

        var container = new Container(new Uri(serviceUri));

        var movieQuery = from movie in container.Movies select movie;

        DataServiceCollection<ODataActionsClient.Movie> trackedMovies = new DataServiceCollection<ODataActionsClient.Movie>(movieQuery, TrackingMode.AutoChangeTracking, "Movies",null,null);

        var myMovie = trackedMovies[0];

        try
        {

            var checkouttedMovie = myMovie.CheckOut().GetValue();   

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.InnerException.ToString());
        }

What is wrong with my code in the client side ?


Solution

  • The default value for merge option is AppendOnly : No current values are modified.

    OverwriteChanges : All current values are overwritten with current store values, regardless of whether they have been changed.

    PreserveChanges: Current values that have been changed are not modified, but any unchanged values are updated with the current store values. No changes are lost in this merge.

    So you have to decide which option you want to achieve, in this case I think OverwriteChanges is good enough. FYI : https://msdn.microsoft.com/en-us/library/system.data.objects.mergeoption(v=vs.110).aspx