특정 상황에서 필수 유효성 검사 속성 비활성화


138

특정 컨트롤러 작업에서 필수 유효성 검사 특성을 비활성화 할 수 있는지 궁금합니다. 편집 양식 중 하나에서 사용자가 이전에 이미 지정한 필드의 값을 입력하지 않아도되기 때문에 이것이 궁금합니다. 그러나 값을 입력 할 때 값을 해시하는 등의 특수 논리를 사용하여 모델을 업데이트하는 논리를 구현합니다.

이 문제를 해결하는 방법에 대한 의견이 있으십니까?

편집 :
네, 클라이언트 유효성 검사는 여기에 문제가 있습니다. 값을 입력하지 않고 양식을 제출할 수 없기 때문입니다.


3
+1 good Q. 여기서 클라이언트 검증을 언급하면 ​​좋을 것입니다. 한 가지 옵션은 RequiredAttr완전히 제거하고 필요할 때 서버 측 점검을 수행하는 것입니다. 그러나 이것은 고객에게 까다로울 것입니다
기드온

4
클라이언트 유효성 검사 에서 특정 필드 비활성화 (jquery 유효성 검사에 대한 참조 제거 없음)를 다루는 모든 사람을위한 포인트
gideon

어쩌면 내가 요점을 잃어 버렸을 수도 있지만 사용자가 이미 값을 이미 지정한 경우 해당 값이 이미 존재하므로 필수 유효성 검사를 통과합니다. 다른 의미가 있었습니까?
Erik Funkenbusch

이 값은 암호 및 보안 응답과 같이 해시되었으므로 편집 양식에 새 값을 입력하면 삽입하기 전에 새 값을 다시 해시하고 싶지만 옵션을 비워 둘 수 있습니다. 말하자면.
Alex Hope O'Connor 2

1
@gideon : Adrian Smith의 답변 참조 : stackoverflow.com/a/9781066/114029
Leniel Maccaferri

답변:


76

이 문제는 뷰 모델을 사용하여 쉽게 해결할 수 있습니다. 뷰 모델은 주어진 뷰의 요구에 맞게 특별히 설계된 클래스입니다. 예를 들어 귀하의 경우 다음과 같은 뷰 모델을 가질 수 있습니다.

public UpdateViewView
{
    [Required]
    public string Id { get; set; }

    ... some other properties
}

public class InsertViewModel
{
    public string Id { get; set; }

    ... some other properties
}

해당 컨트롤러 작업에 사용됩니다.

[HttpPost]
public ActionResult Update(UpdateViewView model)
{
    ...
}

[HttpPost]
public ActionResult Insert(InsertViewModel model)
{
    ...
}

널 입력 가능하지 않은 부울 / 비트가있는 경우 항상 참이 아닙니다. 그러나 실제로는 참 또는 거짓으로 끝나기 때문에 차이를 만들지 않습니다. CSS를 사용하여 필수 필드를 강조 표시하고 CheckBoxFor 항목을 잘못 강조 표시했습니다. 내 솔루션 : $ ( "# IsValueTrue"). removeAttr ( "data-val-required");
Robert Koch

업데이트에는 일반적으로 (FormCollection 컬렉션)이 있습니다. 모델을 매개 변수로 사용하는 방법을 설명해 주시겠습니까?
Raj Kumar

4
아니요, 우리는 보통 Update(FormCollection collection)적어도 없습니다. 항상 특정 뷰 모델을 정의하고 사용합니다 Update(UpdateViewView model).
Darin Dimitrov 2016 년

동일한 HTTP 동작을 가진 오버로드 메소드는 허용되지 않으므로 나에게는 이것이 작동하지 않는 것 같습니다. 뭔가 빠졌습니까?
e11s December

@edgi, 아니오, 당신은 아무것도 빠지지 않았습니다. 내 게시물에 실수가 있습니다. 두 번째 조치 방법은 분명히 호출되어야합니다 Insert. 이것을 지적 해 주셔서 감사합니다.
Darin Dimitrov

55

클라이언트 측에서 단일 필드에 대한 유효성 검증을 사용하지 않으려면 다음과 같이 유효성 검증 속성을 대체 할 수 있습니다.

