質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
.NET Core

.NET Coreは、マネージソフトウェアフレームワークでオープンソースで実装されています。クロスプラットフォームを前提に考えられており、Windows/Mac/Linuxで動くアプリケーションを作成することが可能です。

SignalR

SignalRは、マイクロソフト社のASP.NETを基盤とした技術の一つ。ASP.NETアプリにリアルタイム性を持たせることができるライブラリです。サーバサイドとクライアントサイド双方でのリアルタイム通信アプリの開発を容易にします。

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

1回答

1294閲覧

【.NET Core MVC】SignalRを使って既読処理を実装したい

akarinrin_

総合スコア7

.NET Core

.NET Coreは、マネージソフトウェアフレームワークでオープンソースで実装されています。クロスプラットフォームを前提に考えられており、Windows/Mac/Linuxで動くアプリケーションを作成することが可能です。

SignalR

SignalRは、マイクロソフト社のASP.NETを基盤とした技術の一つ。ASP.NETアプリにリアルタイム性を持たせることができるライブラリです。サーバサイドとクライアントサイド双方でのリアルタイム通信アプリの開発を容易にします。

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

0クリップ

投稿2022/03/11 13:46

編集2022/03/13 07:52

前提

・.NET 5.0

Webアプリの開発経験がないため、不足している情報があれば、すみません。
C#の文法はある程度理解していますが、Javascriptの知識は不足しています。

実現したいこと

.NET Core+SQLServerで日報アプリを作成しています。
Identityを使ったユーザ認証機能があり、ユーザがそれぞれ日報を作成します。
日報にはコメントを付けることができ、ボタンクリック時にResponseHubの
SendMessageでコメントをDBに保存することは出来ています。

日報の閲覧時に既読処理を実装したいのですが、
その際にエラーが発生します。

具体的には、既読処理を実装する上で、ページの読込時(window.onload)に
SendReadProcessを呼びたいのですが、
以下のようなエラーが発生します。

発生している問題・エラーメッセージ

response.js

1"use strict"; 2 3var connection = new signalR.HubConnectionBuilder().withUrl("/ResponseHub").build(); 4 5//Disable send button until connection is established 6document.getElementById("sendButton1").disabled = true; 7 8connection.on("ReceiveMessage", function (id, user, message) { 9 var username = document.createElement("a"); 10 var premessage = document.createElement("pre"); 11 var hr = document.createElement("hr"); 12 username.href = "/UserSetting/Index/" + id; 13 username.textContent = user; 14 premessage.textContent = message; 15 document.getElementById("responseList").appendChild(username); 16 document.getElementById("responseList").appendChild(premessage); 17 document.getElementById("responseList").appendChild(hr); 18}); 19connection.on("AddComment", function (id, user, message) { 20 var username = document.createElement("a"); 21 var premessage = document.createElement("pre"); 22 var hr = document.createElement("hr"); 23 username.href = "/UserSetting/Index/" + id; 24 username.textContent = user; 25 premessage.textContent = "(only you)" + message; 26 document.getElementById("responseList").appendChild(username); 27 document.getElementById("responseList").appendChild(premessage); 28 document.getElementById("responseList").appendChild(hr); 29}); 30 31connection.on("ReceiveRead", function (readCnt, list) { 32 var Read = document.createElement("a"); 33 Read.textContent = readCnt + "人が既読しました。"; 34 document.getElementById("ReadIcon").a; ppendChild(Read); 35}); 36 37connection.start().then(function () { 38 document.getElementById("sendButton1").disabled = false; 39}).catch(function (err) { 40 return console.error(err.toString()); 41}); 42 43document.getElementById("sendButton1").addEventListener("click", function (event) { 44 var reportID = document.getElementById("reportID").value; 45 var message = document.getElementById("messageInput").value; 46 var typeID = document.getElementById("ResponseType").value; 47 reportID = Number(reportID); 48 typeID = Number(typeID); 49 connection.invoke("SendMessage", typeID, reportID, message).catch(function (err) { //このメソッドでエラーが発生します。 50 return console.error(err.toString()); 51 }); 52 event.preventDefault(); 53}); 54 55//以下の関数が正常に動作しません。 56window.onload = function () { 57 var reportID = document.getElementById("reportID").value; 58 reportID = Number(reportID); 59 connection.invoke("SendReadProcess", reportID).catch(function (err) { 60 return console.error(err.toString()); 61 }); 62};

エラー

error: cannot send data if the connection is not in the 'connected' state.

エラー内容で検索した所、SignalRの接続が確立されていないため、接続に失敗するとのエラーでした。

ResponseHub.cs

