1.Blazor
1.1 Blazor应用
Blazor 利用 ASP.NET Core 生成Web 应用。
官网教程:https://dotnet.microsoft.com/zh-cn/learn/aspnet/blazor-tutorial/run
web应用创建到blazorapp这个目录:
 dotnet new blazor -o blazorapp安装其它库,--prerelease为在没有稳定版时安装测试版:
 dotnet add package Azure.AI.OpenAI --prereleasedotnet run运行项目:

1.2 Blazor具体内容
razor文件代码部分,写C#代码控制页面逻辑:
 @code {
}代码:
@page "/chat-1138"
@using System;
@using System.Net.Http;
@using System.Threading.Tasks;
@using System.Text;
@using System.Text.Json;
@using System.Collections.Generic;
@using Azure.AI.OpenAI;
@code {
    private string inputText = "";
    public HttpClient Client { get; set; }=new HttpClient();
    public List<string> ChatHistory { get; set; }= new List<string>();  
    private async Task SendMessage()
    {
        try
        {
            var response = await CallOpenAIChatGPT(inputText);
            ChatHistory.Add($"You: {inputText}");
            ChatHistory.Add($"GPT: {response}");
            inputText = "";
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error in SendMessage: " + ex.Message);
        }
    }
    /***************************chat部分***************************/
    //functionUrl 是api的链接及密钥
    public string functionUrl = "";
    public class ChatData
    {
       // public ChatCompletionsOptions Options { get; set; }
        public List<MyChatMessage> Messages { get; set; }       
        public float? Temperature { get; set; }
        public int? MaxTokens { get; set; }
        public float? NucleusSamplingFactor { get; set; }
        public float? FrequencyPenalty { get; set; }
        public float? PresencePenalty { get; set; }
    }
    public class MyChatMessage
    {
        public string Role { get; set; }
        public string Content { get; set; }
        public MyChatMessage(string role, string content)
        {
            Role = role;
            Content = content;
        }
    }
    public string prompt = @"You are a translation robot that translates all user inputs into English.";
    public string inputs =  "C#控制台应用如何像notebook一样交互式运行?";
    public class ChatCompletionResponse
    {
        public string Id { get; set; }
        public DateTime Created { get; set; }
        public List<Choice> Choices { get; set; }
        public Usage Usage { get; set; }
    }
    public class Choice
    {
        public Message Message { get; set; }
        public int Index { get; set; }
        public string FinishReason { get; set; }
    }
    public class Message
    {
        public Role Role { get; set; }
        public string Content { get; set; }
    }
    public class Role
    {
        public string Label { get; set; }
    }
    public class Usage
    {
        public int CompletionTokens { get; set; }
        public int PromptTokens { get; set; }
        public int TotalTokens { get; set; }
    }
    public static async Task<ChatCompletionResponse> CallFunctionChat(string functionUrl, ChatData data)
    {
        string json = JsonSerializer.Serialize(data);
        using (HttpClient client = new HttpClient())
        {
            try
            {
                // 创建HttpContent
                HttpContent content = new StringContent(json, Encoding.UTF8, "application/json");
                Console.WriteLine("Post!");
                // 发送POST请求
                HttpResponseMessage response = client.PostAsync(functionUrl, content).GetAwaiter(). 
                    GetResult();
                //response.EnsureSuccessStatusCode();
                Console.WriteLine("response!");
                // 读取响应内容
                string responseBody = response.Content.ReadAsStringAsync().GetAwaiter(). 
                    GetResult();
                Console.WriteLine(responseBody);
                ChatCompletionResponse responseObject = JsonSerializer.Deserialize<ChatCompletionResponse>(responseBody);
                return responseObject;
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine("\nException Caught!");
                Console.WriteLine("Message :{0} ", e.Message);
                return null;
            }
        }
    }
    //var r = CallFunctionChat(functionUrl, data).GetAwaiter().GetResult();
    //Console.WriteLine(r.GetType());
    //Console.WriteLine(r.Choices[0].Message.Content);
    /***************************chat部分***************************/
    private async Task<string> CallOpenAIChatGPT(string message)
    {
        ChatData data = new ChatData()
        {
            Messages = new List<MyChatMessage>() // Initialize the Messages property with an empty list
            {
                new MyChatMessage("System", @prompt),
                new MyChatMessage("User", @inputText),
            },
            Temperature = (float)0.7,
            MaxTokens = 800,
            NucleusSamplingFactor = (float)0.95,
            FrequencyPenalty = 0,
            PresencePenalty = 0,
        };
        var r = CallFunctionChat(functionUrl, data).GetAwaiter().GetResult();
        // Call the API
        //return result.data.answer;
        return r.Choices[0].Message.Content;
    }
}
<!-- ... 其他HTML部分不变 -->
<div class="chat-box">
       @if (ChatHistory != null && ChatHistory.Count > 0)
    {  
        <h2>Chat History:</h2>  
        <ul>  
        @foreach (var message in ChatHistory)
            {  
                    <li>@message</li>  
            }  
        </ul>  
    }
    else
    {  
        <p>Loading chat history...</p>  
    }
</div>
<div class="input-section">
    <input @bind="inputText" placeholder="Type your message..." />
    <button @onclick="SendMessage">Send</button>
</div>
2.制作镜像及推送
2.1 制作镜像
在vscode+fedora+dotnet 8.0环境下:
ctrl+shift+P打开,创建调试json文件:
 .NET:Generate Assets for Build and Debug创建docker-compose.yaml:
Docker:Add files安装好docker-compose,修改Dockerfile好文件,如端口。
构建制作镜像项目:
sudo docker-compose build2.2 推送
docker需要新登陆一个仓库:
docker login 地址推送:
docker push myapp 地址/myapp




