Realex MVC Solution (Redirect method) - c#

I have a solution that I built using Webforms that passes over approximately 10 fields to the Realex payments processor server (I use the redirect method), and all works fine there. I'm brand new to MVC and am trying to put in place the same functionality using MVC as I currently have set up with Webforms. With my Webforms solution, I use a buttonclick event handler and a Postback URL, to gather the data I need to pass to Realex and the URL is managed in the Postback.
Using MVC, I don't seem to have the use of an event handler or a Postback URL declaration, or if I do, I can only post back to the form, whereas I need to post my data to an external website.
So in my MVC controller, I have hardcoded in the values (for testing purposes), that I am trying to pass to Realex.
The last line above (return Redirect), is bringing me to the Realex page (it is not letting me see the boxes though for entering credit card details, instead it is returning a 506 error saying "Invalid MerchantID or account number)...
I've been onto Realex and they are telling me that they can see the data above that I'm trying to pass to their server, like my account ID, my order reference, etc.
I've also tried doing it this way within my View, just to get this to post properly:
<input id="ORDER_ID" name="ORDER_ID" type="hidden" value="6264286038162642860381" />
<input id="ACCOUNT" name="ACCOUNT" type="hidden" value="XXXXXXXXX" />
<input id="AMOUNT" name="AMOUNT" type="hidden" value="100" />
/>
But I don't know how to hook up my form fields with my controller, I know I'm still thinking "Webforms" here, and am just not thinking MVC, because I've so little experience with MVC and am finding the transition to MVC more difficult than I though.
Thanks in advance for any help with this...

I think you want something like this, I'm sure there's a more elegant solution but this should work.
public ActionResult ShoppingCart(decimal _TotalPriceBox = 1)
{
//After populating your shopping cart model
ViewBag.MerchantId = My_Cart.MYUSERIDSTRING;
ViewBag.Account = My_Cart.ACCOUNT;
ViewBag.OrderId = My_Cart.ORDER_ID;
ViewBag.Amount = My_Cart.AMOUNT;
//Rest of needed properties
return View()
}
Then in the form inside your view
<form action="https://epage.payandshop.com/epage.cgi" method="post">
<input id="ORDER_ID" name="ORDER_ID" type="hidden" value="#ViewBag.OrderId" />
<input id="ACCOUNT" name="ACCOUNT" type="hidden" value="#ViewBag.Account" />
<input id="AMOUNT" name="AMOUNT" type="hidden" value="#ViewBag.Amount" />
//Rest of inputs needed
<input type="submit" value="send" />
</form>

Related

Check if checkbox is checked MVC controller

On my MVC View I have a few checkboxes:
<form method="POST" id="formRegistration" action="Registration/SubmitRegistration" >
//Other code...
<input name="test1" type="checkbox" />
<input name="test2" type="checkbox" />
</form>
On the controller I get- using a POST request- the data and I insert it to the DataBase:
public void AddRegistered(Registration r)
{
//Other code...
dParameters.Add("test1", r.test1.ToString());
dParameters.Add("test2", r.test2.ToString());
//Other code...
}
The problem is that I keep getting a false value even if the checkbox is checked.
Wham am I missing?
So the first thing you should do it take a look at the actual data being sent to the server with chrome debug tools or similar. What you might find is that your checkbox value will be set to on if checked, or it will be missing completely if un-checked.
One suggestion in the comments was #Html.CheckBoxFor, but this also suffers the fact that nothing will be sent if the checkbox is un-checked and in specific situations that can still become a problem.
You have two solutions - fix it on the client, or fix it on the server.
Fix it on the client:
To do this, you'll need to (with javascript) add a hidden field for every checkbox. Forgive me, I'm not by an editor to test it out but it might look something like this (from memory):
$('input[type="checkbox"]').each(function(el) {
var hidden = $('<input type="hidden" />');
hidden.name = el.name;
el.after(hidden);
el.on("change", function(el) {
hidden.value = el.checked ? "true" : "false";
});
});
Fix it on the server:
To do this, you'll need to create a custom PropertyBinder which recognizes on as a boolean true. This would be set on a property-attribute level. You could alternatively override the global ModelBinder to do this so you don't need to specifically annotate a property for this to work.
Personally, I prefer the "fix it on the client" method, because you will get either true or false posted back to the server every time which is what you'd expect and is the closest to the way that HtmlHelper does it.
You are missing the value attribute:
<input name="test1" type="checkbox" value="true" />
<input name="test2" type="checkbox" value="true" />
As simple as that.
If you don't want to use HtmlHelper class you can do like this
<form method="POST" id="formRegistration" action="Registration/SubmitRegistration" >
<input name="test1" type="checkbox" value="#Model.test1" />
<input name="test2" type="checkbox" value="#Model.test2" />
test1 and test2 should be in your model class.

Input data is not returning by passing through object

I am passing the input data from the .cshtml page to the action method.
Here is my .cshtml page:
#model passingdata
<form asp-controller="Home" method="post" asp-action="About" >
<button class="btn-danger" type="submit" value="Submit"></button>
<div class="form-group">
<label>
<input asp-for="date" placeholder="Date" class="col-md-8" />
</label>
<label>
Select from these Four Classes
<input type="radio" name="class" asp-for="classselect1" id="classselect1" value="classselect1" class="col-md-4" /> <p> #Model.classname1</p>
<input type="radio" name="class" asp-for="classselect2" id="classselect2" value="classselect2" class="col-md-4" /> <p> #Model.classname2</p>
<input type="radio" name="class" asp-for="classselect3" id="classselect3" value="classselect3" class="col-md-4" /> <p> #Model.classname3</p>
<input type="radio" name="class" asp-for="classselect4" id="classselect4" value="classselect4" class="col-md-4" /> <p> #Model.classname4</p>
</label>
</div>
</form>
And here is my controller code which is invoked when i Click on the button.
[HttpPost]
public IActionResult About(passingdata p)
{
ViewData["Message"] = "Your application description page.";
Teacher.classselect1 = p.classselect1;
Teacher.classselect2 = p.classselect2;
Teacher.classselect3 = p.classselect3;
Teacher.classselect4 = p.classselect4;
Teacher.date = p.date;
return View();
}
The input data like date and bool value from the radiobutton is not passing through the object of the class which contain these variables.
Please help me in this.
If i remember correctly, the Name attribute of each radiobutton is how .net MVC will map the values to your model.
In this case, all of your names are "class", which essentially means you have 1 form field named class with 4 options.
I would recommend using the html helper classes, because they will automatically create the proper html for you. The answer to this post should help: When using .net MVC RadioButtonFor(), how do you group so only one selection can be made?
If you dont want to use the helper just remember that when you submit a form, the data that is posted is based on the name of each form field. .Net does some magic in the background to serialize your Model for you, but essentially you are just submitting data in the format "?prop1=val1&prop2=val2".
Update
I figure maybe I should clarify a little better why what you are doing is not working how you expect.
When you post or put data via a form, it passes the input fields (text box, radio button, checkbox, etc...) as either querystring params or are part of the body. Radio buttons work a little differently than other input type. For a radio button, there are multiple input elements, but only one of them is valid. That is handled by using the name attribute. In your case, all of the names are "class", which means that the only thing being passed to the server is a single "?class={val}" (val is the value of which ever radio button is selected).
If your passingdata model had a property called "class", it would be populated. If your goal is to populated all 4 of the classselect properties with different values, you would need the name of each radio button to be different. But if there was only one radio button with each name, then each property could only have 1 value. You would need multiple RadioButtons with the same name to have multiple values (only one of which is selectable for each property).
Hopefully that clarifies what is wrong and gets you in the right direction.

Get input value on server side

I'm having some trouble and not sure what's going on.
I have a form with input value and want to be able to get that input value and send it back to my controller (server side).
My html code
<form action="/Home/Search" method="get">
<button class="search-btn-widget"></button>
<input class="search-field" id="sub" type="text" onblur="if(this.value=='')this.value='Search';" onfocus="if(this.value=='Search')this.value='';" value="Search" />
</form>
Then in my controller I have
string sub = Request["sub"];
However it ends up being null and not sure what's going on. Any ideas?
Just to make it work: add the name attribute
<input class="search-field" id="sub" name="sub" ...
but check this.
You need to add the name attribute to the input tag.
If you pull up the developer console and take a look at the HTTP GET request that is being sent, you will see that no query string is being associated with the request. This will let you know that the issue on the HTML side and not the ASP.Net MVC side.
Update input tag:
<input class="search-field" id="sub" name="sub" type="text" onblur="if(this.value=='')this.value='Search';" onfocus="if(this.value=='Search')this.value='';" value="Search" />
Update Controller Action to:
public ActionResult Search(string sub)
1) If you wanna see your input into the Request you must send your Form as POST:
<form action="/Home/Search" method="POST">
2) Make sure that input has a name:
<input class="search-field" id="sub" name="name"
type="text"
onblur="if(this.value=='')this.value='Search';"
onfocus="if(this.value=='Search')this.value='';"
value="Search" />
Then you will be able so see It in the request
You should add the name attribute to the input element.

