环境:

  1. asp.net 4.5
  2. Visual Studio 2015
  3. 本地已经部署deepseek-r1:1.5b

涉及技术

  1. ASP.NET MVC框架用于构建Web应用程序。
  2. 使用HttpWebRequest和HttpWebResponse进行HTTP请求和响应处理。
  3. JSON序列化和反序列化用于构造和解析数据。
  4. SSE(服务器发送事件)用于向客户端推送实时更新。

完成显示效果如下 (患者信息是AI生成的,非真实信息)

在这里插入图片描述

1、在前端界面(cshtml)使用SSE技术向后端传送患者报告的路径。

<!-- 根据系统环境获取PDF文件路径 -->
@{string pdffilepath = datas.ReportFile;}
<div class="deepseek-title">      <!-- DeepSeek输入框 -->
	<h4 class="title3">DeepSeek分析</h4>
</div>
<div class="deepseek-textarea">
	<textarea class="text-box" id="outputTextarea" readonly></textarea> <!-- 第二行文本框 -->
	<button class="text-button" id="reparseButton">重新解析报告</button> <!-- 新增按钮 -->
</div>
<script>
     var textarea = document.getElementById('outputTextarea');
     var reparseButton = document.getElementById('reparseButton');
     var source;

     // 初始化SSE连接的函数
     function startEventSource() {
         // 如果已有连接,先关闭
         if (source) {
             source.close();
         }
         // 创建新的SSE连接
         source = new EventSource('@Url.Action("StreamAI", "DeepSeek", new { pdfPath = pdffilepath })');

         // 接收数据并更新textarea
         source.onmessage = function(event) {
             if (event.data.includes("换1行")) {
                 textarea.value += event.data.replace("换1行", "\n"); // 替换为一个换行符
             } else if (event.data.includes("换2行")) {
                 textarea.value += event.data.replace("换2行", "\n\n"); // 替换为两个换行符
             } else {
                 textarea.value += event.data; // 无特殊标记,按原数据添加
             }
             // 自动滚动到最新内容
             //textarea.scrollTop = textarea.scrollHeight; // 恢复滚动功能
         };

         // 错误处理
         source.onerror = function() {
             console.log('SSE 连接错误');
             source.close();
         };
     }

     // 页面加载时初次启动SSE
     startEventSource();

     // 按钮点击事件:清空文本框并重新解析
     reparseButton.addEventListener('click', function() {
         textarea.value = ''; // 清空文本框
         startEventSource(); // 重新建立SSE连接
     });
</script>
<style>
   .title3{
       margin: 30px 20px 0px 20px;
       margin-top:10px;
   }
   .text-box {
       margin: 10px 20px;
       width: 540px;
       height: 260px;
       font-size: 15px;
       outline:0px;
       border: 2px solid rgba(228,228,228,1);   
       border-radius: 4px;
       line-height: 25px; /* 设置行距像素 */
   }
   .text-button{
       margin: 20px 20px 0px 20px;
       width: 140px;
       height: 30px;
       background-color: #FFC107;
       font-size: 18px;
       color: white;
       font-family:SourceHanSansCN-Regular;
       border: 0px;
       border-radius: 4px;
       outline: 0;
       cursor: pointer; /* 到达按钮旁边时显示手 */
   }
</style>

2、后端接收到传递过来的患者报告路径,进行解析,然后发送给DeepSeek分析,DeepSeek分析的内容实时使用Response.Write()推送至前端。

DeepSeekController.cs

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Mvc;
using Newtonsoft.Json;

