如何在xamarin web api中显示二进制pdf

时间:2018-04-24 06:36:12

标签: sql-server pdf xamarin asp.net-web-api xamarin.forms

我正在使用带有web api的xamarin crossplatform。我有数据库,其中我有pdf文件的二进制数据。我想显示这些pdf文件。

Web Api

private Entities1 db = new Entities1();

        public IQueryable<DiagnosticDetailModel> GetDiagnosticDetailModels()
        {
            return db.DiagnosticDetailModels;
        }

以上代码获取表的列表,其中我有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;
    }

以上代码返回文件filecontent(byte),我已经测试了这个api在浏览器中工作正常

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;
        }

以上是restclient代码,用于从数据库中获取数据列表

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;
        }

以上代码是获取fileContent(byte)

Xamarin服务

 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>

在每个部分我有两个部分,一个是获取表的列表,另一个是获取表中二进制数据的文件。该程序工作正常,我可以获得表格列表,当我点击列表时点击我导航到报告页面通过传递ID,我有按钮 GetReport 我试图在webview中获取文件,但我无法做到。

1 个答案:

答案 0 :(得分:1)

WebView中的PDF仅支持iOS开箱即用。如果您还想在Android和UWP中使用它们,则需要使用例如pdfjs。看一下这个官方的Xamarin Forms教程,详细介绍如何在Android和UWP中使用pdfjs,然后创建一个可以在Xamarin Forms代码中使用的通用抽象:

Display a Local PDF File in a WebView

抽象将如下所示:

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); }
    }
}

因此,在您的共享代码中,您只需指定pdf文件的正确Uri(可以是文件路径)。要保存文件,您还需要一些UWP自定义逻辑,适用于iOS和Android:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/files?tabs=vswin#saving-and-loading-files