How to have Google Custom Search V2 Search element on master page but result on a Child Page

I am trying to Implement the Google CSE in my site, I have formatted the look and feel of the Search box and result on google CSE site, now I want to do the following:
Have the search box on Master page so it shows up every where
Show results on a seperate page say "search.aspx", which is a child page of the Master
On Results page the Search box remain where it is in master page. and there is a div for it to show results.
I know we have following elements that can be used.
<gcse:search>
<gcse:searchbox> and <gcse:searchresults> A two-column layout
<gcse:searchbox-only> A standalone search box
<gcse:searchresults-only> A standalone block of search results.
But i suppose my requirement can only be met by using a combination of above, but not sure which one.
If any one has done this, can you please guide me what is the way to go.
a trick to that is to make a redirect to the search page placing the search on the url, eg something like:
You search everwhere (on master) for the word test, and your code if you are not on search.aspx is make a redirect to:
search.aspx?q=test
Now, inside the search.aspx, you read the query q and place it on the text box that google use to make search and that's all - ah, and one post back to google.
eg the code will looks like:
<form action="search.aspx" id="Form1">
<div>
<input type="hidden" name="cx" value="partner-pub-XXXXXXXXXX" />
<input type="hidden" name="cof" value="FORID:10" />
<input type="hidden" name="ie" value="UTF-8" />
<input type="text" name="q" size="46" value="<%=Server.HtmlEncode(Current.Request["q"]) %>" />
<input type="submit" name="sa" value="Search" />
</div>
</form>

