1) ‘시작|실행’ 을 선택하여 cmd 를 입력하여 Command 입력 윈도우를 연다.

2) .NET Framework 가 설치된 디렉토리로 이동한다. ( 보통의 경우 : cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 )

3) aspnet_regiis –i 를 실행한다.

4) 등록 메시지가 화면에 표시되면서 ASP.NET를 웹 사이트에 등록된다. ( <그림 1> 참조 )

5) 웹 사이트 등록정보 HTTP 헤더 탭에서 ASP.NET 등록을 확인한다.

 

 

펌 : http://www.autobase.biz/Korean/AutoBaseHelp/Help10/network/NetworkWebServerAspNetInstall.htm

2015 를 쓰면서 자주 사용했던 기능들이 2017 을 가니

비활성화 되어있거나 다르게 동작하는 것들이 있다.

내가 기억하기 위해 적어본다. (자꾸 잊어먹음;;)

 

1. 솔루션 탐색기에서 활성화된 항목 추적 : 내가 작업하고 있는 소스가 있다면 이 항목이 솔루션 탐색기에서 선택되어있도록 한다.

2. 빌드를 시작할 때 [출력] 창에 표시 : 빌드시 하단 창들중 출력 창을 보여준다.

 

3. 자동 중괄호 완성 : 체크하면 { 입력시 } 가 자동으로 입력된다. 난 체크 해제하고 쓰는게 편하다. 습관이 되서 자꾸 자동으로 추가된 } 을 지운다.;

 

4. 정의로 축소 할때 #region 축소 :  region 단위로 소스를 보고자할 때 region 단위로 소스를 축소한다.
                                              체크 되어있지 않으면 메서드 주석이 남은 상태로 region 처리가 되어 보여진다.

 

5. /* */ 주석을 작성할 때 새 줄의 시작 부분에 * 삽입 : 주석앞에 * 이 자동으로 붙는 기능인데 난 없는게 좋다.

 

6. 마우스를 클릭하면 정의로 이동하도록 허용 : 솔직히 이건 왜 이렇게 한건지 모르겠다 F12 누르면 정의로 이동하는데..;

원래 Ctrl+마우스 좌 클릭하면 문자열 단위로 선택이 되어 편하게 썼는데 그 기능과 겹친다.; 그래서 체크 해제

Visual Studio 2017 을 설치하고 프로젝트를 열었는데

system.windows.interactivity 관련 에러가 발생되었다.

dll 참조에 느낌표가 발생된것이다.

Visual Studio 2015 에서는 잘 돌아갔던 소스였는데.. 머지 하고 검색해 보니

Nuget 을 이용해서 설치하라는데.. 이건 프로젝트와 상관이 없는데... 왜 Nuget 에서 설치를 해야하지?

하고 찾고 있었는데 역시나 환경 문제 였다.

Visual Studio 에서 도구 및 기능 가져오기 로 진입

 

아래와 같은 화면이 나오면 우선 Vusial Studio 를 종료하고

상단의 개별 구성 요소 진입

 

SDK 라이브러리 및 프레임워크 에서 .NET 용 Blend for Visual Studio SDK 를 체크하여 설치를 진행하면 된다.

8. 리터럴에 대한 표현 방법 개선

숫자가 클때 가독성이 떨어질때가 많은에 아래처럼 숫자사이에 _ 를 붙여 사용이 가능하다.

int num1 = 10000000;

int num2 = 10_000_000; // 천단위로 끊어서 볼수 있어 가독성이 좋아진다.

모든 숫자 데이터에 적용이 가능하기때문에 16진수 2진수 표현에도 사용이 가능하다.

 

9. 패턴 매칭

1) 연산자의 패턴매칭

 예전에는 is, as 를 구분하여 사용했지만

object obj = new List<string>();
List<string> list = obj as List<string>;
list?.ForEach((e) => Console.WriteLine(e));

7.0 부터는 is 가 as 역할을 수행할수 있아 아래처럼 사용이 가능하다.

object obj = new List<string>();
if (obj is List<string> list)
{
    list.ForEach((e) => Console.WriteLine(e));
}

var 패턴의 경우 사용예시이다 var 패턴은 반드시 변수명이 필요하다. 무조건 is 결과가 true 이므로 의미가 없다.

if (item is var elem) // 타입 패턴과는 달리 변수명을 생략할 수 없다. 무조건 true
{
    Console.WriteLine(elem);
}

 

2) switch/case 문의 패턴 매칭

아래처럼 상수 패턴을 사용할수 있고 타입도 사용하면서 바로 변수에 대입하여 사용할수도 있다.

var objTestList = new List<object>();

foreach (object obj in objTestList)
{
    switch (item)
    {
        case 100: // 상수 패턴
            break;
        case null: // 상수 패턴
            break;
        case DateTime dt: // 타입 패턴 (값 형식) – 필요 없다면 dt 변수 생략 가능
            break;
        case ArrayList arr: // 타입 패턴 (참조 형식) – 필요 없다면 arr 변수 생략 가능
            break;
        case var element: // Var 패턴 (이렇게 사용하면 default와 동일)
            break;
    }
}

또한 switch 에서 when 예약어 기능을 사용할수 있어 아래처럼 사용이 가능하다.

int checkNum = 301;
switch (checkNum)
{
    case int num when checkNum > 300: // int 타입이고 그 값이 300보다 큰 경우
        break;
    default:
        break;
}

위와같이 쓰면 case 의 순서가 중요해진다.

 상위의 case 조건에서 이미 만족한다면 그 절의 코드가 실행되고 그 하위의 case 조건 에 대한 평가는 무시된다.

늘 기억한다고 하면서도 어떤 것들은 코딩할때 예전방식대로 코딩 하고 있는 내 자신을 본다.

다시한번 상기시키기위해 정리해본다.

참고 : 정성태님 자료.

 

1. out 매개변수

이전에는 out 매개변수를 미리 선언했어야 하나 7.0 부터는 변수 선언없이 out 예약어를 쓸수 있다.

 int.TryParse("5", out int result);

C# 7 컴파일러는 위의 구문을 컴파일하는 경우 개발자 대신 C# 6 이전의 코드로 변환해 소스코드를 컴파일한다. 

var 예약어도 사용할 수 있다.

 int.TryParse("5", out var result); // out int result로 컴파일러가 대신 처리

심지어 값을 무시하는 구문까지 추가되어 값이 필요하지 않은 상황에 대해서는 변수명까지 생략할 수 있다. (이건 굳이 필요가?.;)

 int.TryParse("5", out int _ ); // 변수명 대신 밑줄(underline: _)로 생략
 int.TryParse("5", out var _ );

 

2. ref 예약어

이전에는 메서드의 매개변수로만 사용가능했지만 로컬변수와 번환값에서도 사용할 수 있다.

int a = 5;
ref int b = ref a;

위처럼 하고 사용하게되면 a, b 변수는 동일한 메모리를 공유하게 된다.

반환값으로 사용하는 경우는 이전에는 메서드에서 배열의 특정 요소를 변경한 결과를 넘겨주기위해 귀찮게 작업하던걸 아래처럼 처리할수 있다.

 IntList intList = new IntList();
 ref int item = ref intList.GetFirstItem();
 item = 5; // 참조값이므로 값을 변경하면 원래의 int [] 배열에도 반영
 intList.Print(); // 출력 결과: 5,2,


class IntList
{
 int[] list = new int[2] { 1, 2 };
 public ref int GetFirstItem()
 {
   return ref list[0];
 }
 internal void Print() { ……[생략]…… }
}

 

3. 튜플

튜플(Tuple)이란 유한 개의 원소로 이뤄진 졍렬된 리스트를 의미하는 자료구조다.

어떤 메서드의 결과가 두가지를 도출할때 이전에는 아래처럼 class 를 정의해서 사용했지만 튜플을 이용하면 사용하기 쉽다. 

public class Result
{
    public int ResultInt {get; set;}
    public bool ResultBool {get; set;}

public Result TestMethod()
{
      Result result =  new Result(){ ResultInt =0, ResultBool = false};
      return result;
}

dynamic 를 이용해서 아래처럼 어느정도 해결은 가능하다.

public dynamic TestMethod()
{
      return new { ResultInt =0, ResultBool = false };;
}

하지만 dynamic의 도입으로 정적 형식 검사를 할 수 없어 나중에 필드 이름이 바뀌어도 컴파일 시 문
제를 알아낼 수 없다는 문제점이 발생한다.


닷넷 프레임워크 4.0의 BCL부터 제공되는 System.Tuple 제네릭 타입을 이용하면 7개까지의 인자를 기본 처리할 수 있도록 미리 정의돼 있으며,
public class Tuple<T1> : IStructuralEquatable, …[생략]…, ITuple
public class Tuple<T1, T2> : IStructuralEquatable, …[생략]…, ITuple
public class Tuple<T1, T2, T3> : IStructuralEquatable, …[생략]…, ITuple
public class Tuple<T1, T2, T3, T4> : IStructuralEquatable, …[생략]…, ITuple
public class Tuple<T1, T2, T3, T4, T5> : IStructuralEquatable, …[생략]…, ITuple
public class Tuple<T1, T2, T3, T4, T5, T6> : IStructuralEquatable, …[생략]…, ITuple
public class Tuple<T1, T2, T3, T4, T5, T6, T7> : IStructuralEquatable, …[생략]…, ITuple

8개 이상은 또 다른 System.Tuple로 이어서 처리할 수 있도록 구현돼 있다.
public class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> : IStructuralEquatable, …[생략]…, ITuple

따라서 위 문제는 아래처럼 해결이 가능하다.

public Tuple<int, bool> TestMethod()
{
    int number = 0;
    bool result = false; 
    return Tuple.Create(number, result ); 
}

 Tuple<int, bool> result = TestMethod();
 Console.WriteLine(result.Item1); 
 Console.WriteLine(result.Item2);

또한 C# 7.1부터 튜플에 대해 타입 추론이 추가되어 이름 지정을 생략할 수 있는 경우가 있다
여기서 부터는 코드가 무슨 암호가 되버린 느낌이다;;

(int, bool) TestMethod()
{
    int number = 0;
    bool result = false; 
    return (number, result);
}

 (int, bool) result = TestMethod();
 Console.WriteLine(result.Item1); 
 Console.WriteLine(result.Item2);

변수의 이름이 무조건 Item1,Item2, ……와 같은 식으로 정해진다는 아쉬움이 남는다.
하지만 이런 모든 문제를 해결하기 위해 마이크로소프트는 C# 언어 차원에서 튜플을 지원하기로 결정했고 이로 인해 메서드의 정의 구문이 확장된다.

그래서 이제 아래 처럼 사용하여 이름을 지정할수 있다. (var 도 가능)

(int ResultInt , bool ResultBool) TestMethod()
{
    int number = 0;
    bool result = false; 
    return (number, result);
}

 (int , bool) result = TestMethod();
 Console.WriteLine(result.ResultInt ); 
 Console.WriteLine(result.ResultBool);

메서드에서 정의 하지 않고 받는 곳에서 정의도 할수 있다.  

(int, bool) TestMethod()
{
    int number = 0;
    bool result = false; 
    return (number, result);
}

 (int ResultInt , bool ResultBool) result = TestMethod();
 Console.WriteLine(result.ResultInt ); 
 Console.WriteLine(result.ResultBool);

 

5. 람다 식을 이용한 메서드 정의 확대

C# 6.0의 람다 식으로 메서드의 정의가 가능했던 유형은 다음과 같다.
■ 일반 메서드
■ 속성의 get 접근자(읽기 전용으로 처리됨)
■ 인덱서의 get 접근자(읽기 전용으로 처리됨)


C# 7.0부터는 람다 식의 접근이 다음의 메서드 정의까지 확장됐다.
■ 생성자(Constructor)
■ 소멸자(Destructor)
■ 이벤트의 add/remove
■ 속성의 set 구문
■ 인덱서의 set 구문

아래 예시를 보면 깔끔하게 정리된다.

    public class Vector
    {
        double x;
        double y;
        public Vector(double x) => this.x = x; // 생성자 정의 가능
        public Vector(double x, double y) // 생성자이지만 2개의 문장이므로 람다 식으로 정의 불가
        {
            this.x = x;
            this.y = y;
        }
        ~Vector() => Console.WriteLine("~dtor()"); // 소멸자 정의 가능
        public double X
        {
            get => x;
            set => x = value; // 속성의 set 접근자 정의 가능
        }
        public double Y
        {
            get => y;
            set => y = value; // 속성의 set 접근자 정의 가능
        }
        public double this[int index]
        {
            get => (index == 0) ? x : y;
            set => _ = (index == 0) ? x = value : y = value; // 인덱서의 set 접근자 정의 가능
        }
        private EventHandler positionChanged;
        public event EventHandler PositionChanged // 이벤트의 add/remove 접근자 정의 가능
        {
            add => this.positionChanged += value;
            remove => this.positionChanged -= value;
        }
        public Vector Move(double dx, double dy)
        {
            x += dx;
            y += dy;
            positionChanged?.Invoke(this, EventArgs.Empty);
            return this;
        }
        public void PrintIt() => Console.WriteLine(this);
        public override string ToString() => string.Format("x = {0}, y = {1}", x, y);
    }

 

6. 지역함수

아래 코딩만 참고하자

        void LambdaFuncTest()
        {
            (bool, int) func(int a, int b) => (b == 0) ? (false, 0) : (true, a / b);
            Console.WriteLine(func(10, 5));
        }

 

7 자유로워진 throw 사용

이전에는 아래처럼 Throw 를 표현식에서 사용이 불가하여 처리하기위해 별도 메서드를 만들어서 호출했으나

public bool Assert(bool result) => result == true ? result : AssertException("ERROR!!");
public bool AssertException(string msg) => throw new ApplicationException(msg);


이제는 그러지 않아도 된다.

 public bool Assert(bool result) => result == true ? result : throw new ApplicationException("ERROR!!");


다음 코드에서 볼 수 있는 것처럼 null 병합 연산자(??)와 람다식을 사용할 수 있는 곳 에서 throw를 사용할 수 있다.

    class Person
    {
        public string Name { get; }

        // null 병합 연산자(??)에서 throw 사용 가능
        public Person(string name) => Name = name ?? throw new ArgumentNullException(nameof(name));

        // 람다 식으로 정의된 메서드에서 사용 가능
        public string GetLastName() => throw new NotImplementedException();

        public void Print()
        {
            // 단일 람다 식을 이용한 델리게이트 정의에서 사용 가능
            Action action = () => throw new Exception();
            action();
        }
    }

* 표현식이 허용되는 모든 곳에서 사용가능한건 아니다.


continue...

input 문자열에 특수 문자가 있다면 isSpecial 에 true 가 반환된다.

string input = @"특수문자가 있습니까?!@#$%^&~.!";

bool isSpecial = Regex.IsMatch(input, @"[^a-zA-Z0-9가-힣]");

[^a-zA-Z0-9가-힣] 은 앞에 ^ 표시가 붙어 부정을 의미한다.

그러므로 a-zA-Z0-9가-힣 사이에 있는문자가 아닌게 있는지 확인하는 것이다.

 

제거는

input = Regex.Replace(input, @"[^a-zA-Z0-9가-힣]", "", RegexOptions.Singleline);

친구가

double value1 = 0.01;
double value2 = 0.05;
double resultValue = value1 + value2;

위 결과가 이상하게 나온다고하여 확인해 보니

0.060000000000000005 으로 결과가 나왔다.;;

그래서 좀 찾아보니 어쩔수 없는.. 부동소수점은 근사치를 나타내는거라 정확하지 않다고 한다.

참고 http://www.sysnet.pe.kr/Default.aspx?mode=2&sub=0&detail=1&pageno=0&wid=10872&rssMode=1&wtype=0

 

위 결과를 제대로 나타내기 위해선 아래와 같이 두가지 방법이 있다.

1. decimal 자료형을 쓰는것이다. (C# 에서는 이방법을 추천)

decimal value1 = 0.01m;
decimal value2 = 0.05m;
decimal resultValue = value1 + value2;

 

원래 코드에 영향없이 하려면 아래 방법이 좋을것 같다.

double value1 = 0.01;
double value2 = 0.05;

decimal calValue1 = (decimal)value1;
decimal calValue2 = (decimal)value2;

double resultValue = (double)(calValue1 + calValue2);

 

2. double 형을 ToString() 해서 다시 double 로 변환을 해서 써도 된다.

double value1 = 0.01;
double value2 = 0.05;
double resultValue = Convert.ToDouble((value1 + value2).ToString());

추가로 다른 해결방법이 있을지는 모르겠다;

double/float 형으로 계산을 하는 경우는 주의를 해야할것 같다 자칫 잘못된 결과가 나올수 있기 때문이다.

C# 뿐만 아니라 모든 언어(IEEE 754따르는언어)에 해당된다고 한다.

 

참고

http://wiseheart-textcube.blogspot.kr/2006/07/c%EA%B3%BC-%EB%96%A0%EB%8B%A4%EB%8B%88%EB%8A%94-%EC%86%8C%EC%88%98%EC%A0%90-%EC%9D%B4%EC%95%BC%EA%B8%B03.html

https://stackoverflow.com/questions/8911440/strange-behavior-when-casting-a-float-to-int-in-c-sharp

https://azure.microsoft.com/ko-kr/free/?OCID=AID631159_OLA_205134375_93384177

위 링크로 가면 마소계정으로 무료 체험하기 신청을 할수 있습니다. (이러다 대머리가 될수도..;;)

체험하기 버튼을 누르고

 

마소 계정으로 로그인합니다.

 

우선 전호번호로 인증코드를 받아야합니다.

 

동의 를 누르고 카드로 인증을 또 해야합니다.

추가 결제는 안되니 안심하고 등록합니다.

 

첫번째만 체크하고 등록 커튼 클릭합니다. 두번째도 원하면 체크하세요^^;

 

정보확인에 조금 시간이 걸립니다.

 

정보확인이 끝나면 위와같은 화면이 나오고 건너뛰고 AZure Portal 로 계속 진행하기 를 클릭합니다.

 

콘솔화면이 나타납니다.

 

기본적으로 화면의구성 내용은 아래와 같습니다.

 

1년간 사용할수 있는 무료크레딧 24만 크레딧을 줍니다.

 

2017/11/21 - [C#.NET/C#] - 카카오 쳇봇 만들기 - 1 (플러스친구 만들기)

2017/11/24 - [C#.NET/C#] - 카카오 쳇봇 만들기 - 2 (C# 서버 만들기)

 

이전 시간에 이어서 응답 가능한 쳇봇을 구성해보겠습니다.

응답가능한 쳇봇은 아래 처럼 구성이 되어야 한다고 나와있습니다.

https://github.com/plusfriend/auto_reply#52-메시지-수신-및-자동응답-api

우선 내 서버로 들어온 미디어 데이터는 내 서버로 바로 오는게 아니라 카카오 서버에 저장되어 넘어옵니다.

하지만 내 서버에서 보낸건 내 서버에만 저장됩니다.

 

위 그림에서 보듯이 사용자가 내 서버로 메세지나 미디어 정보를 보내면 위 처럼 데이터가 담겨서 넘어옵니다.

내 서버로 온 미디어 정보는 카카오 서버에 저장되어 넘어오므로 content url 에 카카오 서버 링크가 보여집니다.

위 정보를 토대로 Post 메서드를 구성해 보면..

주소가 message 로 끝나야하고 POST 메서드 이므로 아래 처럼 기본 구조를 갖습니다.

        [HttpPost]
        [Route("message")]
        public dynamic GetKakao_message([FromBody]dynamic value)
        {
            return null;
        }

json 형태로 넘겨야하기 때문에 그냥 Dynamic 을 리턴 타입으로 했습니다.

이제 value 에 위에서 제시한 user_key, type, content 값이 넘어오게 됩니다.

이제 이정보를 value 에서 꺼내야합니다.

쉽게 꺼내기 위해서 프로젝트에 Nuget 패키지 관리자 를 통해

Newtonsoft.Json 을 설치합니다.

using Newtonsoft.Json; 문을 추가한 후

아래처럼 꺼내올 구조를 정의하고

        public class KakaoModel
        {
            public string user_key { get; set; }
            public string type { get; set; }
            public string content { get; set; }
        }

아래 처럼 코딩하게되면 KakaoModel 에 데이터가 담기게 됩니다.

        [HttpPost]
        [Route("message")]
        public dynamic GetKakao_message([FromBody]dynamic value)
        {
            string valueString = JsonConvert.SerializeObject(value);
            KakaoModel postmodel = JsonConvert.DeserializeObject<KakaoModel>(valueString);
            string result = postmodel.content;

            return result;
        }

이제 사용자가 내 서버로 어떤 정보를 보내는지 알아내는데 까지 완료되었습니다.

이제 응답을 보내야합니다.

 

응답은 message, keyboard 형태로 응답할수 있습니다.

keyboard 는 버튼 형태로 결과를 주는 것으로 이전 포스팅에서 설명이 되었습니다.

여기서는 단순히 메아리 치는 즉 사용자가 보내는 메세지를 그대로 보내보도록 합니다.

        [HttpPost]
        [Route("message")]
        public dynamic GetKakao_message([FromBody]dynamic value)
        {
            string valueString = JsonConvert.SerializeObject(value);

            KakaoModel postmodel = JsonConvert.DeserializeObject<KakaoModel>(valueString);

            var result = new { message = new { text = postmodel.content }, keyboard = new { type = "text" } };

            return result;
        }

message 의 text 항목에 사용자가 보낸 메세지를 그대로 보냈습니다.

더 설명할건 없는것 같네요;

 

테스트 하기위해 폴더로 게시하고 IIS 올린 후

내 플러스친구와 대화를 나눠보면 아래와 같이 메아리? 치게됩니다.

(처음에 선택1,2,3 버튼이 나와 선택1을 선택하고 그 이후 메세지 보냄.)

 

 

2017/11/21 - [C#.NET/C#] - 카카오 쳇봇 만들기 - 1

 

이전시간에 이어 카카오 쳇봇 두번째 시간에는 서버를 만들어보겠습니다.

비쥬얼 스튜디오를 일단 열고

새 프로젝트를 만들어 아래와 같이 좌측목록에서 을 선택하고 우측에서 ASP.NET 웹 응용 프로그램 을 선택합니다.

아래와 같은 화면이 나오게 되는데 비어 있음 을 선택하고 Web API 는 체크하여 확인합니다.

그럼 아래처럼 프로젝트가 구성됩니다.

이제 카카오가 제시하는 호출 형식으로 웹서비스를 제공해야합니다.

아래처럼 Controllers 폴더 아래에 컨트롤러를 추가합니다.

읽기/쓰기 동작이 표함된 Web API 2 컨트롤러 를 선택하면 예시 코드를 볼수있어서

작성하는데 도움이 많이 됩니다.

도움이 필요없다면 Web API 런트롤러 - 비어있음 을 자신있게 선택하세요!!

컨트롤러가 추가되면 아래처럼 기본적인 Get Post Put Delete 메서드가 구현되어있습니다.

일단 이것을 참고하여 카카도톡이 제시한 http(s)://:your_server_url/keyboard 형식의 GET Method 를 구현해야합니다.

아래 설명에도 나와있지만 keyboard 는 채팅을 처음 시작할때 보여주는 메세지나 버튼을 처리하도록 합니다.

https://github.com/plusfriend/auto_reply#51-home-keyboard-api

GET 방식이므로 기본적으로 아래처럼 작성됩니다.

        [HttpGet]
        public dynamic GetKakao()
        {

            return null;
        }

json 형식을 처리하기위해 dynamic 으로 리턴처리가 되도록 하였습니다.

여기서 중요한건 http(s)://:your_server_url/keyboard 이런형태로 keyboard 로 주소가 끝나게 하여 호출이 되도록 해야합니다.

이를 위해선 [Route("keyboard")] 가 필요합니다.

        [HttpGet]
        [Route("keyboard")]
        public dynamic GetKakao()
        {

            return null;
        }

위처럼 하면 주소에 keyboard 로 호출하게되면 위 메서드가 타게됩니다.

이제 리턴을 아래 json 형태로 전달해야합니다.

{
    "type" : "buttons",
    "buttons" : ["선택 1", "선택 2", "선택 3"]
}

dynamic 을 이용해 위 형태를 만들어 보내면됩니다.

위 내용을 표현한다면 아래처럼 코딩하면됩니다.

            var result = new { type = "buttons", buttons = new List<string>() { "선택1", "선택2", "선택3" } };
            return result;

전체적으로 보면

        [HttpGet]
        [Route("keyboard")]
        public dynamic GetKakao()
        {
            var result = new { type = "buttons", buttons = new List<string>() { "선택1", "선택2", "선택3" } };
            return result;
        }

위처럼 됩니다.

이대로 IIS 올리게되면 플러스친구와 1:1 채팅을 하여 대화방이 열리면 버튼1,2,3 이 나타나게됩니다.

IIS 에 올리는 방법은 우선 빌드한 후 아래와 같이 프로젝트 우클릭 메뉴에서 게시 를 선택합니다.

IIS 에 바로 올릴수도 있지만 전 폴더로 빼서 직접 올렸습니다. 그래서 폴더를 선택하고

게시 버튼을 누르게 되면 게시가 진행됩니다.

게시가 완료되면 해당 경로에 아래처럼 파일이 생성됩니다.

이 파일을 그대로 IIS 에 올리면 됩니다.

IIS 올린 후

https://center-pf.kakao.com/login

으로 이동하여 이전에 추가했던 플러스 친구로 들어가서

좌측의 스마트채팅으로 들어간 후 우측의 API 형 의 설정하기 버튼을 클릭합니다.


아래와 같은 화면에서 API 테스트를 진행해야합니다.

IIS 주소를 넣고 API 테스트 버튼을 클릭하여 아래와 같이 OK 가 떨어져야 제대로 셋팅이 된것입니다.

이제 플러스 친구와 1:1 채팅을 하면 아래와 같이 버튼이 나타나게됩니다.

직접하면 시간이 길지 않은데 포스팅하니 글이 길어지는군요;;;

다음 시간에는 응답형 API 를 이용해 응답처리를 하는것을 해보도록 하겠습니다.

프로젝트 파일을 첨부하고 싶었으나 용량이 커서 안되는군요 ㅜㅠ

+ Recent posts