Getting ASP.NET ImageButton OnClientClick changes to the server - postback

I use an ASP.NET ImageButton on my website. When a user clicks on the ImageButton, a javascript is fired via the OnClientClick event. The script changes the ImageUrl of the ImageButton.
On the same page, I have a submit button.
Clicking the button causes a post back to appear.
Is there a way of knowing the correct ImageUrl of the ImageButton from serverside now when processing the serverside OnClick event of the submit button?

can you store that changed inage url in a hidden text box and at postback you can get the text box.

or you could just use this in your codebehind:
protected void imageclicked(object sender, eventargs e)
{
ImageButton ClickedButton = sender as ImageButton;
}
then you can use ClickedButton.ImageUrl

You can add a hidden field to record what's the image name each time when clien side script fired. When postback, you just check the value of this field.

Related

onSubmit() call multiple time service

I am write a form with some fields, when all have valid then i am enable the submit button, do a service call on onSubmit() method.My issue is when i click on the submit button twice it do service call twice. Is there any directive for check form submit.
When you click on the submit button twice it will call the service two times just use one variable 'submit' boolean by default false.
reference: https://angular.io/guide/forms#submit-the-form-with-ngsubmit
onSubmit() {
if(this.submit) {
return;
}
this.submit = true;
this.serviceCall(); // got error set submit to false.
}

redirect and download pdf on click of radio button

Need a suggestion from people more intelligent than me. I have a modal which has 2 things, essentially, 3 radio buttons (Email, PDF, None)and a Yes and NO submit button.
On press of radio button I flag hidden variables appropriately to know if the user pressed email or pdf in my controller. Than user presses Yes for saving (happy path), and it will call a controller.
This controller will save the changes and redirect to a different page. Now I wanna add to this controller and make it download a pdf. I am doing this by calling my DownloadPDF action.
public ActionResult Main(string id)
//code for doing all the save and other stuff
{
if (viewModel.Email)
{
SendTestingEmail(viewModel.ConsumerEncryptedID);
}
else if(viewModel.PDF)
{
DownloadWelcomePDF()
}
return RedirectToAction("ConsumerIndex", "Consumer")
}
public ActionResult DownloadWelcomePDF(string id)
{
var htmlWelcomeEmail = db.getHtmlBody(id.DecryptID());
var converter = new ConvertToPDF();
var file = converter.ConvertHTMLStringToPDF(htmlWelcomeEmail.EmailBody);
var fileStreamResult = new FileStreamResult(file, "application/pdf") { FileDownloadName = string.Format("Welcome{0}{1}_{2}.pdf", htmlWelcomeEmail.ConsumerFirstName, htmlWelcomeEmail.ConsumerLastName, DateTime.Now.ToString("yyyyMMdd")) };
return fileStreamResult;
}
Now since this will also return pdf content I cannot do both these 2 things (redirecting to a different page and downloading ) at the same time.
Is there any suggestion, I have been searching internet for a long time.
It is essentially download and redirect but download needs to happen only on certain condition (press of radio) and the page should always redirect nonetheless.
You can break this into two steps.
First on submit you do a check in javascript to see if the user wants to download the PDF. If he wants, then call the download action and then call the main method from JS.
Or you can render the customerIndex page first and pass a flag (something like downloadPDFForId). Based on this flag in the JS in CustomerIndex you can download the file.
The first approach would be a cleaner one.

Primefaces DialogFramework - How to show a dialog located in WEB-INF?