Data transfer from one website to another

I have two websites A and B both written in ASP.NET MVC 3. In website A there is a form which needs to be submitted to website B via POST method. The user has option to post it directly or after encrypting the values.
When I submit form without encryption it is simple form.submit() and I am able to get the values in website B using FormCollection object. But when user selects submit after encryption, I redirect to another action on website A itself where encryption occurs and then this encrypted data is placed in a hidden textbox in the corresponding view and then auto submitted on page load using jQuery to website B. But now I am unable to get any values in FormCollection object on website B.
What could the problem be? Is this happening because of any security feature to prevent XSS or something similar?
Its doubtful its from XSS protections - in that case you would see an exception.
Load up fiddler and make sure you see this data in an element inside your form that is getting posted to website b. if its there in the form that is being submitted - it should be available.
Any reason for not using HTTPS and submitting directly the form to site B?
<form action="https://siteb/someaction" method="POST">
<input type="text" name="key1" value="value1" />
<input type="text" name="key2" value="value2" />
<input type="text" name="key3" value="value3" />
<input type="submit" value="Go ahead" />
</form>
If there is any reason in the case you are encrypting the values into a single hidden input and submitting the form containing this hidden field using javascript, only the value of the hidden field will be sent to site B. So for example if you had the following form:
<form action="http://siteb/someaction" method="POST">
<input type="hidden" name="encrypted" value="some encrypted value" />
</form>
on site B you would fetch the encrypted value like this (don't use FormCollection, it's kinda ugly compared to view models):
[HttpPost]
public ActionResult SomeAction(string encrypted)
{
// TODO: decrypt the encrypted value here to get the orginal string
...
}
And an even more elegant way would be to have a view model defined on site B and a custom model binder for this model that will do the decryption so that the action looks simply like this:
[HttpPost]
public ActionResult SomeAction(SomeViewModel model)
{
// Directly use the model with all the fields in it.
// The custom model binder will take care of the creating it
// from the encrypted request string
...
}

Categories