郵便番号検索API を利用するサンプル

郵便番号検索API を利用して郵便番号から住所を検索するクラスを考えてみました。
郵便番号検索API は無料のサービスで、個人・法人・商用・非商用問わず利用できるたいへん有難いサービスです。ただし無償で公開されてるサービスですので、継続利用が保障されてるわけじゃありません。以下のコードもあくまで 「VB.NET を使ってサービスを利用する場合のサンプル」 ということで了承ください。



以下、郵便番号から住所を検索するクラスです。相変わらずVB ですがw

Option Explicit On
Option Strict On

Imports System.Net
Imports System.Xml
Imports System.Xml.Serialization
Imports System.Text.RegularExpressions


''' <summary>
''' 郵便番号から住所を検索するクラスです。
''' </summary>
Public NotInheritable Class ZipToAddress

#Region "ローカルクラス"

	''' <summary>
	''' サーバーから返却された XML をデシリアライズするローカルクラス
	''' </summary>
	Public Class ZIP_result

		Private _value As Object

		<XmlElement("ADDRESS_value", GetType(Object))> _
		Public Property ADDRESS_value() As Object
			Get
				Return _value
			End Get
			Set(value As Object)
				_value = value
			End Set
		End Property

		Public ReadOnly Property State() As String
			Get
				Return GetValue("state")
			End Get
		End Property

		Public ReadOnly Property City() As String
			Get
				Return GetValue("city")
			End Get
		End Property

		Public ReadOnly Property Address() As String
			Get
				Return GetValue("address")
			End Get
		End Property

		Private Function GetValue(name As String) As String
			Dim ret As String = String.Empty
			If (_value Is Nothing) Then Return ret

			Dim nodes = CType(_value, XmlNode())
			For Each node In nodes
				If (node.Attributes(name) IsNot Nothing) Then
					ret = node.Attributes(name).Value.Replace("none", "")
					Exit For
				End If
			Next
			Return ret
		End Function
	End Class

#End Region

#Region "メソッド"

	Public Shared Function GetAddress(
		zipcode As String, ByRef prefecture As String, ByRef address As String) As Boolean

		Dim ret = False
		' 郵便番号が空なら空白を返却
		If (String.IsNullOrEmpty(zipcode)) Then
			Return ret
		End If

		' 郵便番号か検証(ハイフンは含めない)
		If (Not Regex.IsMatch(zipcode, "^[0-9]{7}$")) Then
			Return ret
		End If

		' [郵便番号検索API] http://zip.cgis.biz/ を利用させて頂いてます。
		Dim url = "http://zip.cgis.biz/xml/zip.php?zn=" + zipcode
		Dim webreq = System.Net.WebRequest.Create(New System.Uri(url))

		' サーバーからの応答を受信するための WebResponse を取得
		Using webres = webreq.GetResponse(),st = webres.GetResponseStream()
			' デシリアライズ
			Dim reader As New XmlTextReader(st)
			Dim serializer As New System.Xml.Serialization.XmlSerializer(
				GetType(ZIP_result),
				New System.Xml.Serialization.XmlRootAttribute("ZIP_result")
			)
			Dim result = CType(serializer.Deserialize(reader), ZIP_result)
			If (result IsNot Nothing) Then
				prefecture = result.State
				address = result.City + result.Address
				ret = True
			End If
		End Using
		Return ret
	End Function

#End Region

End Class

Livet でサンプルを作ってみる

上のクラスを使って Livet でサンプルを作ってみました。

まず ViewModel から実装します。プロパティ2つとコマンド1つ、スニペットを使えば簡単に作成できます。

Public Class MainWindowViewModel
	Inherits ViewModel

#Region "Address変更通知プロパティ"
	Private _Address As String

	Public Property Address() As String
		Get
			Return _Address
		End Get
		Set(ByVal value As String)
			If (_Address = value) Then Return
			_Address = value
			RaisePropertyChanged("Address")
		End Set
	End Property
#End Region

#Region "Zipcode変更通知プロパティ"
	Private _Zipcode As String

	Public Property Zipcode() As String
		Get
			Return _Zipcode
		End Get
		Set(ByVal value As String)
			If (_Zipcode = value) Then Return
			_Zipcode = value
			RaisePropertyChanged("Zipcode")
		End Set
	End Property
#End Region

#Region "SearchCommand"
	Private _SearchCommand As ViewModelCommand

	Public ReadOnly Property SearchCommand() As ViewModelCommand
		Get
			If _SearchCommand Is Nothing Then
				_SearchCommand = New ViewModelCommand(AddressOf Search)
			End If
			Return _SearchCommand
		End Get
	End Property

	Private Sub Search()
		Dim prefecture = ""
		Dim address = ""
		If (ZipToAddress.GetAddress(Me.Zipcode, prefecture, address)) Then
			Me.Address = prefecture + address
		End If
	End Sub
#End Region

End Class


View です。各コントロールは ViewModel のプロパティ・コマンドとバインドさせてます。

<Window x:Class="MainWindow"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
		xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
		xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
		xmlns:local="clr-namespace:ZipcodeSample"
		Title="MainWindow" Height="150" Width="400">
	
	<Window.DataContext>
		<local:MainWindowViewModel />
	</Window.DataContext>
	
	<Grid>
		<Grid.RowDefinitions>
			<RowDefinition />
			<RowDefinition Height="Auto" />
			<RowDefinition Height="8" />
			<RowDefinition Height="Auto" />
			<RowDefinition Height="8" />
			<RowDefinition Height="Auto" />
			<RowDefinition />
		</Grid.RowDefinitions>
		<Grid.ColumnDefinitions>
			<ColumnDefinition Width="8" />
			<ColumnDefinition Width="80" />
			<ColumnDefinition />
			<ColumnDefinition Width="8" />
		</Grid.ColumnDefinitions>
		<TextBlock Grid.Row="1" Grid.Column="1" Text="郵便番号" VerticalAlignment="Center" 
				HorizontalAlignment="Right" Margin="0,0,8,0" />
		<TextBox Grid.Row="1" Grid.Column="2" Text="{Binding Zipcode}" />
		<TextBlock Grid.Row="3" Grid.Column="1" Text="住所" VerticalAlignment="Center" 
				HorizontalAlignment="Right" Margin="0,0,8,0" />
		<TextBox Grid.Row="3" Grid.Column="2" Text="{Binding Address}" />
		<Button Grid.Row="5" Grid.Column="2" Content="検索" Command="{Binding SearchCommand}" 
				HorizontalAlignment="Right" Width="80" />
	</Grid>
</Window>