Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters
-
Upload
dynamicscom -
Category
Technology
-
view
3.394 -
download
0
description
Transcript of Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters
![Page 1: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/1.jpg)
Integrating Windows Phone 7 to Microsoft Dynamics NAV 2009R2
Eric Wauters
1
Development ManageriFacto Business Solutions NVWaldo’s blog (www.waldo.be)
![Page 2: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/2.jpg)
2
Integrating Windows Phone 7 to Microsoft Dynamics NAV 2009R2
Eric WautersBackup for Freddy Kristiansen
![Page 3: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/3.jpg)
Agenda
• Cloud? What is that all about? We’re all in .. but in what?
• Building a Windows Phone app that connects to NAV using the cloud.
![Page 4: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/4.jpg)
Cloud computing?
Cloud computing is a pay-per-use model for enabling available, convenient, on-demand network access to a shared pool of configurable computing resources (e.g., networks, servers,
storage, applications, services) that can be rapidly provisioned and released with minimal management effort or service
provider interaction.
![Page 5: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/5.jpg)
Cloud Computing?
![Page 6: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/6.jpg)
Cloud Computing?
Rapid elasticity
Pay per use
Location independent resource pooling
Standard network access
On-demand self-service
Char
acte
ristic
s
![Page 7: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/7.jpg)
Enterprise Cloud Triggers – DriversSpeed to Value1
Flexibility2
Cross Organizational Collaboration3
Cost Reduction 4
CapEx Avoidance5
Green IT6
![Page 8: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/8.jpg)
CapEx Avoidance – Traditional IT
TIME
IT C
APAC
ITY
Actual Load
Allocated IT-capacities
“Waste“ of capacities
“Under-supply“ of capacities
Fixed cost of IT-capacities
Load Forecast
Barrier forinnovations
![Page 9: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/9.jpg)
CapEx Avoidance – Cloud
Actual Load
Allocated IT capacities
Reduction of initial
investments
Reduction of “over-supply“
No “under-supply“
Possible reduction of IT-
capacities in case of reduced
load
Time
IT C
APAC
ITY
Load Forecast
![Page 10: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/10.jpg)
Microsoft Online Services Platform
ON-PREMISES
BUSINESS APPSCOLLABORATION STORAGE PLATFORMIDENTITYCOMMUNICATIONSPRODUCTIVITY
CLOUD SERVICES
![Page 11: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/11.jpg)
SERVICE ORDERS
![Page 12: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/12.jpg)
Components in play
• NAV– Service Dispatchers RoleCenter– Customizations– Web Services, .net interop
• Proxy– C# Windows Service– Connecting to NAV Web Services– Exposing API on the Service Bus
• Windows Phone 7– Silverlight Application
• Cloud– Windows Azure Account
![Page 13: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/13.jpg)
Windows AzureStorage
Service BusServices
Components - flow
NAVService
Tier
Firewall
Upload image
Register Notification
Channel
Window
s Auth
ProxySend Toast Notification
Services
Expose Proxy API on Azure AppFabric
Download image
Send Toast Notification
Get Service OrdersAccept Service Order
Change Order Status – In
ProcessChange Order Status –
FinishedAttach image URLAttach Note
Get Notification Channel Uri
Show map / Calculate route
![Page 14: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/14.jpg)
SERVICE ORDERS – DEMO?
![Page 15: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/15.jpg)
NAV customizations• Service Order card
– On Creating/Modifying Service Orders
• Send notifications (.net interop)
– Related Information – Images
• Download images from Azure storage
• Service Order Image table
• Exposes Web Services– For the Proxy
• Customer Card Page
• Service Order Card Page
• Special build Codeunit
NAVService
Tier
![Page 16: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/16.jpg)
Windows Phone 7 Application• Connecting to NAV Web Services
– Via the Service Bus
• Get Service Orders
• Accept Service Order
• Change status on Service Order
• Attach images and notes to service orders
• Register notification channel (plumbing)
• Connecting to Azure Storage– To storage images
![Page 17: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/17.jpg)
Windows Phone 7• Free Developer tools
– http://create.msdn.com/en-US/
– .net, C#, Silverlight
– Microsoft
• A TON of stuff on how to develop applications for Windows Phone already out there
![Page 18: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/18.jpg)
Https Web Services Proxy - API
[ServiceContract]public interface IServiceOrderProxyClass{ [OperationContract] ServiceOrder[] GetServiceOrders(string username, string password);
[OperationContract] bool AcceptServiceOrder(string username, string password, string no);
[OperationContract] void ChangeServiceOrderStatus(string username, string password, string no, string status);
[OperationContract] void AttachServiceOrderImage(string username, string password, string no, string blobName);
[OperationContract] void AttachServiceOrderNote(string username, string password, string no, string note);
[OperationContract] void RegisterWp7ChannelUri(string username, string password, string channelUri);}
![Page 19: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/19.jpg)
Https Web Services Proxy• Exposes endpoint on the Service Bus
• Connects to NAV Web Services
• Dedicated for Service Orders scenario
• Only expose necessary API– Isolating NAV from attacks
• Removes complexity
• Reduces roundtrips
• Loose coupling (device / NAV)– Possible to use other devices
![Page 20: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/20.jpg)
Windows Azure Account• Windows Azure AppFabric (Service Bus)
– For communication between phone and on-premise NAV
• IssuerName, IssuerSecret
• Windows Azure Storage– For image storing / retrieving
• AccountName, AccessKey
![Page 21: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/21.jpg)
STEP BY STEPWalkthrough
![Page 22: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/22.jpg)
Exposing an API on Windows Azure AppFabric
NAVService
Tier
Firewall
Service Bus
Window
s Auth
ProxyExpose Proxy API on Azure AppFabric
![Page 23: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/23.jpg)
Exposing an API on Windows Azure AppFabric
• Proxy– Create ServiceHost
– Add ServiceBus Endpoints
– Set Shared Secret credentials on endpoints
• IssuerName, IssuerSecret
– Start Servicehost
• Windows Azure AppFabric SDK– http://
www.microsoft.com/downloads/en/details.aspx?FamilyID=39856a03-1490-4283-908f-c8bf0bfad8a5
var serviceHost = new ServiceHost(new ServiceOrderProxyClass());
// sb:// bindingUri sbUri = ServiceBusEnvironment.CreateServiceUri("sb", "iFactoCloudDemo", instanceId);var sbBinding = new NetTcpRelayBinding(EndToEndSecurityMode.Transport, RelayClientAuthenticationType.None);serviceHost.AddServiceEndpoint(typeof(IServiceOrderProxyClass), sbBinding, sbUri);
// https:// binding (for Windows Phone etc.)Uri httpsUri = ServiceBusEnvironment.CreateServiceUri("https", "iFactoCloudDemo", "https/" + instanceId);var httpsBinding = new BasicHttpRelayBinding(EndToEndBasicHttpSecurityMode.Transport, RelayClientAuthenticationType.None);serviceHost.AddServiceEndpoint(typeof(IServiceOrderProxyClass), httpsBinding, httpsUri);
// Setup Shared Secret Credentials for hosting endpoints on the Service BusTransportClientEndpointBehavior sharedSecretServiceBusCredential = new TransportClientEndpointBehavior();sharedSecretServiceBusCredential.CredentialType = TransportClientCredentialType.SharedSecret;sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerName = issuerName;sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerSecret = issuerSecret;
// Set credentials on all endpoints on the Service Busforeach (ServiceEndpoint endpoint in serviceHost.Description.Endpoints) endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
serviceHost.Open();
![Page 24: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/24.jpg)
Register Notification Channel
NAVService
Tier
Firewall
Service Bus
Window
s Auth
ProxyExpose Proxy API on Azure AppFabric
Register Notification
Channel
Get Notification Channel Uri
![Page 25: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/25.jpg)
• Phone– Creates a NotificationChannel using Windows Phone API
– Invokes RegisterWp7ChannelUri in Proxy through Web Services
• Proxy– Authenticates phone user
– Invokes RegisterWp7ChannelUri in Codeunit through Web Services
• NAV – Update/Insert record in Wp7Channel table
Register Notification Channelpublic void RegisterWp7ChannelUri(string username, string password, string channelUri){ var service = new ServiceOrderRef.ServiceOrder(); Authenticate(service, username, password); service.RegisterWp7ChannelUri("ServiceOrders", channelUri);}
RegisterWp7ChannelUri(Application : Text[40];ChannelUri : Text[250])Wp7Channel.SETRANGE(UserID, USERID);Wp7Channel.SETRANGE(Application, Application);IF Wp7Channel.FINDFIRST THENBEGIN Wp7Channel.ChannelUri := ChannelUri; Wp7Channel.MODIFY();END ELSEBEGIN CLEAR(Wp7Channel); Wp7Channel.INIT(); Wp7Channel.UserID := USERID; Wp7Channel.Application := Application; Wp7Channel.ChannelUri := ChannelUri; Wp7Channel.INSERT();END;
... HttpNotificationChannel.Find("waldo.ServiceOrders"); if (myChannel == null) { myChannel = new HttpNotificationChannel("waldo.ServiceOrders"); } SendURIToService(myChannel.ChannelUri); ...
private void SendURIToService(Uri uri){ var client = App.GetServiceOrderProxyClient(); client.RegisterWp7ChannelUriAsync(App.Settings.UserName, App.Settings.Password, uri.AbsoluteUri);}
![Page 26: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/26.jpg)
Send Notification
NAVService
Tier
Firewall
Service Bus
Wndow
s Auth
ProxyExpose Proxy API on Azure AppFabricSend Toast Notification
Send Toast Notification
![Page 27: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/27.jpg)
Send Toast Notification• NAV
– Loop through Wp7Channel table
– Using a WP7Helper class to send the notification (.Net Interop)
• Create XML Document
• Error handling
• Send request using HttpWebRequest / HttpWebResponse
BroadcastToastNotification(Application : Text[40];Header : Text[40];Text : Text[40])Wp7Channel.SETRANGE(Wp7Channel.Application, Application);IF Wp7Channel.FINDSET THEN BEGIN REPEAT Wp7Notifications.DoSendToastNotification(Wp7Channel.ChannelUri,2,Header,Text); UNTIL Wp7Channel.NEXT = 0;END;
DoSendToastNotification(Wp7Channel : Record Wp7Channel;Priority : Integer;Text1 : Text[40];Text2 : Text[40])IF Wp7Channel.NextAttempt > CURRENTDATETIME THEN EXIT;status := Wp7Helper.SendToastNotification(Wp7Channel.ChannelUri, Priority, Text1, Text2);//MESSAGE(FORMAT(status));CASE status OF1: BEGIN // Invalid Uri Wp7Channel.DELETE(); END;2: BEGIN // Queue Full - Wait one hour before reattempting this Uri Wp7Channel.NextAttempt := CURRENTDATETIME + 3600000; Wp7Channel.MODIFY; END;3: BEGIN // Service Unavailable - Wait one hour before reattempting this Uri Wp7Channel.NextAttempt := CURRENTDATETIME + 3600000; Wp7Channel.MODIFY; END;END;
![Page 28: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/28.jpg)
Get Service Orders
NAVService
Tier
Firewall
Service Bus
Window
s Auth
ProxyExpose Proxy API on Azure AppFabric
Get Service Orders
![Page 29: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/29.jpg)
GetServiceOrders• Phone
– Invoke GetServiceOrders in Proxy through Web Services
• Proxy– Reads Service Orders from card page
• Assigned to me
• Assigned to nobody
– Builds and returns ServiceOrderProxyClass collection
• With Customer info read from Customer Card
• Phone– Calculate distance from current location to each service location
– Update Collections (assigned, prioritized, closest)
private double CalculateDistance(double lat1, double lon1, double lat2, double lon2, char unit){ double theta = lon1 - lon2; double dist = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * Math.Cos(deg2rad(theta)); dist = rad2deg(Math.Acos(dist)) * 60 * 1.1515; if (unit == 'K') dist = dist * 1.609344; return (dist);}
private double deg2rad(double deg){ return (deg * Math.PI / 180.0);}
void LoadServiceOrders(){ var client = App.GetServiceOrderProxyClient(); client.GetServiceOrdersCompleted += new EventHandler<ServiceOrderProxy.GetServiceOrdersCompletedEventArgs>(client_GetServiceOrdersCompleted); client.GetServiceOrdersAsync(App.Settings.UserName, App.Settings.Password);}
void client_GetServiceOrdersCompleted(object sender, ServiceOrderProxy.GetServiceOrdersCompletedEventArgs e){ this.All.Clear(); foreach (ServiceOrderProxy.ServiceOrder serviceOrder in e.Result) { serviceOrder.Distance = CalculateDistance(CurrentLocation.Latitude, CurrentLocation.Longitude, serviceOrder.Latitude, serviceOrder.Longitude, unit); this.All.Add(serviceOrder); } UpdateCollections();}
public ServiceOrder[] GetServiceOrders(string username, string password){ ... var myFilter = new ServiceOrderCardRef.ServiceOrderCard_Filter(); myFilter.Field = ServiceOrderCardRef.ServiceOrderCard_Fields.Assigned_User_ID; myFilter.Criteria = "@" + service.GetMyUserID(); var myFilters = new ServiceOrderCardRef.ServiceOrderCard_Filter[] { myFilter }; var myOrders = serviceOrderService.ReadMultiple(myFilters, null, 0);
var unassignedFilter = new ServiceOrderCardRef.ServiceOrderCard_Filter(); unassignedFilter.Field = ServiceOrderCardRef.ServiceOrderCard_Fields.Assigned_User_ID; unassignedFilter.Criteria = "=''"; var unassignedFilters = new ServiceOrderCardRef.ServiceOrderCard_Filter[] { unassignedFilter }; var unassignedOrders = serviceOrderService.ReadMultiple(unassignedFilters, null, 0);
var serviceOrders = new ServiceOrder[myOrders.Length + unassignedOrders.Length]; for (int i = 0; i < myOrders.Length; i++) serviceOrders[i] = ServiceOrder.CreateServiceOrderClass(myOrders[i], customerCardService.Read(myOrders[i].Customer_No));
for (int i = 0; i < unassignedOrders.Length; i++) serviceOrders[i + myOrders.Length] = ServiceOrder.CreateServiceOrderClass(unassignedOrders[i], customerCardService.Read(unassignedOrders[i].Customer_No)); return serviceOrders;}
![Page 30: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/30.jpg)
Accept Service Order
NAVService
Tier
Firewall
Service Bus
Window
s Auth
ProxyExpose Proxy API on Azure AppFabric
Accept Service Order
![Page 31: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/31.jpg)
• Phone– Ask user if he wants to accept the Service Order
– Invoke AcceptServiceOrder in Proxy through Web Services
• Proxy– Read the Service Order from the Card Page through Web Services
– If the Service Order is assigned already – return false
– Set the Assigned_User_ID
– Write the Service Order again – if error – return false
• Phone– Display message and refresh data
Accept Service Order
void acceptAction_Click(object sender, EventArgs e){ if (MessageBox.Show("Do you want to accept this Service Order?", "Accept", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { var client = App.GetServiceOrderProxyClient(); client.AcceptServiceOrderCompleted += new EventHandler<ServiceOrderProxy.AcceptServiceOrderCompletedEventArgs>(client_AcceptServiceOrderCompleted); client.AcceptServiceOrderAsync(App.Settings.UserName, App.Settings.Password, this.ServiceOrder.No); } }
public bool AcceptServiceOrder(string username, string password, string no){ var service = new ServiceOrderRef.ServiceOrder(); Authenticate(service, username, password);
var serviceOrderService = new ServiceOrderCardRef.ServiceOrderCard_Service(); Authenticate(serviceOrderService, username, password);
var serviceOrder = serviceOrderService.Read(no); if (!string.IsNullOrEmpty(serviceOrder.Assigned_User_ID)) return false; serviceOrder.Assigned_User_ID = service.GetMyUserID(); try { serviceOrderService.Update(ref serviceOrder); return true; } catch { return false; }}
void client_AcceptServiceOrderCompleted(object sender, ServiceOrderProxy.AcceptServiceOrderCompletedEventArgs e){ Deployment.Current.Dispatcher.BeginInvoke(() => { if (e.Result) { MessageBox.Show("ServiceOrder is now assigned to you!"); this.AssignedToMe = true; } else MessageBox.Show("ServiceOrder was already assigned to someone else"); App.ViewModel.LoadData(); UpdateApplicationBarButtons(); });}
![Page 32: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/32.jpg)
Change Service Order Status
NAVService
Tier
Firewall
Service Bus
Window
s Auth
ProxyExpose Proxy API on Azure AppFabric
Change Service Order
Status
![Page 33: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/33.jpg)
Change Service Order Status• Phone
– Change status on Service Order internally
– Invoke ChangeServiceOrderStatus in Proxy through Web Services
• Proxy– Read Service Order from the Card Page through Web Services
– Set the Status
– Update Starting Date/Time or Finishing Date/Time if necessary
– Write the Service Order again
private void ChangeServiceOrderStatus(ServiceOrderProxy.ServiceOrder serviceOrder, string status){ serviceOrder.Status = status; var client = App.GetServiceOrderProxyClient(); client.ChangeServiceOrderStatusAsync(App.Settings.UserName, App.Settings.Password, serviceOrder.No, status);}
public void ChangeServiceOrderStatus(string username, string password, string no, string statusStr){ var serviceOrderService = new ServiceOrderCardRef.ServiceOrderCard_Service(); Authenticate(serviceOrderService, username, password);
var status = (Status)Enum.Parse(typeof(Status), statusStr.Replace(' ', '_'), true); var serviceOrder = serviceOrderService.Read(no); serviceOrder.Status = status; serviceOrderService.Update(ref serviceOrder);}
![Page 34: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/34.jpg)
Capture and Upload Image
NAVService
Tier
Firewall
Service Bus
Window
s Auth
ProxyExpose Proxy API on Azure AppFabric
Storage
Upload image
![Page 35: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/35.jpg)
Capture and upload Image• Delay’s Blog
– http://blogs.msdn.com/b/delay/
– Blob API for Windows Phone 7
• Ms-PL (http://opensource.org/licenses/ms-pl.html)
• Phone– Capture Image
– Resize image
• to save time when uploading
– Upload image to Azure Storage
void cameraTask_Completed(object sender, PhotoResult e){ if (e.TaskResult == TaskResult.OK) { // Using WriteableBitmap's SaveJpeg to resize var bitmapImage = new BitmapImage(); bitmapImage.SetSource(e.ChosenPhoto); var bitmap = new WriteableBitmap(bitmapImage); var ms = new MemoryStream(); bitmap.SaveJpeg(ms, 1024, 768, 0, 90); var photo = ms.ToArray();
// Upload photo blobClient = new AzureBlobStoreClient(AzureStorageAccountName, AzureStoragePrimaryAccessKey, "images"); blobInfo = new BlobInfo(Guid.NewGuid().ToString()); blobClient.PutBlob(blobInfo, photo.Length, (s) => PutBlobAction(s, photo), PutBlobCompleted, (ex) => PutBlobFailed(ex)); }}
... CameraCaptureTask cameraTask; ... cameraTask = new CameraCaptureTask(); cameraTask.Completed += new EventHandler<PhotoResult>(cameraTask_Completed); ...
void cameraAction_Click(object sender, EventArgs e){ cameraTask.Show(); //shows camera to take the picture}
void PutBlobAction(Stream s, byte[] photo){ s.Write(photo, 0, photo.Length);}
void PutBlobCompleted(){ Deployment.Current.Dispatcher.BeginInvoke(() => AttachServiceOrderImage(this.ServiceOrder, blobInfo.Name));}
private void PutBlobFailed(Exception ex){ Deployment.Current.Dispatcher.BeginInvoke(() => MessageBox.Show("No connectivity.”));}
![Page 36: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/36.jpg)
Attach Image / Note
NAVService
Tier
Firewall
Service Bus
Window
s Auth
ProxyExpose Proxy API on Azure AppFabric
Attach Image / Note
Storage
![Page 37: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/37.jpg)
Attach Image / Note• Phone
– Invoke AttachServiceOrderImage/Note in Proxy through Web Services with Uri to Azure Storage blob or note
– Display message box when image uploaded
• Proxy– Invoke AttachServiceOrderImage/Note in NAV Codeunit through Web
Services with Uri or note
• NAV– Insert Image Uri in ServiceOrderImage Table or add note to RecordLink
table
private void AttachServiceOrderImage(ServiceOrderProxy.ServiceOrder serviceOrder, string blobName){ var client = App.GetServiceOrderProxyClient(); client.AttachServiceOrderImageCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_AttachServiceOrderImageCompleted); client.AttachServiceOrderImageAsync(App.Settings.UserName, App.Settings.Password, serviceOrder.No, blobName);}
void client_AttachServiceOrderImageCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e){ Deployment.Current.Dispatcher.BeginInvoke(() => MessageBox.Show("Image uploaded.")); }
private void Save_Click(object sender, EventArgs e){ var client = App.GetServiceOrderProxyClient(); client.AttachServiceOrderNoteAsync(App.Settings.UserName, App.Settings.Password, ID, this.textBox1.Text); NavigationService.GoBack();}
public void AttachServiceOrderImage(string username, string password, string no, string blobName){ var service = new ServiceOrderRef.ServiceOrder(); Authenticate(service, username, password); service.AttachServiceOrderImage(no, blobName);}
public void AttachServiceOrderNote(string username, string password, string no, string note){ var service = new ServiceOrderRef.ServiceOrder(); Authenticate(service, username, password); service.AttachServiceOrderNote(no, note);}
AttachServiceOrderImage(No : Code[20];Image : Text[40])ServiceOrderImage.INIT;ServiceOrderImage."Document No." := No;ServiceOrderImage."Image ID" := Image;ServiceOrderImage.INSERT(TRUE);
AttachServiceOrderNote(No : Code[20];Note : Text[250])ServiceHeader.GET(ServiceHeader."Document Type"::Order, No);RecRef.GETTABLE(ServiceHeader);RecordLink.INIT();RecordLink.Type := RecordLink.Type::Note;RecordLink.Created := CURRENTDATETIME;RecordLink."User ID" := USERID;RecordLink.URL1 := 'dynamicsnav://freddyk-appfabr:7047/DynamicsNAV/'+COMPANYNAME+'/runpage?page=5900&personalization=5900&'+ 'bookmark='+FORMAT(RecRef.RECORDID,0,10)+'&mode=edit';RecordLink.Description := 'Service Order - '+No;RecordLink.Company := COMPANYNAME;RecordLink."Record ID" := RecRef.RECORDID;CLEAR(RecordLink.Note);Note := ' '+Note;Note[1] := STRLEN(Note)-1;NoteText.ADDTEXT(Note);RecordLink.Note.CREATEOUTSTREAM(NoteStream);NoteText.WRITE(NoteStream);RecordLink.INSERT();
![Page 38: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/38.jpg)
Download and display image
NAVService
Tier
Firewall
Service Bus
Window
s Auth
ProxyExpose Proxy API on Azure AppFabric
Storage
Download image
![Page 39: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/39.jpg)
• NAV– Create .net class AzureStorage
• Using AccountName and AccessKey
• Wrapper for AzureBlobStoreClient (Delay’s Blog)
– Download all blobs for a specific Service Order to the Service Tier
– Use File.Download to show images on the Client
Download and display image
<Action1170000001> - OnAction()AzureStorage := AzureStorage.AzureStorage(AzureStorageAccountName, AzureStorageAccessKey);ServiceOrderImage.SETRANGE(ServiceOrderImage."Document No.", "No.");IF NOT ServiceOrderImage.FIND('-') THENBEGIN MESSAGE('No Images attached');END ELSEREPEAT AzureStorage.GetBlob('images', ServiceOrderImage."Image ID", TEMPORARYPATH+ServiceOrderImage."Image ID"+'.jpg'); toFile := ServiceOrderImage."Image ID"+'.jpg'; FILE.DOWNLOAD(TEMPORARYPATH+ServiceOrderImage."Image ID"+'.jpg', 'Service Order Image','', '', toFile);UNTIL ServiceOrderImage.NEXT = 0;
public class AzureStorage{ string AccountName; string AccessKey;
public AzureStorage(string AccountName, string AccessKey) { this.AccountName = AccountName; this.AccessKey = AccessKey; }
public void GetBlob(string container, string name, string filename) { EnsureContainerIsCreated(container); var blobClient = new AzureBlobStoreClient(AccountName, AccessKey, container); var blobInfo = new BlobInfo(name); blobClient.GetBlob(blobInfo, (s) => GetBlobAction(s, filename)); }
...
![Page 40: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/40.jpg)
![Page 41: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/41.jpg)
44
More info
• Will soon be published on:– http://blogs.msdn.com/b/freddyk
• Related info:– Vjeko’s blog (navigateintosuccess.com)
– Waldo’s blog (www.waldo.be)
– Mibuso
– Dynamicsuser.net
– ...
![Page 42: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/42.jpg)
45
Questions?
![Page 43: Dynamics NAV, Windows Azure & Windows Phone 7, Eric Wauters](https://reader031.fdocuments.us/reader031/viewer/2022012918/546460deaf7959f2058b5bb0/html5/thumbnails/43.jpg)
Thanks to
• Diamond Sponsors
• Gold Sponsors