Day 29 - 将 Yacht 後台储存资料提取後,送至前台渲染 Layout&deck 及 Video 版面内容区块 - 嵌入 YouTube 影片 - ASP.NET Web Forms C#

=x= 🌵 Yachts 前台页面 Layout & deck plan / Video - Content Page 後端功能制作。


Layout & deck plan / Video 内容区块资料分析介绍 :

📌 Layout & deck plan 跟 Video 分页内容较简单,所以就一起介绍如何处理 :

  1. Layout & deck plan - 带有 CSS 样式的连续图片。

https://ithelp.ithome.com.tw/upload/images/20211013/20139487ks0BXZZ7l3.jpg

  1. Video - 嵌入 YouTube 影片。

https://ithelp.ithome.com.tw/upload/images/20211013/20139487BH4h5RtEUh.jpg



Layout & deck plan - Content Page 页面後端实作 :

1. 於前台资料夹右键新增"使用主版页面的 Web Form" 并指定 Yachts.Master为主版。


2. 於内容区块内放入 Layout & deck plan 分页内容程序码,并使用 asp:Literal 等修改参考如下

https://ithelp.ithome.com.tw/upload/images/20211013/20139487SGG47MVRt7.jpg


3. 於後置程序码 Page_Load 事件内加入读取内容方法 loadContent(); 参考如下

protected void Page_Load(object sender, EventArgs e)
{
    //会先跑 Content 页的 Page_Load 才跑 Master 页的 Page_Load
    if (!IsPostBack) {
        loadContent();
    }
}


4. 建立取得 Layout & deck plan 分页内容 loadContent(); 方法逻辑如下

private void loadContent()
{
    //取得 Session 共用 Guid,Session 物件需转回字串
    string guidStr = Session["guid"].ToString();
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    //依 Guid 取得型号资料
    string sql = "SELECT layoutDeckPlanImgPathJSON FROM Yachts WHERE guid = @guidStr";
    SqlCommand command = new SqlCommand(sql, connection);
    command.Parameters.AddWithValue("@guidStr", guidStr);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    StringBuilder layoutHtmlStr = new StringBuilder();
    List<LayoutPath> saveImagPathList = new List<LayoutPath>();
    if (reader.Read()) {
        string loadImgJson = HttpUtility.HtmlDecode(reader["layoutDeckPlanImgPathJSON"].ToString());
        //加入页面组图 HTML
        saveImagPathList = JsonConvert.DeserializeObject<List<LayoutPath>>(loadImgJson);
        foreach (var item in saveImagPathList) {
            //加入每张图片
            layoutHtmlStr.Append($"<li><img src='upload/Images/{item.SavePath}' alt='layout' Width='670px' /></li>");
        }
        //渲染画面
        ContentHtml.Text = layoutHtmlStr.ToString();
    }
    connection.Close();

}

//页面组图 JSON 资料
public class LayoutPath
{
    public string SavePath { get; set; }
}
  • 🌵 <img> 属性加上 Width='670px' 避免图片太大超出画面。


5. 模拟页面检查是否正确呈现,完成~



Video - Content Page 页面後端实作 :

1. 於前台资料夹右键新增"使用主版页面的 Web Form" 并指定 Yachts.Master为主版。


2. 去 YouTube 任意影片点击分享,并选择嵌入功能,设定想要的模式後点击复制

https://ithelp.ithome.com.tw/upload/images/20211013/20139487ino2vZSWdm.jpg

  • 🌵 点击复制後会将上方的 <iframe> 全选并复制。

  • 👺 如果勾选启用隐私权加强保护模式,连结会变成 www.youtube-nocookie.com 但是这样做无法用於内嵌影片,请不要勾选。


3. 於内容区块内放入 Video 分页内容程序码,并贴上复制的 <iframe> 程序码,将 <iframe>src 属性内容改为 "#" ,并加入 idrunat="server" 参考如下

https://ithelp.ithome.com.tw/upload/images/20211013/20139487DyVzfXtgr4.jpg

  • 🌵 需自行换算尺寸调整为适合页面的长宽比。

  • 🌵 src="#" 为无意义连结,後面会带入各型号的连结。


