1

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.

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

3 Comments

so you can i can display binary data in webview? and how webview controller code will look like after i create CustomWebView ?
just save your binary data as a pdf in your mobile storage and use it as CustomWebView uri.
I updated my answer with link to file saving tutorial. Please try to do it yourself and post any problems you have

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.