namespace *********
{
    public class DeepSeekController : Controller
    {
        public ActionResult StreamAI(string pdfPath)
        {
            // 提取 PDF 文本
            string pdfText = DeepSeekHelper.ExtractTextFromPdf(pdfPath);
            if (string.IsNullOrEmpty(pdfText))
            {
                return Content("PDF文件不存在或无法读取", "text/event-stream");
            }

            // 设置 SSE 响应头
            Response.ContentType = "text/event-stream";
            Response.Headers.Add("Cache-Control", "no-cache");
            Response.Headers.Add("Connection", "keep-alive");

            // 构造 AI 请求数据
            var requestData = new
            {
                model = "deepseek-r1:1.5b",
                prompt = $"请以专业医生的身份,对以下患者报告进行详细分析,并提供医学建议:{pdfText}请按照以下结构输出:影像/检查结果分析:详细解读报告中的影像表现或检查结果,结合医学知识说明异常情况及其可能的临床意义。诊断建议:根据分析结果,提出初步诊断方向(如疾病名称或疑似病因)。请确保内容准确、专业,并符合临床实践规范",
                stream = true
            };

            string jsonContent = JsonConvert.SerializeObject(requestData);
            byte[] byteArray = Encoding.UTF8.GetBytes(jsonContent);

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:11434/api/generate");
            request.Method = "POST";
            request.ContentType = "application/json";
            request.ContentLength = byteArray.Length;
            try
            {
                using (Stream dataStream = request.GetRequestStream())
                {
                    dataStream.Write(byteArray, 0, byteArray.Length);
                }
                //string linestrs = "";
                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    using (Stream responseStream = response.GetResponseStream())
                    using (StreamReader reader = new StreamReader(responseStream))
                    {
                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            if (!string.IsNullOrEmpty(line))
                            {
                                dynamic result = JsonConvert.DeserializeObject(line);
                                if (result != null && result.response != null)
                                {
                                    string responseText = result.response.ToString();
                                    string processedText = DeepSeekHelper.RegexLine(responseText);
                                    if (processedText.Contains("\n\n"))
                                    {
                                        processedText = processedText.Replace("\n\n", "换2行");
                                    }
                                    else if (processedText.Contains("\n"))
                                    {
                                        processedText = processedText.Replace("\n\n", "换1行");
                                    }
                                    //linestrs += processedText;
                                    //推送数据到客户端
                                    Response.Write($"data: {processedText}\n\n");
                                    Response.Flush();
                                }
                            }
                        }
                    }
                }
                catch (WebException ex)
                {
                    Response.Write($"data: 错误:{ex.Message}\n\n");
                    Response.Flush();
                }
            }
            catch
            {
                try
                {
                    // 返回自定义错误信息
                    Response.Write($"data: 错误:请配置本地DeepSeek,或者启动相关服务。\n\n");
                    Response.Flush();
                }
                catch
                {

                }
            }
            return new EmptyResult();
        }
    }
}

DeepSeekHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using System.Text;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using Newtonsoft.Json;

namespace *******
{
    public static class DeepSeekHelper
    {
        /// <summary>
        /// 读取PDF文件获取PDF中的文字
        /// </summary>
        /// <param name="pdfPath"></param>
        /// <returns></returns>
        public static string ExtractTextFromPdf(string pdfPath)
        {
            string pdfPath2 = pdfPath.Replace("_1.png", ".pdf");
            if (!File.Exists(pdfPath2))
            {
                Console.WriteLine("PDF文件不存在!");
                return "";
            }
            PdfReader reader = new PdfReader(pdfPath2); // 直接创建PdfReader对象
            string strs = "";
            for (int page = 1; page <= reader.NumberOfPages; page++)
            {
                ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
                string currentText = PdfTextExtractor.GetTextFromPage(reader, page, strategy);
                strs += currentText;
            }
            reader.Close(); // 手动关闭PdfReader对象
            return strs;
        }
        
        /// <summary>
        /// 处理DeepSeek返回的字符串
        /// </summary>
        /// <param name="responseText"></param>
        /// <returns></returns>
        public static string RegexLine(string responseText)
        {
            // 使用正则表达式去掉 <think> 和 </think> 标签
            responseText = Regex.Replace(responseText, @"<\/?think>", "\n");
            // 去掉开头的换行符
            responseText = responseText.TrimStart('\r', '\n');
            return responseText;
        }
    }
}

总结

  1. 前端技术:HTML、JavaScript(使用EventSource实现SSE)。
  2. 后端技术:C# ASP.NET MVC、HTTP请求/响应处理、JSON处理。
  3. 通信技术:SSE用于服务器向客户端推送实时数据。
  4. 功能:实现了一个可以解析PDF文件内容,通过AI服务进行医学报告分析,并将结果实时推送给前端显示的应用程序。
Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