Ошибка сервера в приложении web api

After publishing Web API to IIS, which is a child of an AngularJs IIS site, I can reach ‘https://localhost/api’ and see all endpoints; but when I try to reach some specific endpoint with a GET request, I get an error

Server Error in ‘/’ Application

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

[RoutePrefix("api/branches")]
public class BranchesController : ApiBaseController
{
    [HttpGet]
    [Route("getBranches")]
    public async Task<JsonResult<List<BranchDto>>> GetActiveBranches()
    {
        var branches = new List<BranchDto>();

        var models = await WarehouseUnitOfWork.BranchRepository.GetActiveBranches();
        if (models != null && models.Count > 0)
        {
            branches.AddRange(AutoMapper.Mapper.Map<List<Branch>, List<BranchDto>>(models));
        }

        return Json(branches, new JsonSerializerSettings
        {
            ContractResolver = new WarehouseCustomContractResolver()
        });
    }
}

Any ideas how to solve this?

User387015 posted

l have wrote a post api to create users

[HttpPost]
    public User CreateUser(User user)
    {
        //User jsonToObject = JsonConvert.DeserializeObject<User>(user.ToString());
        if (ModelState.IsValid)
        {
            db.users.Add(user);
            db.SaveChanges();
        }
        else                    
        {
            throw new Exception("The posted Model is not valid");
        }

      return user;

    }

when l test on postman using this json

{
"FirstName":"Test",
"LastName":"Test",
"Email":"test@gmail.com",
"Password":"Testerrr123"
}

l get 500 internal server error.Below is my model to give more insight

public class User
{
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }

    [Required]
    public string Email { get; set; }

    [Required]
    public string Password { get; set; }


    [NotMapped]
    [Compare("Password")]
    public string ConfirmPassword { get; set; }
    public int UserType { get; set; }
    public DateTime Date_Created { get; set; }
}

Apologies on asking this here but this is suppose to serve as my mobile app backend..thanks ahead.

После публикации веб-API в IIS, который является дочерним по отношению к сайту IIS AngularJs, я могу перейти на https://localhost/api и увидеть все конечные точки; но когда я пытаюсь достичь определенной конечной точки с помощьюGET запрос, я получаю сообщение об ошибке

Ошибка сервера в приложении

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

[RoutePrefix("api/branches")]
public class BranchesController : ApiBaseController
{
    [HttpGet]
    [Route("getBranches")]
    public async Task<JsonResult<List<BranchDto>>> GetActiveBranches()
    {
        var branches = new List<BranchDto>();

        var models = await WarehouseUnitOfWork.BranchRepository.GetActiveBranches();
        if (models != null && models.Count > 0)
        {
            branches.AddRange(AutoMapper.Mapper.Map<List<Branch>, List<BranchDto>>(models));
        }

        return Json(branches, new JsonSerializerSettings
        {
            ContractResolver = new WarehouseCustomContractResolver()
        });
    }
}

Есть идеи, как это решить?

2019-10-06 07:17

1
ответ

Решением для моего случая было развертывание Frontend на основном сайте IIS и создание внутри него приложения с именем v1для Backend. Затем в моем angularJS я определил приложение Production, чтобы отправлять HTTP-запросы на/v1/api вместо того /api.

https://i.stack.imgur.com/j6zjO.png

2020-07-26 10:01

I have concerns on the way that we returns errors to client.

Do we return error immediately by throwing HttpResponseException when we get an error:

public void Post(Customer customer)
{
    if (string.IsNullOrEmpty(customer.Name))
    {
        throw new HttpResponseException("Customer Name cannot be empty", HttpStatusCode.BadRequest) 
    }
    if (customer.Accounts.Count == 0)
    {
         throw new HttpResponseException("Customer does not have any account", HttpStatusCode.BadRequest) 
    }
}

Or we accumulate all errors then send back to client:

public void Post(Customer customer)
{
    List<string> errors = new List<string>();
    if (string.IsNullOrEmpty(customer.Name))
    {
        errors.Add("Customer Name cannot be empty"); 
    }
    if (customer.Accounts.Count == 0)
    {
         errors.Add("Customer does not have any account"); 
    }
    var responseMessage = new HttpResponseMessage<List<string>>(errors, HttpStatusCode.BadRequest);
    throw new HttpResponseException(responseMessage);
}

This is just a sample code, it does not matter either validation errors or server error, I just would like to know the best practice, the pros and cons of each approach.

