Reputation: 237
i am using xamarin crossplatform with web api. I have database in which i have binary data of pdf files. I want to display these pdf files.
Web Api
private Entities1 db = new Entities1();
public IQueryable<DiagnosticDetailModel> GetDiagnosticDetailModels()
{
return db.DiagnosticDetailModels;
}
this above code to get list of table where i have id,reportname,filecontent(byte)
[Route("api/DiagnosticDetail/RetrieveFile/{id}")]
[HttpGet]
public HttpResponseMessage RetrieveFile(int id)
{
DiagnosticDetailModel diagnosticDetailModel = GetFileList(id);
byte[] img = diagnosticDetailModel.FileContent.ToArray();
HttpResponseMessage result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new ByteArrayContent(img);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline");
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return result;
}
private DiagnosticDetailModel GetFileList(int id)
{
var DetList = db.DiagnosticDetailModels.Where(p => p.InpatientCodeId == id).FirstOrDefault();
return DetList;
}
this above code to return file filecontent(byte), i have tested this api its working fine in browser
Xamarin RestClient
private const string WebServiceDiagnostic = "http://172.16.4.212:55364/api/DiagnosticDetailModels/";
private const string WebServiceReport = "http://172.16.4.212:55364/api/DiagnosticDetail/RetrieveFile/";
public async Task<List<T>> GetDiagnosticAsync()
{
var httpClient = new HttpClient();
var json = await httpClient.GetStringAsync(WebServiceDiagnostic);
var taskModels = JsonConvert.DeserializeObject<List<T>>(json);
return taskModels;
}
this above is restclient code to get list of data from database
public async Task<T> userReport(int id)
{
var httpClient = new HttpClient();
var json = await httpClient.GetStringAsync(WebServiceReport + id);
var taskModels = JsonConvert.DeserializeObject<T>(json);
return taskModels;
}
this above code is to get fileContent(byte)
Xamarin Services
public async Task<List<DiagnosticDetailModel>> GetReportDetailAsync()
{
RestClient<DiagnosticDetailModel> restClient = new RestClient<DiagnosticDetailModel>();
var employeesList = await restClient.GetDiagnosticAsync();
return employeesList;
}
public async Task<DiagnosticDetailModel> ReportAsync(int id)
{
RestClient<DiagnosticDetailModel> restClient = new RestClient<DiagnosticDetailModel>();
var user = await restClient.userReport(id);
return user;
}
Xamarin MainVeiwModel
private List<DiagnosticDetailModel> _ReportList;
public List<DiagnosticDetailModel> ReportList
{
get { return _ReportList; }
set
{
_ReportList = value;
OnPropertChanged();
}
}
public MainViewModel()
{
InitializeDiagnosticDataAsync();
}
public async Task InitializeDiagnosticDataAsync()
{
var employeesServices = new EmployeesServices();
ReportList = await employeesServices.GetReportDetailAsync();
}
private DiagnosticDetailModel _SelectedReport;
public DiagnosticDetailModel SelectedReport
{
get { return _SelectedReport; }
set
{
_SelectedReport = value;
OnPropertChanged();
}
}
public Command GetReport
{
get
{
return new Command(async () =>
{
var employeesServices = new EmployeesServices();
SelectedReport= await employeesServices.ReportAsync(_SelectedReport.InpatientCodeId);
});
}
}
Xamarin main.xaml
<ListView x:Name="ReportListView"
ItemsSource="{Binding ReportList}"
HorizontalOptions="Center"
VerticalOptions="Center"
HasUnevenRows="True"
ItemTapped="ListViewReport_OnItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="6,6" HorizontalOptions="Center" Orientation="Horizontal" >
<Label Text="{Binding InpatientCodeId}" FontSize="Small" WidthRequest="100"
Style="{DynamicResource ListItemTextStyle}" HorizontalOptions="Center"/>
<Label Text="{Binding ReportName}" FontSize="Small" WidthRequest="100"
Style="{DynamicResource ListItemTextStyle}" HorizontalOptions="Center"/>
<Label Text="{Binding Date}" FontSize="Small" Opacity="0.6" WidthRequest="100"
Style="{DynamicResource ListItemDetailTextStyle}" HorizontalOptions="Center"/>
<Button Text="View" BackgroundColor="Crimson" TextColor="White" WidthRequest="100"
HorizontalOptions="Center"></Button>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Xamarin main.cs
private async void ListViewReport_OnItemTapped(object sender, ItemTappedEventArgs e)
{
var user = ReportListView.SelectedItem as DiagnosticDetailModel;
if (user != null)
{
var mainViewModel = BindingContext as MainViewModel;
if (mainViewModel != null)
{
mainViewModel.SelectedReport = user;
await Navigation.PushAsync(new Reports(mainViewModel));
ReportListView.SelectedItem = null;
}
}
}
Xamarin Report.xaml
<StackLayout Orientation="Vertical" Spacing="18">
<Button Text="Update" TextColor="White" BackgroundColor="Crimson" Command="{Binding GetReport}"/>
<WebView Source="{Binding SelectedReport.FileContent,Mode=OneWay}" />
</StackLayout>
in every section i have two parts one is getting list of table and other is to get file which in binary data in table. The program is working fine where i can get list of table and when i click on tap of list i navigate to Report page by passing the id, there i have button to GetReport and i am trying to get file in webview which i am not able to do.
Upvotes: 1
Views: 647
Reputation: 2105
PDFs in WebView are only supported out of the box by iOS. If you also want to use them in Android and UWP, you need to use for example pdfjs. Take a look at this official Xamarin Forms tutorial, which details how to use pdfjs in Android&UWP and then create a common abstraction you can use in your Xamarin Forms code:
Display a Local PDF File in a WebView
The abstraction will look like this:
public class CustomWebView : WebView
{
public static readonly BindableProperty UriProperty = BindableProperty.Create (propertyName:"Uri",
returnType:typeof(string),
declaringType:typeof(CustomWebView),
defaultValue:default(string));
public string Uri {
get { return (string)GetValue (UriProperty); }
set { SetValue (UriProperty, value); }
}
}
so in your shared code you'll just have to specify correct Uri (can be a file path) of your pdf file. To save a file, you also need some custom logic for UWP and common for iOS and Android: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/files?tabs=vswin#saving-and-loading-files
Upvotes: 1