@Html.TexBoxFor(model => model.SomeValue, 
                new Dictionary<string, object> { { "data-val", false }})

20
jQuery를 통해 나를 위해 일한 것은 : $ ( "# SomeValue"). removeAttr ( "data-val-required");
Robert Koch

6
이 방법이 마음에 들지만 다음을 사용하여 양식 유효성 검사 특성을 다시 구문 분석해야했습니다. $ ( 'form'). removeData ( 'unobtrusiveValidation'); $ ( 'form'). removeData ( 'validator'); $ .validator.unobtrusive.parse ( '양식 선택기');
Yannick

15
@Html.TexBoxFor(model => model.SomeValue, new { data_val = false })-읽기 쉬운 IMO.
eth0

나는이 방법을 대부분 좋아하여 각 필드를 미세하게 제어 할 수있게했지만 POST로 저장할 데이터를 보낼 때 ModelState.IsValid를 취소하기 위해 추가 할 수 있습니다. 어쩌면 어떤 위험을 일으킬 수 있습니까?
Felipe FMMobile

4
jQuery를 통해 비활성화하려면 :$(".search select").attr('data-val', false);
Leniel Maccaferri

40

나는이 질문이 오래 전에 답변되어 왔으며 수락 된 답변이 실제로 작업을 수행한다는 것을 알고 있습니다. 그러나 나를 귀찮게하는 한 가지가 있습니다 : 유효성 검사를 비활성화하기 위해 2 개의 모델 만 복사하면됩니다.

내 제안은 다음과 같습니다.

public class InsertModel
{
    [Display(...)]
    public virtual string ID { get; set; }

    ...Other properties
}

public class UpdateModel : InsertModel
{
    [Required]
    public override string ID
    {
        get { return base.ID; }
        set { base.ID = value; }
    }
}

이런 식으로 클라이언트 / 서버 측 유효성 검사를 신경 쓸 필요가 없으며 프레임 워크는 예상대로 작동합니다. 또한 [Display]기본 클래스에서 속성 을 정의하는 경우에 속성을 다시 정의하지 않아도됩니다 UpdateModel.

그리고이 클래스들을 여전히 같은 방식으로 사용할 수 있습니다 :

[HttpPost]
public ActionResult Update(UpdateModel model)
{
    ...
}

[HttpPost]
public ActionResult Insert(InsertModel model)
{
    ...
}

특히 유효성 검사 목록이 긴 경우이 방법이 더 좋습니다. 예를 들어, 기본 클래스에 더 많은 속성을 추가하여 이점을보다 분명하게 얻을 수 있습니다. 내가 볼 수있는 유일한 단점은 속성을 상속하여 속성을 재정의 할 수있는 방법이 없다는 것입니다. 예를 들어, 기본 클래스에 [필수] 속성이있는 경우 사용자 지정 [선택 사항] 속성이 없으면 상속 속성도 [필수]가됩니다.
Yorro

여러 속성을 가진 'Project'개체가있는 viewModel이 있지만 특정 상황에서 이러한 속성 중 하나만 유효성 검사하기를 원하지만 이와 같은 것을 생각했습니다. 객체의 속성을 무시할 수 있다고 생각하지 않습니까? 어떤 충고?
vincent de g

속성을 재정의 할 수 없습니다. 기본 클래스는 모든 하위 클래스에 대한 공통 속성 만 포함해야합니다. 그런 다음 하위 클래스는 필요한 속성을 정의해야합니다.
PhilDulac

1
가장 우아하고 재사용 가능한 명확한 솔루션. 복제가 잘못되었습니다. 다형성이 방법입니다. +1
T-moty

필자의 경우 기본 클래스에는 필수 속성이 있으며 부모 클래스에서 필요하지 않은 속성으로 만들고 싶습니다. 모델의 사본 두 개가 없어도 가능합니까?
Alexey Strakh

27

컨트롤러 작업에서 다음을 사용하여 속성에서 모든 유효성 검사를 제거 할 수 있습니다.

ModelState.Remove<ViewModel>(x => x.SomeProperty);