Guido Leenders's user avatar

asked May 24, 2012 at 7:00

cuongle's user avatar

3

For me I usually send back an HttpResponseException and set the status code accordingly depending on the exception thrown and if the exception is fatal or not will determine whether I send back the HttpResponseException immediately.

At the end of the day it’s an API sending back responses and not views, so I think it’s fine to send back a message with the exception and status code to the consumer. I currently haven’t needed to accumulate errors and send them back as most exceptions are usually due to incorrect parameters or calls etc.

An example in my app is that sometimes the client will ask for data, but there isn’t any data available so I throw a custom NoDataAvailableException and let it bubble to the Web API app, where then in my custom filter which captures it sending back a relevant message along with the correct status code.

I am not 100% sure on what’s the best practice for this, but this is working for me currently so that’s what I’m doing.

Update:

Since I answered this question a few blog posts have been written on the topic:

https://weblogs.asp.net/fredriknormen/asp-net-web-api-exception-handling

(this one has some new features in the nightly builds)
https://learn.microsoft.com/archive/blogs/youssefm/error-handling-in-asp-net-webapi

Update 2

Update to our error handling process, we have two cases:

  1. For general errors like not found, or invalid parameters being passed to an action we return a HttpResponseException to stop processing immediately. Additionally for model errors in our actions we will hand the model state dictionary to the Request.CreateErrorResponse extension and wrap it in a HttpResponseException. Adding the model state dictionary results in a list of the model errors sent in the response body.

  2. For errors that occur in higher layers, server errors, we let the exception bubble to the Web API app, here we have a global exception filter which looks at the exception, logs it with ELMAH and tries to make sense of it setting the correct HTTP status code and a relevant friendly error message as the body again in a HttpResponseException. For exceptions that we aren’t expecting the client will receive the default 500 internal server error, but a generic message due to security reasons.

Update 3

Recently, after picking up Web API 2, for sending back general errors we now use the IHttpActionResult interface, specifically the built in classes for in the System.Web.Http.Results namespace such as NotFound, BadRequest when they fit, if they don’t we extend them, for example a NotFound result with a response message:

public class NotFoundWithMessageResult : IHttpActionResult
{
    private string message;

    public NotFoundWithMessageResult(string message)
    {
        this.message = message;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage(HttpStatusCode.NotFound);
        response.Content = new StringContent(message);
        return Task.FromResult(response);
    }
}

Callum Watkins's user avatar

answered May 24, 2012 at 9:27

gdp's user avatar

gdpgdp

7,97210 gold badges42 silver badges62 bronze badges

9

ASP.NET Web API 2 really simplified it. For example, the following code:

public HttpResponseMessage GetProduct(int id)
{
    Product item = repository.Get(id);
    if (item == null)
    {
        var message = string.Format("Product with id = {0} not found", id);
        HttpError err = new HttpError(message);
        return Request.CreateResponse(HttpStatusCode.NotFound, err);
    }
    else
    {
        return Request.CreateResponse(HttpStatusCode.OK, item);
    }
}

returns the following content to the browser when the item is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Date: Thu, 09 Aug 2012 23:27:18 GMT
Content-Length: 51

{
  "Message": "Product with id = 12 not found"
}

Suggestion: Don’t throw HTTP Error 500 unless there is a catastrophic error (for example, WCF Fault Exception). Pick an appropriate HTTP status code that represents the state of your data. (See the apigee link below.)

Links:

  • Exception Handling in ASP.NET Web API (asp.net)
    and
  • RESTful API Design: what about errors? (apigee.com)

BrianS's user avatar

BrianS

13.1k15 gold badges61 silver badges123 bronze badges

answered Mar 1, 2014 at 0:10

Manish Jain's user avatar

Manish JainManish Jain

9,5495 gold badges38 silver badges44 bronze badges

12

It looks like you’re having more trouble with Validation than errors/exceptions so I’ll say a bit about both.

Validation

Controller actions should generally take Input Models where the validation is declared directly on the model.

public class Customer
{ 
    [Require]
    public string Name { get; set; }
}

Then you can use an ActionFilter that automatically sends validation messages back to the client.

public class ValidationActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var modelState = actionContext.ModelState;

        if (!modelState.IsValid) {
            actionContext.Response = actionContext.Request
                 .CreateErrorResponse(HttpStatusCode.BadRequest, modelState);
        }
    }
} 