I am using Primefaces DialogFramework with
Primefaces 5.0
Mojarra 2.1.27
Glassfish 3.1.2.2 Build 5
My problem is, that if the user knows the location of my dialog, he is able to access it directly via the URL. I do not want that to be possible, so I thought it would be able to put the dialog in WEB-INF folder of my web-app, but now, if I want to open the dialog, I get a FileNotFound-Exception.
If my dialog is located in some regular folder, it works fine
RequestContext.getCurrentInstance().openDialog("/myfolder/mydialog");
// this works as expected
but if it is located in WEB-INF, it does not work any longer
RequestContext.getCurrentInstance().openDialog("/WEB-INF/mydialog",options,null);
// this is causing a fileNotFoundException
I also tried to set up a navigation rule for this in faces-config but again with no success
<navigation-case>
<from-outcome>mydialog</from-outcome>
<to-view-id>/WEB-INF/mydialog.xhtml</to-view-id>
<redirect />
</navigation-case>
How may I open dialogs located in WEB-INF folder, or is it not possible at all?
Thanks in advance
Unfortunately, putting PrimeFaces Dialog Framework dialogs in /WEB-INF in order to prevent direct access is indeed not going to work. The dialogs are loaded entirely client side. On the POST request which opens the dialog, JSF/PrimeFaces returns an oncomplete script with the (public!) URL of the dialog to JavaScript/jQuery, which in turn shows a basic dialog template with an <iframe> whose URL is set to the dialog URL, which in turn loads the content. In effects, 2 requests are being sent, the first to get the dialog's URL and the second to get the dialog's content based on that URL in the <iframe>.
There's no way to keep the dialog in /WEB-INF without falling back to the "traditional" dialog approach via <p:dialog> and conditional display via JS/CSS. There's also no way in the server side to verify based on some headers if the request is coming from an <iframe>, so that all others could simply be blocked. Your closest bet is the referer header, but this can be spoofed.
One way to minimize abuse is checking the presence of pfdlgcid request parameter (identified by Constants.DIALOG_FRAMEWORK.CONVERSATION_PARAM) when a dialog is being requested. PrimeFaces namely appends this request parameter representing "conversation ID" to the dialog URL. Presuming that all dialogs are stored in a folder /dialogs, then you could do the job with a simple servlet filter. Here's a kickoff example which sends a HTTP 400 error when /dialogs/* is being requested without the pfdlgcid request parameter.
#WebFilter("/dialogs/*")
public class DialogFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String id = request.getParameter(Constants.DIALOG_FRAMEWORK.CONVERSATION_PARAM);
if (id != null) {
chain.doFilter(req, res); // Okay, just continue request.
}
else {
response.sendError(HttpServletResponse.SC_BAD_REQUEST); // 400 error.
}
}
// ...
}
However, the abuser might not be that stupid and discover the pfdlgcid request parameter during the normal flow and still be able to open the dialog individually when supplying that parameter, even with a random value. I thought of comparing the actual pfdlgcid value to the known ones. I checked the PrimeFaces DialogNavigationHandler source code, but unfortunately, PrimeFaces doesn't store this value anywhere in the session. You'd need to provide a custom DialogNavigationHandler implementation wherein you store the pfdlgcid value in the session map which in turn is also compared in the servlet filter.
First add the following method to the DialogFilter:
public static Set<String> getIds(HttpServletRequest request) {
HttpSession session = request.getSession();
Set<String> ids = (Set<String>) session.getAttribute(getClass().getName());
if (ids == null) {
ids = new HashSet<>();
session.setAttribute(getClass().getName(), ids);
}
return ids;
}
Then copypaste the PrimeFaces DialogNavigationHandler source code into your own package and add the following line after line 62:
DialogFilter.getIds((HttpServletRequest) context.getExternalContext().getRequest()).add(pfdlgcid);
Replace the <navigation-handler> in faces-config.xml with the customized one.
Finally, alter the if condition in the DialogFilter#doFilter() method as follows:
if (getIds(request).contains(id)) {
// ...
}
Now, this prevents the abuser from attempting to open the dialog with a random ID. This however doesn't prevent the abuser from attempting to open the dialog by copypasting the exact <iframe> URL immediately after opening it. Given the way how the PrimeFaces dialog framework works, there's no way to prevent that. You could at most remove the pfdlgcid value from the session when the dialog is about to returns to the parent. However, when the dialog is closed by pure JS means, then this is also bypassed.
All in all, if you really, really, want to avoid the enduser being able to open the dialog individually, then you can't go around the "traditional" <p:dialog> approach.

Textbox ENTER to save the text to DB -- MVC

I have a text box and if user types something and Hit enter it should save it to the DB.
#Html.TextArea("txtComments", new {#style = "width: 450px;",#placeholder = "Enter Comments here" })
Basically am looking for an event to fire on ENTER. and am implementing in RAZOR MVC.
i saw few ideas of keeping and other stuffs. But i thought this is the better place to post it.
Thanks
Basically am looking for an event to fire on ENTER
You could subscribe to the .keypress() event of the textarea and detect if Enter was pressed:
$(function() {
$('#txtComments').keypress(function() {
var code = e.keyCode ? e.keyCode : e.which;
if(code == 13) {
// Enter was pressed => act accordingly
}
});
});
and am implementing in RAZOR MVC.
Razor is a view engine which runs on the server. You cannot detect key presses on the server. You will have to use client side scripting (javascript) as I have shown previously.

Optionally open a new window in controller Action

In a ASP.Net MVC 2 application I want to do the following: in the action that handles a form post I want to:
Redirect the user to other view in the current browser window
Open a new window showing other info (other view)
That can be done easily setting the target="_blank" attribute in the form element and adding the following jQuery script:
$(function () {
$("form").submit(function () {
window.location = "...";
});
});
The View returned by the action handler will be rendered in the new window where the form is posted to.
But, let's make it a little trickier:
If there are no service layer errors when executing the action, then do the above.
If there's any service layer error when executing the action, then do not open the new window and the view returned by the action must be shown in the same window where the form was in the first place.
E.g.: Imagine that the service layer generates a pdfDocument to show to the user if everything is ok, and that pdf must be shown in a new window.
[HttpPost]
public ActionResult SomeAction(FormCollection form)
{
var serviceMethodParams = ... // convertion from the form data somehow
MemoryStream pdfDocument = null;
if (!serviceLayer.DoSomething(serviceMethodParams, out pdfDocument))
{
// Something went wrong, do not redirect, do not open new window
// Return the same view where error should be displayed
return View(...);
}
// The service method run ok, this must be shown in a new window and the origal window must be redirected somewhere else
return File(pdfDocument.ToArray(), "application/pdf");
}
Note that the original solution work fine when the service returns true, but if the service returns false the view showing the errors is shown in a new window and the original window is redirected somewhere else.
In this situation, the better option would be to simply return a URL specific to that document for the user to point to, and your ajax call, when successful, takes the URL returned from your action method, and then opens a new window itself pointing to that URL. On error, you can display errors or some such - basically, that data is folded in a Json return value.
Outside of an ajax call, the most acceptable pattern to me is to have the view re render, then attach some startup javascript to open the new window pointing to that specific URL.

Resources