简体   繁体   中英

Calling Web API from code and website

First off, I'm using C# 4.0 as my coding language. I believe I saw some answers where 4.5 has introduced some methods that could make this a lot easier, but it's not my call to change frameworks.

I'm creating an MVC4 WebApi that will be consumed by both websites and C# code (in another project). Typically when calling this from JavaScript, I'd do it like so:

$.ajax({
    dataType: 'text',
    url: '//localhost:56814/corporations/1/divisions',
    type: 'POST',
    data: {"Divisions":[{"Name":"In Store"},{"Name":"Online"}]}
}).done(function (msg) {
    alert(msg);
}).fail(function (jqXHR, textStatus) {
    alert('Request failed: ' + textStatus);
});

Then in my server side code, I would just have my model as a parameter:

[HttpPost]
public HttpResponseMessage Divisions(int id, DivisionCollectionModel model) {

}

That model would be defined as such:

public class DivisionCollectionModel {
    public IEnumerable<DivisionModel> Divisions { get; set; }
}

public class DivisionModel {
    public string Name { get; set; }
}

Now when I tried to test calling this method from my code, the only way I could find to get the call to work was like this:

public static void TestWebApiPost() {
    var divs = new DivisionCollectionModel {
        Divisions = new DivisionModel[] {
            new DivisionModel {
                Name = "In Store"
            },
            new DivisionModel {
                Name = "Online"
            }
        }
    };

    using (var client = new HttpClient()) {
        var content = JsonConvert.SerializeObject(divs);
        var response = client.PostAsync("http://localhost:56814/corporations/1/divisions", new StringContent(content)).Result;
        Console.WriteLine(response.ToString());
    }
}

Unfortunately, that was unable to find the URL as the content of my message was a string instead of the object.

Is there a method call, or version of HttpContent that I'm missing here in how I'm sending the data over that would allow me to send it as an object instead of a string?

I reworked the Api method above to accept HttpRequestMessage as the second parameter, figuring this would allow me to use request.Content.ReadAsStringAsync().Result to get the object from the request. This worked great for calling it from a C# client. However, when I tried to call it using a JavaScript object, I got the following as my Result :

"Divisions%5B0%5D%5BName%5D=In+Store&Divisions%5B1%5D%5BName%5D=Online"

I tried running that through System.Web.HttpUtility.HtmlDecode() and System.Net.WebUtility.HtmlDecode() , but both did nothing to change the encoding done on that string.

Update I realized after writing this that the string that I'm trying to convert is a Url, not an Html string. I then tried using System.Web.HttpUtility.UrlDecode() , and that gave me this:

"Divisions[0][Name]=In Store&Divisions[1][Name]=Online"

Unfortunately, that also throws an exception when trying to run it through Newtonsoft.Json.JsonConvert.DeserializeObject<DivisionCollectionModel>() .

Clearer problem set I think that it would be better to fix the way that the call is made from the C# client so that I don't have to parse the HttpRequestMessage , and allow the Controller to do that "heavy lifting" for me. However, if there is not a way to send my data over as an object instead of a string in C# 4.0, then the easiest solution would be to just have the JavaScript client send over a string instead of an object.

Am I missing something in my C# client code?

更改ajax数据类型dataType:'json',

OK, so I found what I was missing with the C# client in 4.0 to get this to send over as a JSON object. This is the updated client:

public static void TestWebApiPost() {
    var divs = new DivisionCollectionModel {
        Divisions = new DivisionModel[] {
            new DivisionModel {
                Name = "In Store"
            },
            new DivisionModel {
                Name = "Online"
            }
        }
    };

    using (var client = new HttpClient()) {
        var content = JsonConvert.SerializeObject(divs);
        var response = client.PostAsync("http://localhost:56814/corporations/1/divisions", 
                new StringContent(content, Encoding.UTF8, "application/json")).Result;
        Console.WriteLine(response.ToString());
    }
}

Using the StringContent overload that adds in the Encoding, and media type will have it send over as a JSON object. With those changes in place, you can now successfully utilize the same parameter signature that requires just your Model in your WebApi action method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM