ASMX(ASP.NET 웹 서비스) 사용

Download Sample 샘플 다운로드

ASMX는 SOAP(Simple Object Access Protocol)를 사용하여 메시지를 보내는 웹 서비스를 빌드하는 기능을 제공합니다. SOAP는 웹 서비스를 빌드하고 액세스하기 위한 플랫폼 독립적 언어 독립적 프로토콜입니다. ASMX 서비스의 소비자는 서비스를 구현하는 데 사용되는 플랫폼, 개체 모델 또는 프로그래밍 언어에 대해 아무것도 알 필요가 없습니다. SOAP 메시지를 보내고 받는 방법만 이해하면 됩니다. 이 문서에서는 애플리케이션에서 Xamarin.Forms ASMX SOAP 서비스를 사용하는 방법을 보여 줍니다.

SOAP 메시지는 다음 요소를 포함하는 XML 문서입니다.

  • XML 문서를 SOAP 메시지로 식별하는 Envelope라는 루트 요소입니다.
  • 인증 데이터와 같은 애플리케이션 관련 정보를 포함하는 선택적 Header 요소입니다. Header 요소가 있으면 Envelope 요소의 첫 번째 자식 요소여야 합니다.
  • 받는 사람을 위한 SOAP 메시지를 포함하는 필수 Body 요소입니다.
  • 오류 메시지를 나타내는 데 사용되는 선택적 Fault 요소입니다. Fault 요소가 있는 경우 Body 요소의 자식 요소여야 합니다.

SOAP는 HTTP, SMTP, TCP 및 UDP를 비롯한 많은 전송 프로토콜에 대해 작동할 수 있습니다. 그러나 ASMX 서비스는 HTTP를 통해서만 작동할 수 있습니다. Xamarin 플랫폼은 HTTP를 통한 표준 SOAP 1.1 구현을 지원하며, 여기에는 많은 표준 ASMX 서비스 구성에 대한 지원이 포함됩니다.

이 샘플에는 물리적 또는 에뮬레이트된 디바이스에서 실행되는 모바일 애플리케이션과 데이터를 가져오기, 추가, 편집 및 삭제하는 메서드를 제공하는 ASMX 서비스가 포함됩니다. 모바일 애플리케이션이 실행되면 다음 스크린샷과 같이 로컬로 호스팅되는 ASMX 서비스에 연결합니다.

Sample Application

참고 항목

iOS 9 이상에서 ATS(App Transport Security)는 인터넷 리소스(예: 앱의 백 엔드 서버)와 앱 간에 보안 연결을 적용하여 중요한 정보의 우발적인 공개를 방지합니다. ATS는 iOS 9용으로 빌드된 앱에서 기본적으로 사용하도록 설정되므로 모든 연결에는 ATS 보안 요구 사항이 적용됩니다. 연결이 이러한 요구 사항을 충족하지 않으면 예외로 실패합니다. 인터넷 리소스에 대한 프로토콜 및 보안 통신을 사용할 HTTPS 수 없는 경우 ATS를 옵트아웃할 수 있습니다. 이 작업은 앱의 Info.plist 파일을 업데이트하여 수행할 수 있습니다. 자세한 내용은 App Transport Security를 참조 하세요.

웹 서비스 사용

ASMX 서비스는 다음 작업을 제공합니다.

연산 설명 매개 변수
GetTodoItems 할 일 항목의 목록 가져오기
CreateTodoItem 새 할 일 항목 만들기 직렬화된 XML TodoItem
EditTodoItem 할 일 항목 업데이트 직렬화된 XML TodoItem
DeleteTodoItem 할 일 항목 삭제 직렬화된 XML TodoItem

애플리케이션에서 사용되는 데이터 모델에 대한 자세한 내용은 데이터 모델링을 참조하세요.

TodoService 프록시 만들기

호출 TodoService된 프록시 클래스는 HTTP를 SoapHttpClientProtocol 통해 ASMX 서비스와 통신하기 위한 메서드를 확장하고 제공합니다. 프록시는 Visual Studio 2019 또는 Visual Studio 2017의 각 플랫폼별 프로젝트에 웹 참조를 추가하여 생성됩니다. 웹 참조는 서비스의 WSDL(Web Services Description Language) 문서에 정의된 각 작업에 대한 메서드와 이벤트를 생성합니다.

예를 들어 GetTodoItems 서비스 작업으로 인해 프록시에서 GetTodoItemsAsync 메서드와 GetTodoItemsCompleted 이벤트가 발생합니다. 생성된 메서드는 void 반환 형식을 가지고 있으며 부모 SoapHttpClientProtocol 클래스에서 GetTodoItems 동작을 호출합니다. 호출된 메서드는 서비스에서 응답을 받으면 이벤트를 발생 GetTodoItemsCompleted 시키고 이벤트 Result 속성 내에서 응답 데이터를 제공합니다.

ISoapService 구현 만들기

공유 플랫폼 간 프로젝트가 서비스와 함께 작동할 수 있도록 이 샘플은 C#의 작업 비동기 프로그래밍 모델을 따르는 인터페이스를 정의 ISoapService 합니다. 각 플랫폼은 ISoapService 플랫폼별 프록시를 노출하도록 구현합니다. 샘플에서는 개체를 사용하여 TaskCompletionSource 프록시를 작업 비동기 인터페이스로 노출합니다. 사용에 TaskCompletionSource 대한 자세한 내용은 아래 섹션의 각 작업 유형 구현에서 확인할 수 있습니다.

샘플 SoapService:

  1. 클래스 수준 인스턴스로 인스턴스화 TodoService
  2. 개체를 저장 TodoItem 하기 위해 호출되는 Items 컬렉션을 만듭니다.
  3. 의 선택적 Url 속성에 대한 사용자 지정 엔드포인트를 지정합니다. TodoService
public class SoapService : ISoapService
{
    ASMXService.TodoService todoService;
    public List<TodoItem> Items { get; private set; } = new List<TodoItem>();

    public SoapService ()
    {
        todoService = new ASMXService.TodoService ();
        todoService.Url = Constants.SoapUrl;
        ...
    }
}

데이터 전송 개체 만들기

샘플 애플리케이션은 클래스를 TodoItem 사용하여 데이터를 모델링합니다. 웹 서비스에 항목을 저장 TodoItem 하려면 먼저 프록시 생성 TodoItem 형식으로 변환해야 합니다. 이 작업은 다음 코드 예제와 같이 메서드에 의해 ToASMXServiceTodoItem 수행됩니다.

ASMXService.TodoItem ToASMXServiceTodoItem (TodoItem item)
{
    return new ASMXService.TodoItem {
        ID = item.ID,
        Name = item.Name,
        Notes = item.Notes,
        Done = item.Done
    };
}

이 메서드는 새 ASMService.TodoItem 인스턴스를 만들고 각 속성을 인스턴스에서 동일한 속성으로 TodoItem 설정합니다.

마찬가지로 웹 서비스에서 데이터를 검색할 때 프록시 생성 TodoItem 형식에서 인스턴스로 TodoItem 변환해야 합니다. 이 작업은 다음 코드 예제와 같이 메서드를 사용하여 수행 FromASMXServiceTodoItem 됩니다.

static TodoItem FromASMXServiceTodoItem (ASMXService.TodoItem item)
{
    return new TodoItem {
        ID = item.ID,
        Name = item.Name,
        Notes = item.Notes,
        Done = item.Done
    };
}

이 메서드는 프록시 생성 TodoItem 형식에서 데이터를 검색하고 새로 만든 TodoItem 인스턴스에서 설정합니다.

데이터 검색

인터페이스는 ISoapService 메서드가 RefreshDataAsync 항목 컬렉션과 Task 함께 반환해야 합니다. 그러나 메서드는 void를 TodoService.GetTodoItemsAsync 반환합니다. 인터페이스 패턴을 충족하려면 호출 GetTodoItemsAsync하고 이벤트가 발생할 때까지 기다렸다가 GetTodoItemsCompleted 컬렉션을 채워야 합니다. 이렇게 하면 유효한 컬렉션을 UI에 반환할 수 있습니다.

아래 예제에서는 새 TaskCompletionSource메서드를 만들고 메서드에서 비동기 호출을 RefreshDataAsync 시작하고 제공된 TaskCompletionSource메서드를 기다립니다Task. TodoService_GetTodoItemsCompleted 이벤트 처리기가 호출되면 컬렉션이 Items 채워지고 다음이 TaskCompletionSource업데이트됩니다.

public class SoapService : ISoapService
{
    TaskCompletionSource<bool> getRequestComplete = null;
    ...

