最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Return JSON instead of XML from web service using Ajax while 'contentType' is 'false&#3

programmeradmin4浏览0评论

I made an AJAX call to send an image file to one of my web service (.asmx) methods. Everything's okay, but the problem is that the web service returns XML instead of JSON because I HAVE TO set 'contentType' to 'false', otherwise file can't be sent. (If I set contentType to application/json; charset=utf-8, it returns JSON but I can't do that because I'm sending a file.)

This is my JavaScript:

function setAvatar(imageFile, successCallback) {
var formData = new FormData();
formData.append("UploadedAvatar", imageFile);
$.ajax({
    type: "POST",
    url: "/Services/UserService.asmx/SetAvatar",
    contentType: false,
    processData: false,
    dataType: 'json',
    data: formData,
    success: function (result) {
        alert(result.d);
        alert(result.d.IsSuccessful);
        if (typeof successCallback === 'function')
            successCallback(result);
    }
});

And the web service method:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public Result SetAvatar()
{
    HttpPostedFile postedFile = HttpContext.Current.Request.Files["UploadedAvatar"];
    Image avatar = Image.FromStream(postedFile.InputStream, true, true);
    avatar = new Bitmap(avatar, new Size(150, 150));
    avatar.Save(Path.Combine(path, $"Avatar-Small.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);

    return new Result(true, Messages.AvatarSavedSuccessfully);
}

I made an AJAX call to send an image file to one of my web service (.asmx) methods. Everything's okay, but the problem is that the web service returns XML instead of JSON because I HAVE TO set 'contentType' to 'false', otherwise file can't be sent. (If I set contentType to application/json; charset=utf-8, it returns JSON but I can't do that because I'm sending a file.)

This is my JavaScript:

function setAvatar(imageFile, successCallback) {
var formData = new FormData();
formData.append("UploadedAvatar", imageFile);
$.ajax({
    type: "POST",
    url: "/Services/UserService.asmx/SetAvatar",
    contentType: false,
    processData: false,
    dataType: 'json',
    data: formData,
    success: function (result) {
        alert(result.d);
        alert(result.d.IsSuccessful);
        if (typeof successCallback === 'function')
            successCallback(result);
    }
});

And the web service method:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public Result SetAvatar()
{
    HttpPostedFile postedFile = HttpContext.Current.Request.Files["UploadedAvatar"];
    Image avatar = Image.FromStream(postedFile.InputStream, true, true);
    avatar = new Bitmap(avatar, new Size(150, 150));
    avatar.Save(Path.Combine(path, $"Avatar-Small.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);

    return new Result(true, Messages.AvatarSavedSuccessfully);
}
Share Improve this question edited Apr 30, 2018 at 13:39 Nkosi 248k38 gold badges465 silver badges499 bronze badges asked Apr 28, 2018 at 7:36 AradArad 12.9k11 gold badges68 silver badges92 bronze badges 3
  • See my answer here. You're trying to return an object but it must be serialized first. You will probably be able to remove contentType after that and go with the default setting. – wazz Commented Apr 29, 2018 at 2:44
  • @wazz That didn't help me – Arad Commented Apr 30, 2018 at 9:57
  • See this stackoverflow./questions/42360139/…, make sure you have options.RespectBrowserAcceptHeader = true;, so that the return type is based on the Accept header – Tarun Lalwani Commented Apr 30, 2018 at 12:13
Add a ment  | 

3 Answers 3

Reset to default 5 +25

Set the Accept header when making the request to expect JSON

$.ajax({
    type: "POST",
    url: "/Services/UserService.asmx/SetAvatar",
    headers: { //SET ACCEPT HEADER
        Accept : "application/json; charset=utf-8",
    },  
    contentType: false,
    processData: false,
    dataType: 'json',
    data: formData,
    success: function (result) {
        alert(result.d);
        alert(result.d.IsSuccessful);
        if (typeof successCallback === 'function')
            successCallback(result);
    }
});

On the server side, using Json.Net you can serialize the result

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string SetAvatar() {
    HttpPostedFile postedFile = HttpContext.Current.Request.Files["UploadedAvatar"];
    Image avatar = Image.FromStream(postedFile.InputStream, true, true);
    avatar = new Bitmap(avatar, new Size(150, 150));
    avatar.Save(Path.Combine(path, $"Avatar-Small.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);

    var result = new Result(true, Messages.AvatarSavedSuccessfully);
    return JsonConvert.SerializeObject(result);
}

This should allow the response to be in the desired type

After beating my head against the wall for many days, I finally figured out the solution which belongs to Ajay, here.

While nothing else has helped me, I used this and it worked perfectly:

  1. Change the return type of your method to void.

  2. And then instead of writing the return statement in your method, you need to do this to return a value:

    Context.Response.ContentType = "application/json; charset=utf-8";
    Context.Response.Write(new JavaScriptSerializer().Serialize(new YourData()));
    
  3. After that you can easily get the result using the success event of the Ajax call:

    success: function (result) {
        alert(result.Property); // Note: Don't use result.d here
    }
    

You need to update your .NET code and add options.RespectBrowserAcceptHeader = true

services
    .AddMvc(options => {
        options.RespectBrowserAcceptHeader = true;
    })
    //support application/xml
    .AddXmlDataContractSerializerFormatters()
    //support application/json
    .AddJsonOptions(options => {
        // Force Camel Case to JSON
        options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    });

The dataType: 'json' will automatically add the Accept header as below

"accept":"application/json, text/javascript, */*; q=0.01"

If you specifically want just application/json, then you need to add below to your ajax options

headers: {
  Accept : "application/json; charset=utf-8"
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论