4. 於後置程序码 Page_Load 事件内加入读取内容方法 loadContent(); 参考如下

protected void Page_Load(object sender, EventArgs e)
{
    //会先跑 Content 页的 Page_Load 才跑 Master 页的 Page_Load
    if (!IsPostBack) {
        loadContent();
    }
}


5. 建立取得 Video 分页内容 loadContent(); 方法逻辑如下

private void loadContent()
{
    List<RowData> saveRowList = new List<RowData>();
    //取得 Session 共用 Guid,Session 物件需转回字串
    string guidStr = Session["guid"].ToString();
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    //依 Guid 取得型号资料
    string sql = "SELECT overviewDimensionsJSON FROM Yachts WHERE guid = @guid";
    SqlCommand command = new SqlCommand(sql, connection);
    command.Parameters.AddWithValue("@guid", guidStr);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    if (reader.Read()) {
        string loadJson = HttpUtility.HtmlDecode(reader["overviewDimensionsJSON"].ToString());
        saveRowList = JsonConvert.DeserializeObject<List<RowData>>(loadJson);
        // List<T> 第一笔资料是放影片连结
        string youtubeUrlStr = saveRowList[0].SaveValue;
        //如果没有影片连结就导回 OverView 分页
        if (String.IsNullOrEmpty(youtubeUrlStr)) {
            Response.Redirect($"Yachts_OverView.aspx?id={guidStr}");
        }
        else {
            //将取出的 YouTube 连结字串分离出 "影片 ID 字串"
            //使用者如果是用分享功能复制连结时处理方式
            string[] youtubeUrlArr = youtubeUrlStr.Split('/');
            //使用者如果是直接从网址复制连结时处理方式
            string[] vedioIDArr = youtubeUrlArr[youtubeUrlArr.Length - 1].Split('=');
            //将 "影片 ID 字串" 组合成嵌入状态的 YouTube 连结
            string strNewUrl = "https:/" + "/youtube.com/" + "embed/" + vedioIDArr[vedioIDArr.Length - 1];
            //更新 <iframe> src 连结
            video.Attributes.Add("src", strNewUrl);
        }
    }
    connection.Close();
}

// JSON 资料
public class RowData
{
    public string SaveItem { get; set; }
    public string SaveValue { get; set; }
}
  • 🌵 YouTube 连结需加入 /embed/ 才是嵌入模式。

  • 🌵 YouTube 分享功能的连结,最後一个反斜线之後的字串是影片的唯一 ID。

  • 🌵 YouTube 浏览器网址的连结,最後一个等於符号之後的字串是影片的唯一 ID。


6. 模拟页面检查是否正确呈现,完成~



本日总结 :

📢 今天的内容就是单纯的图片跟影片嵌入页面,影片嵌入的小细节只要仔细观察连结,就可以发现嵌入的连结跟一般分享的连结不同,还有不同影片最後面的字串不同,所以最後面的字串就是影片识别 ID,也做了如果使用者直接从网址复制连结的处理,另外,如果要设定自动拨放,要设成静音才能自动拨放。

  • 明日将介绍专案制作完成後可以进行优化的相关细节。

<<:  Chain of Responsibility 责任链模式

>>:  [NestJS 带你飞!] DAY28 - CORS

Day 28 Easy x 2

Day 28 Easy x 2 LeetCode 100 题 待优化的两题 Guess Number...

【D19】尝试料理#2:取得所有指数清单

前言 发现无法轻易取得股票资讯,但换个念头,这应该是市场上所有的资料吧,剩下就是要进行筛检。不过今天...

006-元件状态

今天太晚回家,文章要开天窗拉! 先简单分享一下,我在初期在管理元件的时候,也对於命名这件事情感到有点...

18. PHPer x API document x Swagger API

想当一个 Good PHPer,不但要写程序、写注解还要写 API 文件,想到要维护三个地方工程师就...

[Day 05] Sass - Variables

Variables 在Sass中,开发者可以使用变数,例如可以将常用的颜色、宽度设定成变数,这样未来...