1public class ResponseHub : Hub 2 { 3 private readonly ApplicationDbContext _context; 4 private readonly UserManager<ReportUser> _userManager; 5 6 public ResponseHub(ApplicationDbContext context, UserManager<ReportUser> userManager) 7 { 8 _context = context; 9 _userManager = userManager; 10 } 11 12 public async Task SendMessage(int typeID, int reportID, string message) 13 { 14 //コメントをDBに保存する処理 15 } 16 17 public async Task SendReadProcess(int reportID) 18 { 19 var user = await _userManager.FindByNameAsync(Context.User.Identity.Name); 20 21 if (user != null) 22 { 23 var read = new Read() 24 { 25 ReportID = reportID, 26 ReportUserId = user.Id, 27 IsLiked = false 28 }; 29 await _context.Reads.AddAsync(read); 30 await _context.SaveChangesAsync(); 31 32 var readlist = await _context.Reads.Where(s => s.ReportID == reportID) 33 .ToListAsync(); 34 35 await Clients.All.SendAsync("ReceiveRead", readlist.Count, readlist); 36 } 37 } 38 }

Index.html

1@model JobReport.ViewModels.ReportViewViewModel 2 3@{ 4 ViewData["Title"] = "Index"; 5 var prevDisabled = !Model.ReportList.HasPreviousPage ? "disabled" : ""; 6 var nextDisabled = !Model.ReportList.HasNextPage ? "disabled" : ""; 7} 8 9<div class="flexbox"> 10 <section class="list"> 11 <h1>Contents</h1> 12 <ul> 13 @for(int i = 0; i >=-6 ; i--) 14 { 15 <li><a asp-action="Index" asp-route-date="@DateTime.Now.AddDays(i).Date">@DateTime.Now.AddDays(i).Date.ToString("MM月dd日 (ddd)")</a></li> 16 } 17 18 @*@foreach (var item in Model.UserList) 19 { 20 <li><a asp-action="Index">@item.Name</a></li> 21 }*@ 22 </ul> 23 </section> 24 <article class="main"> 25 <h1>日報閲覧</h1> 26 <a asp-action="Index" 27 asp-route-date="@Model.Date" 28 asp-route-page="@(Model.ReportList.PageIndex - 1)" 29 class="btn btn-primary @prevDisabled"> 3031 </a> 32 <a asp-action="Index" 33 asp-route-date="@Model.Date" 34 asp-route-page="@(Model.ReportList.PageIndex + 1)" 35 class="btn btn-primary @nextDisabled"> 3637 </a> 38 39 <p> 40 @if (Model.ReportList.Count() != 0 && Model.ReportList != null) 41 { 42 <h3 class="text-md-center">@Model.Date.Date.ToString("M月d日")</h3> 43 <h3 class="text-md-right">@Model.Report.ReportUser.Name</h3> 44 <div id="ReadIcon" hidden></div> 45 @foreach (var reportItem in Model.ItemList) 46 { 47 <h3>@reportItem.ReportItemName</h3> 48 @foreach (var reportText in Model.TextList) 49 { 50 @if (reportItem.ReportItemID == reportText.ReportItemID) 51 { 52 <pre>@reportText.Text</pre> 53 } 54 } 55 } 56 57 58 <div id="responseList"> 59 @if (Model.ResponseList != null) 60 { 61 <hr /> 62 @foreach (var response in Model.ResponseList) 63 { 64 <a asp-controller="UserSetting" asp-route-id="@response.Read.ReportUserId">@response.Read.ReportUser.Name</a> 65 66 <pre>@response.ReponseText</pre> 67 <hr /> 68 } 69 70 } 71 </div> 72 73 <div class="row">&nbsp;</div> 74 <div class="row"> 75 <div class="col-6"> 76 <input type="number" value="@Model.Report.ReportID" id="reportID" hidden /> 77 <select asp-for="ResponseType" asp-items="ViewBag.SelectList"></select> 78 <div class="col-2">Message</div> 79 <div class="col-4"><input type="text" id="messageInput" /></div> 80 <input type="button" id="sendButton1" value="Send Message" /> 81 </div> 82 </div> 83 84 <div class="row"> 85 <div class="col-12"> 86 <hr /> 87 </div> 88 </div> 89 <div class="row"> 90 <div class="col-6"> 91 <ul id="messagesList"></ul> 92 </div> 93 </div> 94 } 95 </p> 96 </article> 97 <section class="side"> 98 <h1>About</h1> 99 <p> 100 The Little Prince (French: Le Petit Prince), first published in 1943, is a novella and the most famous work of the French aristocrat, writer, poet and pioneering aviator Antoine de Saint-Exupéry (1900–1944). 101 </p> 102 </section> 103</div>

解決したいこと

現状、ページ読込時に既読処理を実現する方法をアドバイス頂けたら幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/03/11 21:57

ASP.NET のタグを付けてください。
退会済みユーザー

退会済みユーザー

2022/03/11 22:46

> .NET Core+SQLServerで日報アプリを作成しています。 日報という言葉からは個人個人が別々に書くものを想像しますが、質問者さんのケースでは違うようですね。簡単にどのようなものか説明できませんか?
akarinrin_

2022/03/13 07:54

>Identityを使ったユーザ認証機能があり、ユーザがそれぞれ日報を作成します。 ログインしたユーザが個人個人で作成し、互いに閲覧できる日報アプリです。
guest

回答1

0

ベストアンサー

ハブに接続する際にconnection.start()メソッドを呼び出していますが、このメソッドは非同期のようで、戻りがPromise<void>となっているようです。
非同期でハブとの接続が確立される前に、window.onloadが動き始めて、connection.invoke("SendReadProcess", reportID)をするタイミングでもまだ接続が確立できていないのではないかと思いました。

connection.invoke("SendReadProcess", reportID)connection.start()メソッドの後のthenの中に記述してみたらどうでしょうか。
(このthenの中は接続が確立された時に動くと思います)

https://docs.microsoft.com/ja-jp/aspnet/core/signalr/javascript-client?view=aspnetcore-6.0#connect-to-a-hub
https://docs.microsoft.com/ja-jp/javascript/api/@microsoft/signalr/hubconnection?view=signalr-js-latest#@microsoft-signalr-hubconnection-start

投稿2022/03/11 14:45

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akarinrin_

2022/03/13 07:57

connection.start().then内に処理を記載することで接続後に処理できました! ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問