MVC5에 관한 @Ian 의견

다음은 여전히 ​​가능합니다

ModelState.Remove("PropertyNameInModel");

업데이트 된 API로 정적 타이핑을 잃어 버리는 것이 조금 귀찮습니다. HTML 헬퍼 인스턴스를 작성하고 NameExtensions Methods를 사용하여 이전 방식과 유사한 것을 달성 할 수 있습니다.


빼고 ... ModelState그 서명과 일치 하는 방법이 없습니다 . 적어도 MVC 5에는 없습니다.
Ian Kemp

문제는 모든 유효성 검사를 제거하는 방법이 아닙니다. 필수 필드 유효성 검사를 제거하는 방법이었습니다. 다른 유효성 검사 규칙을 그대로두고이 작업을 수행 할 수 있습니다.
Richard

15

고객 쪽 양식에 대한 유효성 검사를 비활성화하기 위해 내 연구에 기반한 여러 옵션이 아래에 나와 있습니다. 그들 중 하나가 희망적으로 당신을 위해 일할 것입니다.

옵션 1

나는 이것을 선호하며 이것은 완벽하게 작동합니다.

(function ($) {
    $.fn.turnOffValidation = function (form) {
        var settings = form.validate().settings;

        for (var ruleIndex in settings.rules) {
            delete settings.rules[ruleIndex];
        }
    };
})(jQuery); 

그리고 그것을 호출

$('#btn').click(function () {
    $(this).turnOffValidation(jQuery('#myForm'));
});

옵션 2

$('your selector here').data('val', false);
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");

옵션 3

var settings = $.data($('#myForm').get(0), 'validator').settings;
settings.ignore = ".input";

옵션 4

 $("form").get(0).submit();
 jQuery('#createForm').unbind('submit').submit();

옵션 5

$('input selector').each(function () {
    $(this).rules('remove');
});

서버 측

속성을 작성하고 해당 속성으로 조치 메소드를 표시하십시오. 특정 요구에 맞게이를 사용자 정의하십시오.

[AttributeUsage(AttributeTargets.All)]
public class IgnoreValidationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var modelState = filterContext.Controller.ViewData.ModelState;

        foreach (var modelValue in modelState.Values)
        {
            modelValue.Errors.Clear();
        }
    }
}

더 나은 접근법은 여기에서 설명 합니다 .mvc 서버 측 유효성 검사를 동적으로 활성화 / 비활성화


$ ( '입력 선택기') .each (function () {$ (this) .rules ( 'remove');}); 나를 도와주었습니다
Sachin Pakale

문제는 특히 모든 유효성 검사를 제거하는 것이 아니라 필수 필드 유효성 검사를 제거하는 것에 관한 것입니다. 귀하의 답변은 모든 유효성 검사를 제거하는 것입니다.
Richard

14

개인적으로 나는 Darin Dimitrov가 그의 해결책에서 보여준 접근법을 사용하는 경향이 있습니다. 이를 통해 데이터 주석 접근 방식을 유효성 검사와 함께 사용할 수 있고 각 작업에 해당하는 각 ViewModel에 대해 별도의 데이터 속성을 가질 수 있습니다. 모델과 뷰 모델 간의 복사 작업량을 최소화하려면 AutoMapper 또는 ValueInjecter를 살펴 보십시오 . 둘 다 각자의 장점이 있으므로 확인하십시오.

IValidatableObject에서 뷰 모델 또는 모델을 파생시키는 다른 방법이 있습니다. 이를 통해 Validate 함수를 구현할 수 있습니다. 유효성 검사에서 유효성 검사 결과 요소 목록을 반환하거나 유효성 검사에서 탐지 한 각 문제에 대해 수익률을 반환 할 수 있습니다.

ValidationResult는 오류 메시지와 필드 이름이 포함 된 문자열 목록으로 구성됩니다. 오류 메시지는 입력 필드 근처의 위치에 표시됩니다.

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
  if( NumberField < 0 )
  {
    yield return new ValidationResult( 
        "Don't input a negative number", 
        new[] { "NumberField" } );
  }

  if( NumberField > 100 )
  {
    yield return new ValidationResult( 
        "Don't input a number > 100", 
        new[] { "NumberField" } );
  }

  yield break;
}