For more information about this check out http://ben.onfabrik.com/posts/automatic-modelstate-validation-in-aspnet-mvc

Error handling

It’s best to return a message back to the client that represents the exception that happened (with relevant status code).

Out of the box you have to use Request.CreateErrorResponse(HttpStatusCode, message) if you want to specify a message. However, this ties the code to the Request object, which you shouldn’t need to do.

I usually create my own type of «safe» exception that I expect the client would know how to handle and wrap all others with a generic 500 error.

Using an action filter to handle the exceptions would look like this:

public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        var exception = context.Exception as ApiException;
        if (exception != null) {
            context.Response = context.Request.CreateErrorResponse(exception.StatusCode, exception.Message);
        }
    }
}

Then you can register it globally.

GlobalConfiguration.Configuration.Filters.Add(new ApiExceptionFilterAttribute());

This is my custom exception type.

using System;
using System.Net;

namespace WebApi
{
    public class ApiException : Exception
    {
        private readonly HttpStatusCode statusCode;

        public ApiException (HttpStatusCode statusCode, string message, Exception ex)
            : base(message, ex)
        {
            this.statusCode = statusCode;
        }

        public ApiException (HttpStatusCode statusCode, string message)
            : base(message)
        {
            this.statusCode = statusCode;
        }

        public ApiException (HttpStatusCode statusCode)
        {
            this.statusCode = statusCode;
        }

        public HttpStatusCode StatusCode
        {
            get { return this.statusCode; }
        }
    }
}

An example exception that my API can throw.

public class NotAuthenticatedException : ApiException
{
    public NotAuthenticatedException()
        : base(HttpStatusCode.Forbidden)
    {
    }
}

Christian Casutt's user avatar

answered Mar 4, 2014 at 5:30

Daniel Little's user avatar

Daniel LittleDaniel Little

16.9k12 gold badges69 silver badges93 bronze badges

3

You can throw a HttpResponseException

HttpResponseMessage response = 
    this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "your message");
throw new HttpResponseException(response);

answered Mar 4, 2014 at 5:15

tartakynov's user avatar

tartakynovtartakynov

2,7583 gold badges26 silver badges23 bronze badges

1

If you are using ASP.NET Web API 2, the easiest way is to use the ApiController Short-Method. This will result in a BadRequestResult.

return BadRequest("message");

answered Mar 22, 2018 at 12:22

Fabian von Ellerts's user avatar

1

For Web API 2 my methods consistently return IHttpActionResult so I use…

public IHttpActionResult Save(MyEntity entity)
{
    ....
    if (...errors....)
        return ResponseMessage(
            Request.CreateResponse(
                HttpStatusCode.BadRequest, 
                validationErrors));

    // otherwise success
    return Ok(returnData);
}

answered Jan 20, 2016 at 1:53

Mick's user avatar

MickMick

6,4374 gold badges51 silver badges67 bronze badges

1

You can use custom ActionFilter in Web Api to validate model:

public class DRFValidationFilters : ActionFilterAttribute
{

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!actionContext.ModelState.IsValid)
        {
            actionContext.Response = actionContext.Request
                .CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);

            //BadRequest(actionContext.ModelState);
        }
    }

    public override Task OnActionExecutingAsync(HttpActionContext actionContext,
        CancellationToken cancellationToken)
    {

        return Task.Factory.StartNew(() =>
        {
            if (!actionContext.ModelState.IsValid)
            {
                actionContext.Response = actionContext.Request
                    .CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
            }
        });
    }

    public class AspirantModel
    {
        public int AspirantId { get; set; }
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public string AspirantType { get; set; }
        [RegularExpression(@"^(?([0-9]{3}))?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$",
            ErrorMessage = "Not a valid Phone number")]
        public string MobileNumber { get; set; }
        public int StateId { get; set; }
        public int CityId { get; set; }
        public int CenterId { get; set; }


        [HttpPost]
        [Route("AspirantCreate")]
        [DRFValidationFilters]
        public IHttpActionResult Create(AspirantModel aspirant)
        {
            if (aspirant != null)
            {

            }
            else
            {
                return Conflict();
            }

            return Ok();
        }
    }
}

Register CustomAttribute class in webApiConfig.cs
config.Filters.Add(new DRFValidationFilters());

Metro Smurf's user avatar

Metro Smurf

37.1k20 gold badges108 silver badges140 bronze badges

