question

AG-1964 avatar image
0 Votes"
AG-1964 asked AG-1964 answered

SignalR not working when submitting MVC form using jQuery

Hi,

The repo for my question is here https://github.com/asafgo/SignalRProgress

In the code Index.cshtml I have a form and in it btnImportExcel.
When using btnImportExcel onclick="$('#SignalRForm').submit();" SignalR is working ok, but if I try to use jQuery using Ajax by function DoAjaxPost with btnImportExcel onclick="return DoAjaxPost(this);" SignalR is not working.

I would like to submit the form without refreshing the View so that's why I am using jQuery Ajax, Also btnImportExcel needs to be outside the form tags..
There is no need to return a View at InvokeSignalR Action so it can be change if needed.

Thanks in advanced for any help,
AG




dotnet-aspnet-generaldotnet-aspnet-core-mvc
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

ZhiLv-MSFT avatar image
1 Vote"
ZhiLv-MSFT answered

Hi @AG-1964,

206101-image.png

The issue relates the JobId.

Try to set break point in the InvokeSignalR method, JobProgressHub.AssociateJob method, and then debug your code.

Since the JobId was defined in the InvokeSignalR method, when running the application, before click the btnImportExcel button, the ViewBag.JobId is empty, so in the JobProgressHub.AssociateJob method, it will not add the current client into the group. Then, after click the btnImportExcel button (without using JQuery Ajax), it will submit the form to the InvokeSignalR method and the page will refresh, so in this time, the ViewBag.JobId is not empty, so it will show the process using SignalR.

Then, when using the JQuery Ajax method to submit the form, the main page will not refresh, it will cause the ViewBag.JobId keep empty. So, even through the InvokeSignalR method will send the message to the new JobId, but the client side will not recognize. So the process will not show and the SignalR not working.

To solve this issue, you can define the JobId in the Home controller Index action method, like this:

     public IActionResult Index()
     {
         string jobId = Guid.NewGuid().ToString("N");
         ViewBag.JobId = jobId;
         return View();
     }

Then, in the Index.cshtml page, use a hidden field to store the JobId.

206111-image.png

In the InvokeSignalR method, add a jobId parameter to receive the created JobId.

     [HttpPost]
     public async Task<IActionResult> InvokeSignalR(string jobId)
     {
         await Task.Delay(100).ConfigureAwait(false);
         ViewBag.JobId = jobId;
         Task task = Task.Run(async () =>
         {
             for (int i = 0; i < 100; i++)
             {
                 await _hubContext.Clients.Group(jobId).SendAsync("progress", i).ConfigureAwait(false);
                 await Task.Delay(1000).ConfigureAwait(false);
             }
         }); 
         return View("Index");
     }

Then, change the DoAjaxPost, get the JobId and transfer the data via query string.

     function DoAjaxPost(btnClicked) {
         //var $form = $(btnClicked).parents('form');
         var $form = $("#SignalRForm");

         //get the JobId 
         var jobid =$("#hidJobId").val();
         $.ajax({
             type: "POST",
             url: $form.attr('action')+"?jobId="+jobid,
             data: $form.serialize(),
             error: function(xhr, status, error) {
                 console.log(error);
             },
             success: function(response) {
                 console.log($form.attr('action'));   
             }
         });

         return false;// if it's a link to prevent post
     } 

You can view the full code from here: 205999-indexcshtml.txt 206085-homecontroller.txt

The output as below:

Use the form submit method:

206070-1.gif

Use JQuery Ajax to submit:

206077-2.gif


If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Best regards,
Dillion


image.png (9.0 KiB)
image.png (47.6 KiB)
indexcshtml.txt (4.3 KiB)
homecontroller.txt (1.7 KiB)
1.gif (935.5 KiB)
2.gif (464.2 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AG-1964 avatar image
0 Votes"
AG-1964 answered

Hi Dillion,


I am amazed by your efforts you spent in order to provide me with a solution to my code problem.
Thanks you very very much for your help!

Kind Regards,
AG

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.