이것을 클라이언트쪽에 연결할 수 있습니까?
Muhammad Adeel Zahid

클라이언트 측 유효성 검사는 일반적으로 개별 필드에 대해서만 수행되며 대화 형의 필드 별 유효성 검사 피드백을 사용자 편의를 위해 수행합니다. 객체 유효성 검사 단계에는 일반적으로 종속 유효성 검사 (객체 자체 외부에있는 다중 필드 및 / 또는 조건)가 포함되므로 코드를 JavaScript로 컴파일 할 수 있더라도 클라이언트 쪽에서 반드시 수행 할 필요는 없습니다. 클라이언트 측의 복잡한 / 종속적 유효성 검사로 인해 가치가 추가되면 onsubmit 콜백을 사용하고 클라이언트 측에서 유효성 검사 논리를 복제해야합니다.
mindplay.dk

7

내가 생각하는 가장 깨끗한 방법은 클라이언트 측 유효성 검사를 비활성화하고 서버 측에서 다음을 수행해야한다는 것입니다.

  1. ModelState [ "SomeField"]. Errors.Clear (컨트롤러에서 또는 컨트롤러 코드가 실행되기 전에 오류를 제거하기위한 작업 필터를 만듭니다)
  2. 감지 된 문제의 위반을 감지하면 컨트롤러 코드에서 ModelState.AddModelError를 추가하십시오.

여기에 사용자 정의보기 모델조차도 '사전 응답 된'필드의 수가 다양 할 수 있기 때문에 문제를 해결하지 못하는 것 같습니다. 그렇지 않으면 사용자 정의보기 모델이 가장 쉬운 방법 일 수 있지만 위의 기술을 사용하면 유효성 검사 문제를 해결할 수 있습니다.


1
이것은 내가 필요한 것입니다. 하나의보기가 있었고이보기에서 다른 동작이 발생하므로 다른 ViewModel로 볼 수 없었습니다. 이것은 매력처럼 작동합니다
ggderas

6

이것은 의견에 대한 다른 사람의 대답이었습니다 ... 그러나 진정한 대답이어야합니다.

$("#SomeValue").removeAttr("data-val-required")

[Required]속성 이있는 필드를 사용하여 MVC 6에서 테스트

위의 https://stackoverflow.com/users/73382/rob 에서 도난당한 답변


1
서버 측 유효성 검사는 어떻습니까?
T-moty 2016 년

ModelState. 제거, 그렇지? 어쨌든, 문제는 내 모델에 두 번째 엔터티가 포함되어 있다는 것입니다 ... 주요 검증을 원했지만 보조는 해당 페이지에서 검증이 필요하지 않았습니다. JQuery 만 필요했습니다.
Mike_Matthews_II

링크가 깨 졌다고 생각하므로 수정하십시오. 이것은 부분 답변입니다.
T-moty 2016 년

이것이 MVC6에서 작동한다고 말한 것이 이상합니다 (현재 MVC6에서 테스트 할 수있는 옵션이 없습니다). 현재 사용중인 MVC4에서는 작동하지 않습니다.
eaglei22

질문은 MVC / C #에 대한 것입니다
-JS

2

내 모델에 대한 편집 뷰를 생성 할 때이 문제가 발생하여 하나의 필드 만 업데이트하려고합니다.

가장 간단한 방법에 대한 내 솔루션은 다음을 사용하여 두 필드를 넣는 것입니다.

 <%: Html.HiddenFor(model => model.ID) %>
 <%: Html.HiddenFor(model => model.Name)%>
 <%: Html.HiddenFor(model => model.Content)%>
 <%: Html.TextAreaFor(model => model.Comments)%>

주석은 편집보기에서만 업데이트하며 필수 속성이없는 필드입니다.

ASP.NET MVC 3 엔터티


1

