SignalR not working when submitting MVC form using jQuery

AG 491 Reputation points
2022-05-26T17:18:34.98+00:00

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

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,138 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,245 questions
0 comments No comments
{count} votes

Accepted answer
  1. Zhi Lv - MSFT 32,006 Reputation points Microsoft Vendor
    2022-05-27T06:56:54.617+00:00

    Hi @AG ,

    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

    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. AG 491 Reputation points
    2022-05-27T17:01:56.137+00:00

    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

    0 comments No comments