answered Mar 18, 2016 at 9:40

LokeshChikkala's user avatar

Building up upon Manish Jain‘s answer (which is meant for Web API 2 which simplifies things):

1) Use validation structures to response as many validation errors as possible. These structures can also be used to response to requests coming from forms.

public class FieldError
{
    public String FieldName { get; set; }
    public String FieldMessage { get; set; }
}

// a result will be able to inform API client about some general error/information and details information (related to invalid parameter values etc.)
public class ValidationResult<T>
{
    public bool IsError { get; set; }

    /// <summary>
    /// validation message. It is used as a success message if IsError is false, otherwise it is an error message
    /// </summary>
    public string Message { get; set; } = string.Empty;

    public List<FieldError> FieldErrors { get; set; } = new List<FieldError>();

    public T Payload { get; set; }

    public void AddFieldError(string fieldName, string fieldMessage)
    {
        if (string.IsNullOrWhiteSpace(fieldName))
            throw new ArgumentException("Empty field name");

        if (string.IsNullOrWhiteSpace(fieldMessage))
            throw new ArgumentException("Empty field message");

        // appending error to existing one, if field already contains a message
        var existingFieldError = FieldErrors.FirstOrDefault(e => e.FieldName.Equals(fieldName));
        if (existingFieldError == null)
            FieldErrors.Add(new FieldError {FieldName = fieldName, FieldMessage = fieldMessage});
        else
            existingFieldError.FieldMessage = $"{existingFieldError.FieldMessage}. {fieldMessage}";

        IsError = true;
    }

    public void AddEmptyFieldError(string fieldName, string contextInfo = null)
    {
        AddFieldError(fieldName, $"No value provided for field. Context info: {contextInfo}");
    }
}

public class ValidationResult : ValidationResult<object>
{

}

2) Service layer will return ValidationResults, regardless of operation being successful or not. E.g:

    public ValidationResult DoSomeAction(RequestFilters filters)
    {
        var ret = new ValidationResult();

        if (filters.SomeProp1 == null) ret.AddEmptyFieldError(nameof(filters.SomeProp1));
        if (filters.SomeOtherProp2 == null) ret.AddFieldError(nameof(filters.SomeOtherProp2 ), $"Failed to parse {filters.SomeOtherProp2} into integer list");

        if (filters.MinProp == null) ret.AddEmptyFieldError(nameof(filters.MinProp));
        if (filters.MaxProp == null) ret.AddEmptyFieldError(nameof(filters.MaxProp));


        // validation affecting multiple input parameters
        if (filters.MinProp > filters.MaxProp)
        {
            ret.AddFieldError(nameof(filters.MinProp, "Min prop cannot be greater than max prop"));
            ret.AddFieldError(nameof(filters.MaxProp, "Check"));
        }

        // also specify a global error message, if we have at least one error
        if (ret.IsError)
        {
            ret.Message = "Failed to perform DoSomeAction";
            return ret;
        }

        ret.Message = "Successfully performed DoSomeAction";
        return ret;
    }

3) API Controller will construct the response based on service function result

One option is to put virtually all parameters as optional and perform custom validation which return a more meaningful response. Also, I am taking care not to allow any exception to go beyond the service boundary.

    [Route("DoSomeAction")]
    [HttpPost]
    public HttpResponseMessage DoSomeAction(int? someProp1 = null, string someOtherProp2 = null, int? minProp = null, int? maxProp = null)
    {
        try
        {
            var filters = new RequestFilters 
            {
                SomeProp1 = someProp1 ,
                SomeOtherProp2 = someOtherProp2.TrySplitIntegerList() ,
                MinProp = minProp, 
                MaxProp = maxProp
            };

            var result = theService.DoSomeAction(filters);
            return !result.IsError ? Request.CreateResponse(HttpStatusCode.OK, result) : Request.CreateResponse(HttpStatusCode.BadRequest, result);
        }
        catch (Exception exc)
        {
            Logger.Log(LogLevel.Error, exc, "Failed to DoSomeAction");
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, new HttpError("Failed to DoSomeAction - internal error"));
        }
    }

answered Dec 19, 2016 at 14:32

Alexei - check Codidact's user avatar

Use the built in «InternalServerError» method (available in ApiController):

return InternalServerError();
//or...
return InternalServerError(new YourException("your message"));

answered Aug 4, 2017 at 15:03

Rusty's user avatar

RustyRusty