AFAIK 런타임에 속성을 제거 할 수는 없지만 값만 변경하십시오 (예 : readonly true / false) 비슷한 것을 찾으십시오 . 속성을 엉망으로하지 않고 원하는 것을 수행하는 또 다른 방법으로 특정 작업에 대해 ViewModel을 사용하여 다른 컨트롤러에 필요한 로직을 손상시키지 않고 모든 로직을 삽입 할 수 있습니다. 일종의 마법사 (다단계 양식)를 얻으려고하면 이미 컴파일 된 필드를 직렬화하고 TempData를 사용하여 단계를 수행하십시오. (직렬화 직렬화를 돕기 위해 MVC 선물을 사용할 수 있습니다 )


1

@Darin이 말한 것은 내가 추천하는 것입니다. 그러나 실제로 비트, 부울, Guid와 같은 기본 유형에 단순히이 null을 허용 하여이 유형을 사용하는 경우 에도이 방법을 사용할 수 있다고 덧붙였습니다. 이 작업을 수행하면 Required속성 이 예상대로 작동합니다.

public UpdateViewView
{
    [Required]
    public Guid? Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public int? Age { get; set; }
    [Required]
    public bool? IsApproved { get; set; }
    //... some other properties
}

1

MVC 5부터는 이것을에 추가하면 쉽게 얻을 수 있습니다 global.asax.

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

1

웹 API에서 삽입 및 업데이트에 동일한 모델을 사용할 수있는 솔루션을 찾고있었습니다. 내 상황에서 이것은 항상 본문 내용입니다. [Requiered]이 업데이트 방법 인 경우 속성은 생략해야합니다. 내 솔루션에서는 [IgnoreRequiredValidations]메소드 위에 속성을 배치합니다 . 이것은 다음과 같습니다 :

public class WebServiceController : ApiController
{
    [HttpPost]
    public IHttpActionResult Insert(SameModel model)
    {
        ...
    }

    [HttpPut]
    [IgnoreRequiredValidations]
    public IHttpActionResult Update(SameModel model)
    {
        ...
    }

    ...

다른 무엇을해야합니까? 시작시 자체 BodyModelValidator를 작성하고 추가해야합니다. 이것은 HttpConfiguration에 있으며 다음과 같습니다.config.Services.Replace(typeof(IBodyModelValidator), new IgnoreRequiredOrDefaultBodyModelValidator());

using Owin;
using your_namespace.Web.Http.Validation;

[assembly: OwinStartup(typeof(your_namespace.Startup))]

namespace your_namespace
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            Configuration(app, new HttpConfiguration());
        }

        public void Configuration(IAppBuilder app, HttpConfiguration config)
        {
            config.Services.Replace(typeof(IBodyModelValidator), new IgnoreRequiredOrDefaultBodyModelValidator());
        }

        ...

내 자신의 BodyModelValidator는 DefaultBodyModelValidator에서 파생됩니다. 그리고 나는 'ShallowValidate'방법을 재정의해야한다는 것을 알았습니다. 이 재정의에서 필요한 모델 유효성 검사기를 필터링합니다. 그리고 이제 IgnoreRequiredOrDefaultBodyModelValidator 클래스와 IgnoreRequiredValidations 속성 클래스 :

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Http.Metadata;
using System.Web.Http.Validation;

namespace your_namespace.Web.Http.Validation
{
    public class IgnoreRequiredOrDefaultBodyModelValidator : DefaultBodyModelValidator
    {
        private static ConcurrentDictionary<HttpActionBinding, bool> _ignoreRequiredValidationByActionBindingCache;

        static IgnoreRequiredOrDefaultBodyModelValidator()
        {
            _ignoreRequiredValidationByActionBindingCache = new ConcurrentDictionary<HttpActionBinding, bool>();
        }

        protected override bool ShallowValidate(ModelMetadata metadata, BodyModelValidatorContext validationContext, object container, IEnumerable<ModelValidator> validators)
        {
            var actionContext = validationContext.ActionContext;

            if (RequiredValidationsIsIgnored(actionContext.ActionDescriptor.ActionBinding))
                validators = validators.Where(v => !v.IsRequired);          

            return base.ShallowValidate(metadata, validationContext, container, validators);
        }

