how to fix “500 internal server error in retrofit and web services” in asp.net web method [closed]

ぐ巨炮叔叔 提交于 2019-12-24 08:28:49

问题


I am trying to insert the record using asp.net web-services from the android platform using retrofit. I have already tried many solutions but not able to get success.

Basically in my asp.net web service code is:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void insertEducationAPI(int user_id, string degree_name, string institute_name, string board_university_name, int year_of_passing, float percentage_cgpa, string specialization)
{

    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        //These headers are handling the "pre-flight" OPTIONS call sent by the browser
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    }

    Education edu = new Education();
    string result = educationModel.addEducation(user_id, degree_name, institute_name, board_university_name, year_of_passing, percentage_cgpa, specialization);
    JavaScriptSerializer js = new JavaScriptSerializer();

    Context.Response.Clear();
    Context.Response.ContentType = "application/json";

    if (result.Equals("complete"))
    {
        edu.err = false;
        edu.err_message = "Inserted success";
    }
    else
    {
        edu.err = true;
        edu.err_message = "Fail";
    }
    Context.Response.Write(js.Serialize(edu));
}

And at android side

API interface:

@Headers({
        "Accept: application/json",
        "Content-Type: application/json"
})
@FormUrlEncoded
@POST("/EducationApi.asmx/insertEducationAPI")
public void insertEducationDetail(@Field("user_id") int user_id, @Field("degree_name") String degree_name, @Field("institute_name") String institute_name, @Field("board_university_name") String board_university_name, @Field("year_of_passing") int year_of_passing, @Field("percentage_cgpa") float percentage_cgpa, @Field("specialization") String specialization, Callback<Education> callback);
}

Method calling;

retro.getService().insertEducationDetail(1, "MCA", "SRIMCA", "UTU", 2015, 85, ".NET", new Callback<Education>() {
        @Override
        public void success(Education education, Response response) {
            Toast.makeText(Dashboard.this, "success", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void failure(RetrofitError error) {
            Toast.makeText(Dashboard.this, error.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });

Error:

I/System.out: [OkHttp] sendRequest<<
D/GraphicBuffer: register, handle(0x87d71180) (w:720 h:1440 s:736 f:0x1 u:b00)
D/Retrofit: <--- HTTP 500 http://192.168.43.25:81/EducationApi.asmx/insertEducationAPI (77ms)
    : HTTP/1.1 500 Internal Server Error
    Cache-Control: private
D/Retrofit: Content-Length: 91
    Content-Type: application/json; charset=utf-8
    Date: Sat, 10 Aug 2019 20:36:09 GMT
D/Retrofit: jsonerror: true
D/Retrofit: Server: Microsoft-IIS/10.0
    X-Android-Received-Millis: 1565469369999
    X-Android-Response-Source: NETWORK 500
    X-Android-Selected-Protocol: http/1.1
    X-Android-Sent-Millis: 1565469369982
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
D/Retrofit: {"Message":"There was an error processing the request.","StackTrace":"","ExceptionType":""}
    <--- END HTTP (91-byte body)

How can I solve this problem?


回答1:


On the Android side your API interface looks incorrect:

@POST("/EducationApi.asmx/addEducationAPI")
public void addEducation(@Body List<Education> education, Callback<Education> callback);

It's not a List<Education> on the server side, just a single Education object, so the definition should probably be:

@POST("/EducationApi.asmx/addEducationAPI")
public void addEducation(@Body Education education, Callback<Education> callback);

== edit ==

Also, you have only decorated your API method with [WebMethod] so it only accepts SOAP+XML input. To be callable with JSON you need to add the [ScriptMethod] decoration, e.g.:

[WebMethod]
[ScriptMethod]
public void addEducationAPI(Education education)
{
    //...
}

Due to security requirements of the [ScriptMethod] attribute (see JSON Hijacking and How ASP.NET AJAX 1.0 Avoids these Attacks) you need to ensure that your Retrofit requests include a Content-Type: application/json header. e.g.:

@Headers("Content-Type: application/json")
@POST("/EducationApi.asmx/addEducationAPI")
public void addEducation(@Body Education education, Callback<Education> callback);

You should also add an Accept: application/json header if Retrofit isn't already doing that for you. e.g.:

@Headers({
    "Accept: application/json",
    "Content-Type: application/json"
})
@POST("/EducationApi.asmx/addEducationAPI")
public void addEducation(@Body Education education, Callback<Education> callback);

Including both of these headers in your requests will allow you to delete your JavaScriptSerializer code, and just return an instance of Education. When using [ScriptMethod] the ASP.NET web service framework will automatically return SOAP+XML for SOAP+XML requests and return JSON for JSON requests.

So a full working example, which also includes the [ScriptService] attribute on the EducationApi class, looks like:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class EducationApi : WebService
{
    EducationModel educationModel = new EducationModel();

    [WebMethod]
    [ScriptMethod]
    public Education addEducationAPI(Education education)
    {
        Education edu = new Education();
        string result = educationModel.addEducation(
            education.user_id,
            education.degree_name,
            education.institute_name,
            education.board_university_name,
            education.year_of_passing,
            education.percentage_cgpa,
            education.specialization);
        if (result.Equals("complete"))
        {
            edu.err = false;
            edu.err_message = "Inserted success";
        }
        else
        {
            edu.err = true;
            edu.err_message = "Fail";
        }
        return edu;
    }
}

And posting data to it with the curl utility:

curl --data '{"education":{"__type":"Education","user_id":1,"degree_name":"MCA","institute_name":"SRIMCA","board_university_name":"UTU","year_of_passing":2015,"specialization":"None","percentage_cgpa":85}}' --header "Content-Type: application/json" --header "Accept: application/json" --trace-ascii - http://127.0.0.1:8080/EducationApi.asmx/addEducationAPI

Returns the JSON result:

{"d":{"user_id":0,"degree_name":null,"institute_name":null,"board_university_name":null,"year_of_passing":0,"specialization":null,"percentage_cgpa":0,"err":false,"err_message":"Inserted success"}}


来源:https://stackoverflow.com/questions/57439576/how-to-fix-500-internal-server-error-in-retrofit-and-web-services-in-asp-net-w

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!