I am working on an asp.net core application where I am loading a view on click of a hyperlink. The view loads fine but what strange thing happening here is whenever I click on the hyperlink, call to controller's action goes twice. I accidently found this issue when I put debug point on the action method and it got hit twice. Then I also checked the network traffic tab in the browser, there also I noticed 2 calls to controller action got recorded twice.
Markup of hyperlink in layout page:
<li><a asp-action="ApplyLeave" asp-controller="Home">Apply Leave</a></li>
Controller's action method:
[HttpGet]
public IActionResult ApplyLeave()
{
.......
.......
.......
return View();
}
ApplyLeave.cshtml
#{
ViewData["Title"] = "Apply Leave";
}
<header class="page-header">
<div class="container-fluid">
<div class="row">
<div class="col-12">
<h2 class="no-margin-bottom">
Apply Leave
</h2>
</div>
</div>
</div>
</header>
Screenshot of network traffic captured in browser:
Kindly help me in resolving this issue, thanks in advance!
If you see your request in console window on network tab, there is two kind of request:-
1: Doc Type
2: XmlHttpRequest
Doc type request is coming from the View which is action link where action method name is mention, but if you see another request then, this request comes from Javascript environment.
Please see the official definition of XMLHttpRequest:-
XMLHttpRequest (XHR) is an API in the form of an object whose methods transfer data between a web browser and a web server. The object is provided by the browser's JavaScript environment.
Please validate once your JS part.
Thanks you all for your kind attention on this.
I have site.js where I am keeping all the script code and code for ajax calls.
There was an ajax call which was intended to be called on a particular page, but due to improper code, that ajax call was triggering after every other page load.
So I corrected the code for that ajax call and now I am not seeing any duplicate call to controller, everything is working fine.
Thanks everyone.
Related
I'm following this Official NET Core tutorial where I've also chosen the Authentication mode as Individual User Accounts. When I try to call ResetPassword Get action method inside the built-in AccountController from a link in the default Index.cshtml view below it, as expected, sends the code parameter to the action method as null. And, as a result, the default error.cshtml page is displayed instead of ResetPassword.cshtml view. Question: How do I call the ResetPassword Get action method so its input parameter code is not null?
Snapshot of Index.cshtml with Reset Password link:
<div class="row">
<div class="col-md-3">
<h2>Application uses</h2>
<ul>
<li>Sample pages using ASP.NET Core MVC</li>
<li>Bower for managing client-side libraries</li>
<li>Theming using Bootstrap</li>
<li><a asp-controller="Account" asp-action="ResetPassword">Reset Password</a></li>
</ul>
</div>
<div class="col-md-3">
<h2>How to</h2>
<ul>
....
</div>
ResetPassword Action method in AccountController
[HttpGet]
[AllowAnonymous]
public IActionResult ResetPassword(string code = null)
{
return code == null ? View("Error") : View();
}
Under normal use that action expects to have the code bound from the querystring. If you take a look at the ForgotPassword POST action, that has code (commented out by default) that can send a link to the user that includes their id and a uniquely generated code (token).
There's a link in that action to a MS page, which guides you further on setting it up. You can test by writing the callBackUrl to debug if you want, then when you follow that link to reset password it should contain a valid token.
The reset password action then accepts the code, which within Identity will be validated to ensure it's valid.
You shouldn't be providing a link to ResetPassword from your Index, but instead should be linking to ForgottenPassword. This action will then generate the code and send an email with the link to click. That link will take the user to the ResetPassword action with the code provided.
I'm working on this project that currently has the follow method:
[HttpPost]
public ActionResult Service(string identifier)
This function is currently being used by a webpage form
<form method="POST" action="/Connector/Service">
<input type="hidden" id="identifier" name="identifier" value="#TempData["Identifier"]"/>
So Service is used when the user clicks on a button that submits the form on the webpage. The user is taken to this page from another action.
I have to implement a feature where sometimes instead of taking the user to the webpage, the user goes directly to the Service method from the action.
I found this thread when searching: ASP.NET MVC: RedirectToAction with parameters to POST Action
But it seems like that is bad design and returning RedirectToAction with Service actually did not work for me.
return RedirectToAction("Service", new {identifier})
Upon more search it seems like I actually cannot make a post request from my controller. Asp.NET MVC : redirect to another controller with POST Action
Any ideas on what I could do here? I am fairly new to ASP.NET and have no idea what to do at this point. All help is appreciated, thanks.
So turns out I could just call the function directly by doing
Service(identifier)
I kept thinking I had to use RedirectToAction so that didn't even cross my mind.
Thanks Sherlock for the answer!
The tag [post] is used only when a form is submited by the view itself, if your page redirect to a controler function from another view than the one your in, you have two option:
Use the [get] tag, you will probably have more luck with this tag, although i don't know exactly how it work (this might be edited)
Use the tagless function with parameters, if you rediret from another view to a function with a parameter, like public ActionResult Service(string identifier) that has no tag, you will automatically reach this function.
if the parameter haven't been specified, it will simply be NULL.
I've been looking for a solution for 2 days now. Maybe I'm mind blocked so I have to ask for help.
I have a project in MVC 4 which has many controllers, models and views. I kept the HomeController and used the Index action as the default entry for the site. There I have a grid, something like this:
<div class="ui-grid-b home-icon-grid">
<div class="ui-block-a"><div class="home-icon" style="background-color:#b13a3a"><i class="fa fa-3x fa-shopping-cart"></div><div class="icon-title">#Mobile.Resources.Resources.resCart</div></div>
<div class="ui-block-c"><div class="home-icon" style="background-color:#1c70ef"><i class="fa fa-3x fa-tags"></i></div><div class="icon-title">#Mobile.Resources.Resources.resItems</div></div>
<div class="ui-block-c"><div class="home-icon" style="background-color:#6b6b6b"><i class="fa fa-3x fa-gear"></i></div><div class="icon-title">#Mobile.Resources.Resources.resSettings</div></div>
</div>
As expected, every time I start debugging, I can see the method
public ActionResult Index() {code}
in HomeController.cs is fired.
Also, in Fiddler I see the following at the beggining:
Host: localhost:55883
URL: /
(Sorry I don't post images, I don't have enough reputation yet)
So far so good. Now, when I click on one of the links in the grid, let's say "Items". I expect to see the Products list, and I do, but if I'm debugging, I see that the Index method in the HomeController is fired as well. An then the Category method in ProductsController is called.
And not only that. Let's say I'm seeing the Products list, and I click in some other link (which go to other view, I've tested many cases) the HomeController Index() is called too.
In Fiddler, when I click the Items link, I see first "/" in the URL column, and then the "Products/Category/ROOT" one.
Following the example, in that view, I clicked over a link which go to "Search/Result", in Fiddler I see "/" and then "Search/Result?productCategory=..."
This happens in all over the site. Every time I click on an anchor, Home/Index is called first, and then the selected path.
I even tried using a simple anchor:
Google
And again, first the Home/Index, and then it redirected to Google.
I suppose it could be related to Route Configuration, or maybe there's something with POSTs being made. Maybe is the normal flow in the mvc life cycle and I'm freaking out over nothing, hehe.
Any ideas? Thanks in advance. I hope I was clear enough.
Many modern browsers "preload" linked pages. So when you load a page, it may also load pages that are linked to those pages. So if you have links back to your home page, then those pages might be loaded by the browser to improve performance.
I have a partial that defines an Ajax.BeginForm. The model returned has a property for ReportLink created on the server resource that returns a Url to a PartialView.
On the Ajax,BeginForm.OnSuccessFunction I am attempting to return and load html content with $("reportContent").load(AJAXRESULT.RenderLink)
However, I get into an infinite loop somewhere.
Edited to add moving parts:
#model xxxx.Reports.Models.Reports.BaseReportModel
#{Layout = null;}
<div id="reportBase" class="k-content">
<div id="reportControl" >
#using (Ajax.BeginForm(
Model.PostAction,
Model.PostController,
null,
new AjaxOptions() { OnSuccess = "editPostSuccess", OnFailure = "editPostFailure" },
new { id = "reportBase_frmViewer", name = "reportBase_frmViewer" }))
{
#Html.AntiForgeryToken()
#RenderSection("reportParams", required: false)
if (#Model.AllowRefresh){
<input type="button" id="btnRefresh" value="refresh" />
}
if (#Model.AllowExportToPDF){
<input type="button" id="btnPDF" value="PDF" />
}
if (#Model.AllowExportToExcel){
<input type="button" id="btnExcel" value="XLS" />
}
#Html.HiddenFor(p => p.AllowExportToExcel)
#Html.HiddenFor(p => p.AllowExportToPDF)
#Html.HiddenFor(p => p.AllowRefresh)
#Html.HiddenFor(p => p.AutoStartReport)
}
</div>
</div>
<div id="wait"></div>
<div id="reportContent"></div>
//The
<script type="text/javascript">
function editPostSuccess(ajaxContext) {
showWaitIndicator(false);
$('#reportContent').load(ajaxContext.RenderLink**,<--This is a link to an asction that calls renderPartial on the controller** function () {
$("#reportContent").show();
});
}
function editPostFailure(ajaxContext) {
showWaitIndicator(false);
var response = JSON.parse(ajaxContext.responseText);
var errorMessage = response.Message;
$('#reportContent').html('#Resources.labels.lblServerErrorsOnForm' + " " + errorMessage);
$("#reportContent").show();
alert("FAILURE:"+response.Message);
}
Update: I am no longer sure that browser is locking up. The content is 3.15 MB. I think the raw html is very verbose and takes that long to render in the browser. Here is the execution sequence:
LoadPartial(ReportModel) - This has an Ajax.BeginForm() that returns report meta data and has a refresh button. When the refresh button is clicked. I call a js function that loads a div using div.load(ReportModel.RenderLink), which is a url to get the content as html from the controller.
The ReportModel.RenderLink points to a controller method that returns an html report based on model params sent to the controller. The result is a PartialView("ReportContentPartial",string) where string is the html fragment.
For testing the ReportContentPartial just dumps #Model into a div as #Html.Raw(Model) and this is where the browser locks up. I thought it was in an infinite loop but it is just taking way to long to render the html.
The part I do not understand is when I use #Html.BeginForm and dump the #Html.Raw(HTML) it is pretty quick. I need to somehow use the same mechanism used in that rendering method. The report html is fetched and returned in less than a second. The problem is when I trace out of #Html.Raw(HTML) the browser locks and takes +15 seconds to render the content.
I will keep plugging at it. I am sure there is a more efficient way to go about it and I probably need to think about ways to break up the reports.
Update 2: This seems to be development environment issue. I am launching IE from VS2012 using the run command. I sense that something is up with the asp.net dev server. When I load the same url in chrome, while debugging in vs, it renders in less than a second.
I solved this. It seems there was an issue with browser definition files that shipped with .net 40. I resorted back to a forms based version of the reporting application that used .aspx pages and postbacks to see why it would render fast and the MVC version was so slow. When using IE 10 it would not render and I found the _dsoPostBacks were not working on the forms version. I then found Scott Hanselman's blog on browsers definition files and applied the hotfix on the test server and now the mvc version in ie is rendering at an acceptable rate. It has something to do with recognizing the browser and downgrading js support. I do not know why that fixed my problem but it did :)
I have this:
<form id="import_form" method="post" enctype="multipart/form-data" action="/Blah/Blah">
<input type="file" id="fileUpload" name="fileUpload"/>
<input type="submit" name="submit" value="Import"/>
</form>
$('#import_form').submit(function () {
...
});
Here is the c# method:
[AcceptVerbs(HttpVerbs.Post)]
public string Blah(HttpPostedFileBase fileUpload, FormCollection form)
{ ... }
I want when Blah finishes executing a javacript code to start executing. How to do this?
The submit event is called before it.
This depends on how the form is being submitted.
If you're submitting the form via AJAX then you can execute some JavaScript in the handler for the response. However, given that there's a submit button, I'm assuming for the moment that you're not doing this via AJAX and are instead posting the whole page to the server and rendering a response.
In this case, to execute some JavaScript after the form post, you're going to need to render that JavaScript in the response from the server as part of the next page. When the server constructs the view, include the JavaScript you want to execute in that view.
Keep in mind the request/response nature of the web. When something on the server executes, the client is unaware of it and disconnected from it. The end result of any server-side processing should be an HTTP response to the client. In the event of submitting a form or clicking a link or anything which results in a page reload, that response is in the form of a new page (view). So anything that you want to do on the client after the server-side processing needs to happen as part of that response.
Edit: I just noticed that Blah is returning a string. Is this even working for you? How does the form submit result in a new view? Or am I unaware of a feature in ASP.NET MVC?
This is what I did in the end.
My form returns the exact same view with whom it was called.
I add a ViewData in the Blah method.
In the view, in the $(function()) event I check if ViewData has a value, I execute the javascript code.