    public SoapService()
    {
        ...
        todoService.GetTodoItemsCompleted += TodoService_GetTodoItemsCompleted;
    }

    public async Task<List<TodoItem>> RefreshDataAsync()
    {
        getRequestComplete = new TaskCompletionSource<bool>();
        todoService.GetTodoItemsAsync();
        await getRequestComplete.Task;
        return Items;
    }

    private void TodoService_GetTodoItemsCompleted(object sender, ASMXService.GetTodoItemsCompletedEventArgs e)
    {
        try
        {
            getRequestComplete = getRequestComplete ?? new TaskCompletionSource<bool>();

            Items = new List<TodoItem>();
            foreach (var item in e.Result)
            {
                Items.Add(FromASMXServiceTodoItem(item));
            }
            getRequestComplete?.TrySetResult(true);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(@"\t\tERROR {0}", ex.Message);
        }
    }

    ...
}

자세한 내용은 비동기 프로그래밍 모델 및 TPL 및 기존 .NET Framework 비동기 프로그래밍을 참조하세요.

데이터 만들기 또는 편집

데이터를 만들거나 편집할 때 메서드를 ISoapService.SaveTodoItemAsync 구현해야 합니다. 이 메서드는 새 항목인지 업데이트된 항목인지를 TodoItem 검색하고 개체에 적절한 메서드를 todoService 호출합니다. CreateTodoItemCompleted ASMX 서비스에서 응답을 받은 시점 todoService 을 알 수 있도록 이벤트 처리기 및 EditTodoItemCompleted 이벤트 처리기도 구현해야 합니다(동일한 작업을 수행하기 때문에 단일 처리기로 결합할 수 있습니다). 다음 예제에서는 인터페이스 및 이벤트 처리기 구현뿐만 TaskCompletionSource 아니라 비동기적으로 작동하는 데 사용되는 개체를 보여 줍니다.

public class SoapService : ISoapService
{
    TaskCompletionSource<bool> saveRequestComplete = null;
    ...

    public SoapService()
    {
        ...
        todoService.CreateTodoItemCompleted += TodoService_SaveTodoItemCompleted;
        todoService.EditTodoItemCompleted += TodoService_SaveTodoItemCompleted;
    }

    public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
    {
        try
        {
            var todoItem = ToASMXServiceTodoItem(item);
            saveRequestComplete = new TaskCompletionSource<bool>();
            if (isNewItem)
            {
                todoService.CreateTodoItemAsync(todoItem);
            }
            else
            {
                todoService.EditTodoItemAsync(todoItem);
            }
            await saveRequestComplete.Task;
        }
        catch (SoapException se)
        {
            Debug.WriteLine("\t\t{0}", se.Message);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("\t\tERROR {0}", ex.Message);
        }
    }

    private void TodoService_SaveTodoItemCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        saveRequestComplete?.TrySetResult(true);
    }

    ...
}

데이터 삭제

데이터를 삭제하려면 비슷한 구현이 필요합니다. 정의, TaskCompletionSource이벤트 처리기 구현 및 ISoapService.DeleteTodoItemAsync 메서드:

public class SoapService : ISoapService
{
    TaskCompletionSource<bool> deleteRequestComplete = null;
    ...

    public SoapService()
    {
        ...
        todoService.DeleteTodoItemCompleted += TodoService_DeleteTodoItemCompleted;
    }

    public async Task DeleteTodoItemAsync (string id)
    {
        try
        {
            deleteRequestComplete = new TaskCompletionSource<bool>();
            todoService.DeleteTodoItemAsync(id);
            await deleteRequestComplete.Task;
        }
        catch (SoapException se)
        {
            Debug.WriteLine("\t\t{0}", se.Message);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("\t\tERROR {0}", ex.Message);
        }
    }

    private void TodoService_DeleteTodoItemCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        deleteRequestComplete?.TrySetResult(true);
    }

    ...
}

웹 서비스 테스트

로컬 호스팅 서비스를 사용하여 물리적 또는 에뮬레이트된 디바이스를 테스트하려면 사용자 지정 IIS 구성, 엔드포인트 주소 및 방화벽 규칙이 있어야 합니다. 테스트를 위해 환경을 설정하는 방법에 대한 자세한 내용은 IIS Express대한 원격 액세스 구성을 참조하세요. WCF와 ASMX 테스트의 유일한 차이점은 TodoService의 포트 번호입니다.