1091 silver badge9 bronze badges

Welcome to 2022! Now we have other answers in .NET (since ASP.NET Core 2.1). Look at this article: Using the ProblemDetails Class in ASP.NET Core Web API, where the author explains the following best practices:

  1. How to implement standard IETF RFC 7807, which defines a «problem detail» as a way to carry machine-readable details of errors in an HTTP response to avoid the need to define new error response formats for HTTP APIs.
  2. How model validations use the ProblemDetails class to populate a list of validation errors — the direct answer to the question for a general rule, whether to break processing after the first error.

As a teaser, this is how the JSON output looks if we use ProductDetails and multiple errors:

enter image description here

answered Oct 5, 2022 at 11:01

Gerard Jaryczewski's user avatar

Some of these answers seem to be relics of the past. I’ve found the solution below to be simple and work well. This is in .NET 6 for a Web API derived from ControllerBase.

Rather than throwing exceptions, you can directly return the various HTTP response codes as objects, along with an exact error message:

using Microsoft.AspNetCore.Mvc;

[ApiController]
public class MyWebApiController : ControllerBase
{
    [HttpPost]
    public IActionResult Process(Customer customer)
    {
        if (string.IsNullOrEmpty(customer.Name))
            return BadRequest("Customer Name cannot be empty");

        if (!Customers.Find(customer))
            return NotFound("Customer does not have any account");

        // After validating inputs, core logic goes here...

        return Ok(customer.ID);  // or simply "return Ok()" if not returning data
    }
}

See a list of error codes available here.

As for when to return the errors (OP’s question), it depends on the requirement. Returning errors as they happen means you avoid the overhead of additional processing, but then the client has to make repeated calls to get all the errors. Consider the server viewpoint also, as it may cause undesirable program behavior to continue server-side processing when an error has occurred.

answered Sep 1, 2022 at 18:56

Tawab Wakil's user avatar

Tawab WakilTawab Wakil

1,64718 silver badges33 bronze badges

Just to update on the current state of ASP.NET WebAPI. The interface is now called IActionResult and implementation hasn’t changed much:

[JsonObject(IsReference = true)]
public class DuplicateEntityException : IActionResult
{        
    public DuplicateEntityException(object duplicateEntity, object entityId)
    {
        this.EntityType = duplicateEntity.GetType().Name;
        this.EntityId = entityId;
    }

    /// <summary>
    ///     Id of the duplicate (new) entity
    /// </summary>
    public object EntityId { get; set; }

    /// <summary>
    ///     Type of the duplicate (new) entity
    /// </summary>
    public string EntityType { get; set; }

    public Task ExecuteResultAsync(ActionContext context)
    {
        var message = new StringContent($"{this.EntityType ?? "Entity"} with id {this.EntityId ?? "(no id)"} already exist in the database");

        var response = new HttpResponseMessage(HttpStatusCode.Ambiguous) { Content = message };

        return Task.FromResult(response);
    }

    #endregion
}

answered May 10, 2016 at 7:51

Thomas Hagström's user avatar

Thomas HagströmThomas Hagström

4,3111 gold badge21 silver badges27 bronze badges

2

Try this

[HttpPost]
public async Task<ActionResult<User>> PostUser(int UserTypeId, User user)
{
  if (somethingFails)
  {
    // Return the error message like this.
    return new BadRequestObjectResult(new
    {
      message = "Something is not working here"
    });
  }

  return ok();
}

CinCout's user avatar

CinCout

9,46411 gold badges49 silver badges67 bronze badges

answered Dec 17, 2021 at 18:29

Zablon's user avatar

ZablonZablon

1171 silver badge4 bronze badges

5

For those errors where modelstate.isvalid is false, I generally send the error as it is thrown by the code. Its easy to understand for the developer who is consuming my service. I generally send the result using below code.

     if(!ModelState.IsValid) {
                List<string> errorlist=new List<string>();
                foreach (var value in ModelState.Values)
                {
                    foreach(var error in value.Errors)
                    errorlist.Add( error.Exception.ToString());
                    //errorlist.Add(value.Errors);
                }
                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.BadRequest,errorlist);}

This sends the error to the client in below format which is basically a list of errors:

    [  
    "Newtonsoft.Json.JsonReaderException: **Could not convert string to integer: abc. Path 'Country',** line 6, position 16.rn   
at Newtonsoft.Json.JsonReader.ReadAsInt32Internal()rn   
at Newtonsoft.Json.JsonTextReader.ReadAsInt32()rn   
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter, Boolean inArray)rn   
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)",

       "Newtonsoft.Json.JsonReaderException: **Could not convert string to integer: ab. Path 'State'**, line 7, position 13.rn   
