I am new to MVC, I looked at other solutions to my problem on web but still I can't find what is wrong with my code, I'm using code (as is) from umbraco website, I'm trying to call a function and pass a var from js, I don't understand what is the problem..., tried to solve it with online examples but getting the same error... help
//c#
public class MokedLoginController : SurfaceController
{
[HttpGet]
[Route("umbraco/surface/MokedLogin/DoLogin/{id}")]
public void DoLogin([FromBody]int member)
{
var _member = Services.MemberService.GetById(member);
if (_member != null)
FormsAuthentication.SetAuthCookie(_member.Username, false);
}
}
//js
angular.module('umbraco').controller('MokedLoginController', [
'$scope',
'$http',
'editorState',
'contentResource',
function ($scope, $http, editorState, contentResource) {
// Check if you are creating a new member
$scope.isNew = editorState.current.id <= 0;
// Define the login as member function
$scope.loginAsMember = function () {
// ### Setup cookie ????
var url = '/umbraco/surface/MokedLogin/DoLogin/{id}';
// Get the current member id using the editorState
var _memberId = editorState.current.id;
// Do Login
$http.post(
url, _memberId
).then(
function (response) {
// ### Redirect ????
// Get the redirect page from config
var urlPageRedirect = $scope.model.config.memberRedirectPage;
// Check if page is set in the config
if (urlPageRedirect)
{
contentResource.getNiceUrl(urlPageRedirect).then(function (data) {
window.open(data, '_blank') // Get the first url
});
} else {
// Open the root page
window.open('/', '_blank');
}
},
function (error) {
console.log(error.data);
}
);
};
}
]);
// Do Login
$http.post(
// the famouse exception that comes from ? and why ?
System.ArgumentException: The parameters dictionary contains a null entry for parameter 'member' of non-nullable type 'System.Int32' for method 'Void DoLogin(Int32)'
in 'ThePoolInsurance.Web.Controllers.MokedLoginController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Related
ASP.Net Framework 4.5.2 on Windows
I am configuring my integration with paypal using Server-side REST, my code is the same that this https://github.com/paypal/PayPal-NET-SDK/blob/develop/Samples/Source/PaymentWithPayPal.aspx.cs, no diference.
Payment model
The Payment model created are this:
{"intent":"sale","payer":{"payment_method":"paypal"},"transactions":[{"amount":{"currency":"USD","total":"100.00","details":{"subtotal":"75","shipping":"10","tax":"15"}},"description":"Transaction description.","invoice_number":"608961","item_list":{"items":[{"sku":"sku","name":"Item Name","quantity":"5","price":"15","currency":"USD"}]}}],"redirect_urls":{"return_url":"http://localhost:51379/PaymentWithPayPal.aspx?guid=60896","cancel_url":"http://localhost:51379/PaymentWithPayPal.aspx?guid=60896&cancel=true"}}
After Payment model is created
I create the payment at this line
var createdPayment = payment.Create(apiContext);
CreatedPayment
And the createdPayment variable is equals to:
{"id":"PAY-8TG15254J2564684XLFQUQHQ","intent":"sale","payer":{"payment_method":"paypal"},"transactions":[{"related_resources":[],"amount":{"currency":"USD","total":"100.00","details":{"subtotal":"75.00","shipping":"10.00","tax":"15.00"}},"description":"Transaction description.","invoice_number":"608961","item_list":{"items":[{"sku":"sku","name":"Item Name","quantity":"5","price":"15.00","currency":"USD"}]}}],"state":"created","create_time":"2017-07-08T21:01:18Z","links":[{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-8TG15254J2564684XLFQUQHQ","rel":"self","method":"GET"},{"href":"https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-6PE445186E489192C","rel":"approval_url","method":"REDIRECT"},{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-8TG15254J2564684XLFQUQHQ/execute","rel":"execute","method":"POST"}]}
Error
after, the code continues without any error, and when it finish, the paypal window closes and I am getting the next error on javascript:
Error: No value passed to payment
Object {stack: "Error: No value passed to payment↵ at https://w…://www.paypalobjects.com/api/checkout.js:2390:13)", errtype: "[object Error]", timestamp: 1499547706746, windowID: "5148517b93", pageID: "510d0e1522"…} country:"US" env:"sandbox" errtype:"[object Error]" host:"www.sandbox.paypal.com" lang:"en" pageID:"510d0e1522" path:"/webapps/hermes/button" referer:"http://localhost:51379" stack:"Error: No value passed to payment↵ at https://www.paypalobjects.com/api/checkout.js:7986:52↵ at https://www.paypalobjects.com/api/checkout.js:7417:54↵ at ZalgoPromise.dispatch (https://www.paypalobjects.com/api/checkout.js:7441:27)↵ at ZalgoPromise.resolve (https://www.paypalobjects.com/api/checkout.js:7386:22)↵ at https://www.paypalobjects.com/api/checkout.js:7363:48↵ at https://www.paypalobjects.com/api/checkout.js:7417:54↵ at ZalgoPromise.dispatch (https://www.paypalobjects.com/api/checkout.js:7441:27)↵ at ZalgoPromise.resolve (https://www.paypalobjects.com/api/checkout.js:7386:22)↵ at https://www.paypalobjects.com/api/checkout.js:7440:42↵ at ZalgoPromise.dispatch (https://www.paypalobjects.com/api/checkout.js:7441:27)↵ at Object._RECEIVE_MESSAGE_TYPE.(anonymous function) [as postrobot_message_response] (https://www.paypalobjects.com/api/checkout.js:2471:118)↵ at receiveMessage (https://www.paypalobjects.com/api/checkout.js:2369:77)↵ at messageListener (https://www.paypalobjects.com/api/checkout.js:2390:13)" timestamp : 1499547706746 uid : "8cb15883be" ver : "4.0.89" windowID : "5148517b93" __proto__ : Object
This is my PayPal CheckoutJS
paypal.Button.render({
env: 'sandbox',
commit: true,
payment: function () {
// Set up a url on your server to create the payment
var CREATE_URL = "#Url.Action("MakePaymentWithPayPal", "Payment")";
// Make a call to your server to set up the payment
return paypal.request.post(CREATE_URL)
.then(function (res) {
console.log("res");
console.log(res);//this is always empty
return res.paymentID;
}).catch(function (err) {
reject("err");
reject(err);
});
},
onAuthorize: function (data, actions) {
// Set up a url on your server to execute the payment
var EXECUTE_URL = '/demo/checkout/api/paypal/payment/execute/';
// Set up the data you need to pass to your server
var data = {
paymentID: data.paymentID,
payerID: data.payerID
};
// Make a call to your server to execute the payment
return paypal.request.post(EXECUTE_URL, data)
.then(function (res) {
window.alert('Payment Complete!');
console.log(res);
});
}
}, '#paypal-button');`
Thanks to bluepnume for open my eyes
I changed the method from Void type to String type => this change is for return the response from my server to Client-Side js
At the end of the create payment code, I added one line to save the guid number and the return
HttpContext.Current.Session.Add("guid", guid); //we need this number on authorize payment
HttpContext.Current.Session.Add(guid, createdPayment.id);
HttpContext.Current.Session.Add("flow-" + guid, this.flow);
return JsonConvert.SerializeObject(createdPayment, Formatting.None); //I return the created payment
Now at the JS I changed the return by the correct payment id
payment: function () {
var CREATE_URL = "#Url.Action("MakePaymentWithPayPal", "Payment")";
return paypal.request.post(CREATE_URL)
.then(function (res) {
//return res.paymentID; //earlier line
return res.id;
});
},
And at the begin of the authorize payment code, I exchange the line with which the guid was retrieved to continue the transaction and at the end I return the executed payment
//var guid = HttpContext.Current.Request.Params["guid"]; //earlier line
string guid = HttpContext.Current.Session["guid"].ToString();
//code...
return JsonConvert.SerializeObject(executedPayment, Formatting.None);
and this is ready to make payments.
I have a JSON object like so:
var newContact = {"contact_name":"Joe","contact_cell_phone":"4651354"}
And I need to pass it through to C# ASP backend using Angular $http.post such as:
$scope.Add = function (newContact) {
// I am passing in this string variable "newContact_string", not the function param "newContact"
var newContract_string = JSON.stringify(newContact);
$http
.post('Default.aspx/AddDb_contact', { newContact_string: newContact_string })
.success(function (data) {
console.log("New contact was added with id: " + data.d);
})
.error(function () {
console.log("An error occurred adding the new contact.");
});
};
However, I am hit with this error in the JS console, specifically referring to this line of code:
ReferenceError: newContact_string is not defined
>> $http.post('Default.aspx/AddDb_contact', { newContact_string: newContact_string })
My C# backend code is never reached:
[WebMethod]
public static object AddDb_contact(string newContact_string)
{
return newContact_string;
}
Perhaps it is a syntax error? How would I go about AJAXing the Angular way?
You have a typo.
You declare var newContract_string = JSON.stringify(newContact);
but you pass newContact_string.
You need: { newContact_string: newContract_string }
I have a view with a hidden field
#Html.HiddenFor(model => model.Driver.ID, new { htmlAttributes = new { id = "driver" } })
I have a controller with a method I want to call passing that field "driver", but debugging I see this method doesn't even get called.
public string GetEditWarningMessage(int? driverID)
{
Driver driver = unitOfWork.DriverRepository.Get().Where(d => d.ID == driverID).FirstOrDefault();
string message = null;
if(!driver.Status.Equals("A"))
{
message = "This driver is assigned to current or future schedule movements";
}
return new JavaScriptSerializer().Serialize(message);
}
and finally the javascript, which I'm sure is the source of the problem
$().ready(function () {
$("#driver").change(function () {
$.get("../GetEditWarningMessage/" + $(this).val() + '?' + $.now(), function (response) {
var warning;
warning = $.parseJSON(response);
});
$("form").submit(function () {
var performEdit = false;
if (warning != null) {
performEdit = confirm(warning);
return performDelete;
}
});
});
});
basically if the message I pass from the GetEditWarningMessage() is null, I don't want the popup to appear, otherwise have it popup with the warning message passed on.
Help much appreciated, thank you all
Change the following
$.get("../GetEditWarningMessage/" + $(this).val() + '?' + $.now(), function (response) {
var warning;
warning = $.parseJSON(response);
});
To
var warning;
$.get("../GetEditWarningMessage/" + $(this).val() + '?' + $.now(), function (response) {
warning = $.parseJSON(response);
});
In your code the variable "warning" has scope inside only $.get call. So it cannot be used in form submit call..
Declaring it outside the $.get call will solve the issue.
If the hidden input value doesn't change then you must call GetEditWarningMessage inside the form submit call.. even that Synchronous ajax call so that form submittion can wait for the response of warning message.
So I have thisfunction I have to make. All previous functions have been made pretty much the same way like so:
[Route("MemberInfo"), HttpPost]
public IHttpActionResult ArrayTest([FromBody]Member member)
{
using (var db = new DBContext())
{
var member = db.Members.Where(m => m.email == loginForm.email).FirstOrDefault();
if (member != null)
{
return Ok(new { success = true, message = member });
}
else
{
return Json(new { success = false, message = "Invalid email or password" });
}
}
}
Just an example, there are a lot more lines of code in that function but it was just an example of how I write them.
I use Google's Advanced REST client to make sure all my functions are working. For MemberInfo I give this with the POST option clicked and content-type is application/json:
{
email: "blahblah#gmail.com",
password: "123456789"
}
and I get all my info.
These function are used by another developer who is creating my iPhone app. I am in the process of creating a function to refer a friend/friends.
I created a little test to see how infinite parameters work(in case there are multiple referred emails):
[Route("ArrayTest"), HttpPost]
public IHttpActionResult ArrayTest(params string[] emails)
{
string emailSentence = "";
for (Int32 i = 0; i < emails.Length; i++ )
{
emailSentence += emails[i] + ", ";
}
return Ok(new { success = true, emails = emailSentence });
}
I am having trouble inputing the parameters, how can I do that?
I try it like this:
{
("hello", "buhbye", "ella")
}
and it says "{"Object reference not set to an instance of an object."}"
That's not valid JSON. You can validate your request by running it through jsonlint.com
Try this instead, post the emails as an array
{
"emails": [
"hello",
"buhbye",
"ella"
]
}
I've seen this question asked a few ways and the solutions are generally for other languages and don't apply to ASP.NET MVC 2.
I am using Jquery & Jquery forms to auto-save user data at a set interval. I still want the application to be able to time out, but the auto-saves via jquery forms keep refreshing the server.
My initial idea to fix this was pretty simple. I've already got an ActionFilter I use to see if the session expires. Well, the session won't ever expire; however, I just keep track of how many auto saves occurr based on a value in session and when it reaches a limit (specified in the web.config), it does a:
filterContext.Result = new RedirectResult("~/Account.aspx/LogOn");
Well, this doesn't work because the auto save is doing an ajaxFormSubmit to call the action in the first place. I've tried changing the action to redirect to the login page, but the same thing happens....it just doesn't do a redirect. The only thing the action can return is a Json result. In my latest version (code below) I'm setting the json return value to false and calling a redirectToLogin() function to send the page over to the login page. It doesn't work and i'm not sure why.
Any thoughts on this would be most helpful.
Excerpt of code that sets up the interval for autosaving on the view (placed just before the form is closed):
<%
double sessionTimeoutInMinutes = double.Parse(ConfigurationManager.AppSettings["SESSION_TIMEOUT_IN_MINUTES"].ToString());
double maxContiguousAutoSaves = double.Parse(ConfigurationManager.AppSettings["MAX_CONTIGUOUS_AUTO_SAVES"].ToString());
double autoSaveInterval = (sessionTimeoutInMinutes / maxContiguousAutoSaves) * 60 * 1000;
%>
<%= Html.Hidden("autoSaveInterval", autoSaveInterval) %>
<script type="text/javascript">
$(document).ready(function() {
var autoSaveFrequency = $('[id=autoSaveInterval]').val();
//alert(' Auto Save Interval in miliseconds: ' + autoSaveFrequency);
setInterval(
"initAutoSave('AutoSaveGoals', 'message')"
, autoSaveFrequency);
});
</script>
"AutoSaveGoals" goals is the name of one of my actions. It handles the post, updates certain items in session, and calls the repository.update. It is defined below:
[HttpPost]
public ActionResult AutoSaveGoals(Data data)
{
Data sessdata = Data();
sessdata.MpaGoals = data.Goals;
sessdata.MpaStatus = data.MpaStatus;
sessdata.StartPeriodDate = data.StartPeriodDate;
sessdata.EndPeriodDate = data.EndPeriodDate;
sessdata.AssociatePassword = data.AssociatePassword;
try
{
_repository.update(sessdata);
}
catch (Exception e)
{
LogUtil.Write("AutoSaveGoals", "Auto Save Goals Failed");
LogUtil.WriteException(e);
}
if (!autoLogOffUser(RouteData.GetRequiredString("action")))
return Json(new { success = true });
else
return Json(new { success = false });
}
The initAutoSave function is javascript that uses Jquery & Jquery Forms plugin. Here it is:
function initAutoSave(targetUrl, messageDivId) {
var options = {
url: targetUrl,
type: 'POST',
beforeSubmit: showRequest,
success: function(data, textStatus) {
//alert('Returned from save! data: ' + data);
if (data.success) {
var currDateAndTime = " Page last saved on: " + getCurrentDateAndTime();
$('[id=' + messageDivId + ']').text(currDateAndTime).show('normal', function() { })
}
else {
alert('redirecting to login page');
redirectToLogin();
//$('[id=' + messageDivId + ']').text(' An error occurred while attempting to auto save this page.').show('normal', function() { })
//alert('ERROR: Page was not auto-saved properly!!!!');
}
}
};
$('form').ajaxSubmit(options);
}
I try doing a javascript redirect in redirectToLogin() but it doesn't seem to get the url or something behind the scenes is blowing up. Here is how it's defined:
function redirectToLogin() {
window.location = "Account.aspx/LogOn";
}
best way to solve this is to have your code always return an Json result, i use a model called StandardAjaxResponse that has an ID, a Message and an answer answer is always false unless my code completes in the correct way and sets this to true. Any errors from try / catch are placed into the message field, so if !data.Answer and the Message is equal to not loggged in the you can then location.href to the login page, without getting the login page as your ajax response.
for example:
public class AjaxGenericResponse{
public bool Answer {get;set; }
public int Id {ge; set; } // this is for cases when i want an ID result
public string Mesage {get;set;} // this is so i can show errors from ajax
}
the controller / action
public JsonResult DoAutoSave(Data data){
var JsonResults = new AjaxGenericResponse{Answer=false};
// do code here to save etc
// no matter what always return a result, even if code is broken
return Json(model);
}
your Javascript:
$.ajax({
url:"",
dataTYpe: 'json',
success:function(data){
if(data.Answer) {
// all is good
} else {
if(data.Message === "logout') { href.location=('login'); } else { alert(data.Message); }
}
}
});
thats one solution anyway!
Stupid me. Thanks for your response minus, but I think our solutions coincided for the answer. My issue was I didn't have the right url to redirect to in the redirectToLogin method. I've made minor tweaks, and presto, its redirecting.
Javascript changes:
function redirectToLogin(url) {
window.location = url;
}
function initAutoSave(targetUrl, messageDivId) {
var options = {
url: targetUrl,
type: 'POST',
beforeSubmit: showRequest,
success: function(data, textStatus) {
//alert('Returned from save! data: ' + data);
if (data.success) {
var currDateAndTime = " Page last saved on: " + getCurrentDateAndTime();
$('[id=' + messageDivId + ']').text(currDateAndTime).show('normal', function() { })
}
else {
alert('redirecting to login page');
redirectToLogin(data.url);
//$('[id=' + messageDivId + ']').text(' An error occurred while attempting to auto save this page.').show('normal', function() { })
//alert('ERROR: Page was not auto-saved properly!!!!');
}
}
};
$('form').ajaxSubmit(options);
}
Action changes
if (!shouldAutoLogOffUser(RouteData.GetRequiredString("action")))
return Json(new { success = true, url = "" });
else
return Json(new { success = false , url = Url.Action("LogOff","Account").ToString() });
The shouldAutoLogOffUser checks a session variable that was updated by an action filter to track the # of contiguous auto saves and handles the logic to see if that value has exceeded the max # of contiguous autosaves allowed. The action filter checked the actionname for 'AutoSave' and if it found it, the counter was incremented. Otherwise the counter was reset to 0 (a non autosave post occurred).
One more random question. If this application were loaded in an IFrame and the window.location call is made, would the IFrame content be changed or the entire page (the container in essence) be changed? Our company is looking to run some of our asp.net mvc 2 apps in IFrame's via websphere portal (yeah, I know....it's not my choice).
Now this is just absurd...So, I was looking over my applications (I've got several going to QA soon) and noted that I've already solved this very question with a much better solution - it was ALL handled in an ActionFilter. I wanted this from the getgo when I asked this question, but to have already implemented it, forgot about that, AND ask again on Stack Overflow...well, I hope my memory issues helps somebody with this. Below is the full action filter code. As always, I'm open to criticism so mock it, revise it, copy it, etc, etc.
public class UserStillActiveAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
int sessionTimeoutInMinutes = int.Parse(ConfigurationManager.AppSettings["SESSION_TIMEOUT"].ToString());
int maxContiguousAutoSaves = int.Parse(ConfigurationManager.AppSettings["MAX_CONSEC_SAVES"].ToString());
int autoSaveIntervalInMinutes = int.Parse(ConfigurationManager.AppSettings["AUTO_SAVE_INTERVAL"].ToString());
string actionName = filterContext.ActionDescriptor.ActionName;
string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
HttpContext currentSession = HttpContext.Current;
LogAssociateGoalsSessionStatus(filterContext.HttpContext, actionName);
if (actionName.ToLower().Contains("autosave"))
{
int autoSaveCount = GetContigousAutoSaves(filterContext.HttpContext);
if (autoSaveCount == maxContiguousAutoSaves)
{
var result = new RedirectResult("~/Account.aspx/LogOff");
if (result != null && filterContext.HttpContext.Request.IsAjaxRequest())
{
//Value checked on Logon.aspx page and message displayed if not null
filterContext.Controller.TempData.Add(PersistenceKeys.SessionTimeOutMessage,
StaticData.MessageSessionExpiredWorkStillSaved);
string destinationUrl = UrlHelper.GenerateContentUrl(
result.Url,
filterContext.HttpContext);
filterContext.Result = new JavaScriptResult()
{
Script = "window.location='" + destinationUrl + "';"
};
}
}
else
{
RefreshContiguousAutoSaves(filterContext.HttpContext, autoSaveCount + 1);
}
}
else
{
RefreshContiguousAutoSaves(filterContext.HttpContext, 1);
}
}
private int GetContigousAutoSaves(HttpContextBase context)
{
Object o = context.Session[PersistenceKeys.ContiguousAutoUpdateCount];
int contiguousAutoSaves = 1;
if (o != null && int.TryParse(o.ToString(), out contiguousAutoSaves))
{
return contiguousAutoSaves;
}
else
{
return 1;
}
}
private void RefreshContiguousAutoSaves(HttpContextBase context,
int autoSavecount)
{
context.Session.Remove(PersistenceKeys.ContiguousAutoUpdateCount);
context.Session.Add(PersistenceKeys.ContiguousAutoUpdateCount,
autoSavecount);
}
private void LogAssociateGoalsSessionStatus(HttpContextBase filterContext, string actionName)
{
AssociateGoals ag = (AssociateGoals)filterContext.Session[(PersistenceKeys.SelectedAssociateGoals)];
bool assocGoalsIsNull = false;
bool assocGoalsInformationIsNull = false;
if (ag == null)
{
assocGoalsIsNull = true;
assocGoalsInformationIsNull = true;
}
else if (ag != null && ag.AssociateInformation == null)
assocGoalsInformationIsNull = true;
}
}
always use double quote in java script and jquery to avoid browser specific issues
like
dataTYpe: 'json' must be as "dataTYpe:"json"