        #region RequiredValidationsIsIgnored
        private bool RequiredValidationsIsIgnored(HttpActionBinding actionBinding)
        {
            bool ignore;

            if (!_ignoreRequiredValidationByActionBindingCache.TryGetValue(actionBinding, out ignore))
                _ignoreRequiredValidationByActionBindingCache.TryAdd(actionBinding, ignore = RequiredValidationsIsIgnored(actionBinding.ActionDescriptor as ReflectedHttpActionDescriptor));

            return ignore;
        }

        private bool RequiredValidationsIsIgnored(ReflectedHttpActionDescriptor actionDescriptor)
        {
            if (actionDescriptor == null)
                return false;

            return actionDescriptor.MethodInfo.GetCustomAttribute<IgnoreRequiredValidationsAttribute>(false) != null;
        } 
        #endregion
    }

    [AttributeUsage(AttributeTargets.Method, Inherited = true)]
    public class IgnoreRequiredValidationsAttribute : Attribute
    {

    }
}

출처 :



0

필자의 경우 동일한 모델이 많은 페이지에서 재사용을 위해 사용되었습니다. 그래서 내가 한 것은 제외를 확인하는 사용자 정의 속성을 만들었습니다.

public class ValidateAttribute : ActionFilterAttribute
{
    public string Exclude { get; set; }
    public string Base { get; set; }
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!string.IsNullOrWhiteSpace(this.Exclude))
        {
            string[] excludes = this.Exclude.Split(',');
            foreach (var exclude in excludes)
            {
                actionContext.ModelState.Remove(Base + "." + exclude);
            }
        }
        if (actionContext.ModelState.IsValid == false)
        {
            var mediaType = new MediaTypeHeaderValue("application/json");
            var error = actionContext.ModelState;

            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, error.Keys, mediaType);

        }
    }
}

컨트롤러에서

[Validate(Base= "person",Exclude ="Age,Name")]
    public async Task<IHttpActionResult> Save(User person)
    {

            //do something           

    }

모델이

public class User
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Range(18,99)]
    public string Age { get; set; }
    [MaxLength(250)]
    public string Address { get; set; }
}

-1

예, 필수 속성을 비활성화 할 수 있습니다. RequiredAtribute에서 확장 할 수 있도록 고유 한 사용자 지정 클래스 특성 (ChangeableRequired라는 샘플 코드)을 만들고 Disabled 속성을 추가하고 IsValid 메서드를 재정 의하여 기밀이 있는지 확인합니다. 다음과 같이 반사를 사용하여 비활성화 된 poperty를 설정하십시오.

맞춤 속성 :

namespace System.ComponentModel.DataAnnotations
{
    public class ChangeableRequired : RequiredAttribute
    {
       public bool Disabled { get; set; }

       public override bool IsValid(object value)
       {
          if (Disabled)
          {
            return true;
          }

          return base.IsValid(value);
       }
    }
}

새 사용자 정의 속성을 사용하도록 속성을 업데이트하십시오.

 class Forex
 {
 ....
    [ChangeableRequired]
    public decimal? ExchangeRate {get;set;}
 ....
 }

속성을 사용하지 않으려면 리플렉션을 사용하여 설정하십시오.

Forex forex = new Forex();
// Get Property Descriptor from instance with the Property name
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(forex.GetType())["ExchangeRate"];
//Search for Attribute
ChangeableRequired attrib =  (ChangeableRequired)descriptor.Attributes[typeof(ChangeableRequired)];

// Set Attribute to true to Disable
attrib.Disabled = true;

기분이 좋고 깨끗합니까?

NB : 객체 인스턴스가 활성화되어있는 동안 위의 유효성 검사가 비활성화됩니다 ...


이에 대해 몇 가지 토론을 한 후 유효성 검사 비활성화를 권장하지 않고 규칙을 검토한다고 언급하고 싶습니다. 비활성화하면 규칙을 다시 활성화하기 위해 종속성을 생성하므로 규칙을 검토하는 것이 좋습니다.
어니스트 Gunning

동일한 프로세스 내에서 실행되는 해당 필드의 모든 유효성 검사를 완전히 비활성화하기 위해 정적 값을 변경하면 끔찍한 아이디어처럼 들립니다.
Jeremy Lakeman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.