at Newtonsoft.Json.JsonReader.ReadAsInt32Internal()rn   
at Newtonsoft.Json.JsonTextReader.ReadAsInt32()rn   
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter, Boolean inArray)rn   
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)"
    ]

Sylvain's user avatar

Sylvain

19.1k23 gold badges94 silver badges145 bronze badges

answered Jan 19, 2016 at 10:41

Ashish Sahu's user avatar

2

Вопрос:

Я вызвал метод HttpPost от контроллера к веб-API. Для других методов ответ в порядке, и метод работает хорошо, за исключением описанного ниже метода, указывающего ошибку

{StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Pragma: no-cache
Connection: Close
Cache-Control: no-cache
Date: Fri, 16 Aug 2013 09:49:25 GMT
Server: ASP.NET
Server: Development
Server: Server/10.0.0.0
X-AspNet-Version: 4.0.30319
Content-Length: 1855
Content-Type: application/json; charset=utf-8
Expires: -1
}}

Мой метод

public int CustomerRegistration(CustomerRequestResponse req)
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["ServerAddress"].ToString());
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
Uri gizmoUri = null;
var Response = client.PostAsJsonAsync("api/MyAccount/CustomerRegistration", req).Result;
int result = 0;
if (Response.IsSuccessStatusCode)
{
gizmoUri = Response.Headers.Location;
result = Response.Content.ReadAsAsync<Int32>().Result;
}
return result;
}
catch { throw; }
}

Как я могу определить, где ошибка в моем коде. Какие-либо предложения??

EDIT :: Прослеживается ошибка с указанием “System.Net.Http.ObjectContent”

{Method: POST, RequestUri: 'http://localhost:56003/api/MyAccount/CustomerRegistration', Version: 1.1, Content: System.Net.Http.ObjectContent'1[[ServiceEntities.MyAccount.CustomerRequestResponse, ServiceEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Headers:
{
Accept: application/json
Content-Type: application/json; charset=utf-8
Content-Length: 495
}}

Любые предложения по его исправлению.?

EDIT1:

</Message><ExceptionMessage>No MediaTypeFormatter is available to read an object of type 'CustomerRequestResponse' from content with media type 'text/plain'.</ExceptionMessage>

Ответ №1

Первое, что я хотел бы сделать, это проверить, что запрос клиента выполняется правильно – правильный URL-адрес, заголовки, тело. Для этого вы можете включить fiddler в качестве прокси-сервера в своем приложении. Добавьте этот раздел в свой Web.config и попробуйте снова запустить код с открытым файлом – теперь вы сможете увидеть запрос в скрипаче:

<system.net>
<defaultProxy>
<proxy  proxyaddress="http://127.0.0.1:8888" />
</defaultProxy>
</system.net>

Если запрос в порядке, убедитесь, что сервер, к которому вы пытаетесь подключиться, фактически запущен и работает, и он дает вам правильный ответ с правильными заголовками.

Я подозреваю, что этого должно быть достаточно, чтобы идентифицировать проблему.

КСТАТИ: В реальной жизни делает ваш catch блок сделать что – то полезное на самом деле? Чтобы сделать его более полезным, чем сейчас, вы можете добавить некоторые log4net-протоколы, которые, вероятно, также помогут выявить любые будущие проблемы.

Ответ №2

Я думаю, что есть ошибка при обработке данных о действии MyAccountController CustomerRegistration. Я предпочитаю, чтобы вы проверяли свой контроллер, если произошла ошибка при его прогрессе.

Ответ №3

Если у вас есть стандартная установка DLL (backend) и Web Script (frontend: например, ashx или aspx и т.д.), Тогда легко забыть загрузить (на сервер) изменения, внесенные в веб-скрипт. Я получил ошибку, подобную этой, однако она ушла, когда я убедился, что весь мой код/​​сценарий синхронизирован и загружен на сервер.

Понравилась статья? Поделить с друзьями:
  • Ошибка сервера в приложении ssturf
  • Ошибка сервера в приложении reports
  • Ошибка сервера в приложении rdweb
  • Ошибка сервера в приложении play market
  • Ошибка сервера в приложении owa