Skip to content

Web API 오류 해결

JaeYeonLee0621 edited this page Aug 19, 2018 · 9 revisions

Web API 오류 해결

Version 호환성 문제

  1. MAC에서 Project 와 Library를 생성하였을 때 Project와 Library의 Version이 맞지 않아 고생했다.

이때 해결방법은 Visual Studio Code Editor를 이용해서 프로젝트를 연 후 이름.csproj 이라는 파일을 찾아 <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>을 맞춰주면 된다.

  1. package의 Version Error는 낮은 Version을 install하거나 Version 호환성을 검색해서 적용시키면 된다.

  2. package를 설치할 때 Compiler의 Version Error가 날때가 있다.

Install-Package Microsoft.Net.Compilers -Version 2.8.2

로 새로 Install해주면 에러가 사라진다.




MySql Connection 문제

  1. 처음에는 SqlConnection을 이용해서 개발하여 Sql Server로 자꾸 연결을 했다. Mysql Connection을 이용하면 완벽하게 돌아간다.
  2. Mysql은 Configuration을 작성하는 방법이 다르다.
server=localhost;port=3306;database=dbName;user=root;password=password
  1. Mysql Connection에서 host를 찾지 못한다는 에러가 떴다. Configuration을
Server=127.0.0.1;Port=3306;Database=db;Uid=root;Pwd=password

로 변경하였더니 됬다. 위의 방법이 좀더 보편적이라는데 내가 보기에는 지멋대로.. 이렇게 개발해도 되려나.. 싶다.. 왜 갑자기 되지..? 이해가 안가네




Required Validation Error

Required Annotation을 사용했음에도 불구하고

int type에서는 해당 조건이 적용되지 않는 다는 것을 알았다.

도대체 왜 이런일이 일어날까 검색을 해보니

int type의 Defualt 값이 0이면 값이 있다고 가정한다고 한다.

따라서 두가지 방법으로 해당 오류를 해결할 수 있다.


1. nullable int로 변경

[SwaggerSchema(Description  = "계정 아이디")]
[Required(ErrorMessage      = "계정 아이디 값이 존재하지 않습니다.")]
public int? id       { get; set; }

2. int 값에 Range Annotation 적용

[SwaggerSchema(Description = "가맹점 번호")]
[Required(ErrorMessage = "{0} field is required.")]
[Range(1, int.MaxValue, ErrorMessage = "{0} field must be between {1} and {2}.")]
public int id { get; set; }




Model Validation 적용 시

Model Class에서 각 요소에 Data Annotation을 붙인다고 하더라도

실제 api 적용시에는 적용되지 않는다.

적용을 시키려면 각 Controller의 함수마다 Annotation을 붙여야하는데

ModelValidation이라는 이름을 가진 Custom Filter Attribute를 생성해야한다.

public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var objRequest      = actionContext.Request;
        var objModelState   = actionContext.ModelState;
        var objDescriptor   = actionContext.ActionDescriptor as ReflectedHttpActionDescriptor;

        if(objDescriptor != null)
        {
            var objParameters = objDescriptor.MethodInfo.GetParameters();
            foreach(var objParameter in objParameters)
            {
                var objArgument = actionContext.ActionArguments[objParameter.Name];
                EvaluateValidationAttribute(objParameter, objArgument, actionContext.ModelState);
            }
        }

        if(objModelState.IsValid == false)
        {
            actionContext.Response = ActionErrorResult(objRequest, objModelState);
        }
    }

    private void EvaluateValidationAttribute(ParameterInfo objParameter, object objArgument, ModelStateDictionary objModelState)
    {
        var objValidationAttributes = objParameter.CustomAttributes;

        foreach(var objAttributeData in objValidationAttributes)
        {
            var objAttributeInstance    = CustomAttributeExtensions.GetCustomAttribute(objParameter, objAttributeData.AttributeType);
            var objValidationAttribute  = objAttributeInstance as ValidationAttribute;

            if(objValidationAttribute != null)
            {
                var isValid = objValidationAttribute.IsValid(objArgument);
                if (!isValid)
                {
                    objModelState.AddModelError(objParameter.Name, objValidationAttribute.FormatErrorMessage(objParameter.Name));
                }
            }
        }
    }

    public HttpResponseMessage ActionErrorResult(HttpRequestMessage objRequest, ModelStateDictionary objModelState)
    {
        var modelError      = new RequestModelSateError(objModelState)._errors;
        var objHttpResMsg   = new HttpResponseMessage
        {
            RequestMessage  = objRequest,
            Content         = new ObjectContent<BasicErrorResFormat>(new BasicErrorResFormat(ResCode.API_REQUEST_ERROR_CODE,modelError), new JsonMediaTypeFormatter()),
            StatusCode      = HttpStatusCode.BadRequest

        };

        return objHttpResMsg;
    }
}

아 이 코드는 너무 어려워서 따로 공부를 더 해야한다......ㅜㅜ

공부할게 너무 많다..

생성한 Filter Attribute를 아래와 같이 Controller 밑의 Function에 적용시켜야한다.

[ValidateModel]
public IHttpActionResult PostAccountGet(REQ_UP_ACCOUNT_GET objReqParam)        

그러면 API를 호출했을 때 조건에 맞지 않는 즉 ModelSate가 IsNotValid인 경우, 설정한 오류 값이 나타난다.

React

Aiden

Zoe

Gini

Clone this wiki locally