using cookies in up/down voting system - c#

I want to build Up/down voting system for several articles retrieved from database, but i want to add cookie for each article to limit number of votes so cookie will expires in one day, but i don't know where to add the appropriate code.
more details:
<script>
function vote(id, value) { // function vote with 2 arguments: article ID and value (+1 or -1) depending if you clicked on the arrow up or down
var dataFields = { 'id': id, 'value': value }; // We pass the 2 arguments
$.ajax({ // Ajax
type: "POST",
dataType: "text",//This for indicate that you'r expecting a text response from server
url: "WebService.asmx/updateVotes",
data: dataFields,
timeout: 3000,
success: function (dataBack) {
if(
$('#number' + id).html(dataBack);// div "number" with the new number
$('#arrow_up' + id).html('<div class="arrow_up_voted"></div>'); // We replace the clickable "arrow up" by the not clickable one
$('#arrow_down' + id).html('<div class="arrow_down_voted"></div>'); // We replace the clickable "arrow down" by the not clickable one
$('#message' + id).html('<div id="alertFadeOut' + id + '" style="color: green">Thank you for voting</div>'); // Diplay message with a fadeout
$('#alertFadeOut' + id).fadeOut(1100, function () {
$('#alertFadeOut' + id).text('');
});
},
error: function () {
$('#number' + id).text('Problem!');
}
});
}
</script>
the above code is a script calling ajax method to increase number of votes per one every time user click on the up arrow and decrease conversely.
public string updateVotes(string id,int value)
{
System.Threading.Thread.Sleep(500); // delay for 2.5 seconds Network latency
post p = db.posts.Find(int.Parse(id));
// assign new values
p.totalVotes += value;
db.Entry(p).State = System.Data.EntityState.Modified;
db.SaveChanges();
string dataBack =p.totalVotes.ToString();
return dataBack;
}
This is the webmethod.
Now i tried to think loudly and i code the following function to ewxamine if the cookie is null or not.
public bool enableVoting()
{
HttpCookie cookie = Request.Cookies["enableVote"];
if (Request.Cookies["enableVote"] != null)
{
return true;
}
else
{
return false;
}
}
i know it's wrong but at least i tried.
also where to add a for each loop to add cookie whenever user vote for article.?
foreach(post p in db.posts){
HttpCookie cookie = new HttpCookie("enableVote"+p.ID);
cookie.Value = "article:"+p.ID;
cookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(cookie);
}

A suggestion. Don't use cookies for this. They are easily manipulated. Clear browser history and you can vote again.. and again.. and again.
Instead, create a Vote table in your database and add a record with the ip of the voter and the id of the post they voted for along with a timestamp.
This way you can easily count the votes and when someone votes you do a quick check on how long ago that IP last voted for that article (or any article).
Also with a vote table in your database you can easily catch bots that are up or downvoting everything, and limit the number of votes a single ip can make on any article (no more than 1 or two votes every few minutes maybe).
If your worried about multiple people behind the same IP not being able to vote you can include the browser name and only count unique ip and browser version as a vote. This is fairly unique. It can also be manipulated but its a little bit harder for the normal user.
Update:
I use this code for the purpose of getting a somewhat unique key in one of my MVC projects. The user can switch browsers and vote again, but it takes a bit of effort and its more of a pain than just clearing browser history.
I combine the IP, browser, and Country into a string and use that as a vote key.
public class UserInfo
{
public String ip { get; private set; }
public String browser { get; private set; }
public String country { get; private set; }
public UserInfo(HttpRequestBase Request)
{
ip = Request.UserHostAddress;
browser = Request.Browser.Platform + " " + Request.Browser.Type + "/" + Request.Browser.Id + " " + Request.Browser.Version;
country = "";
if (Request.UserLanguages.Length > 0)
country += " - " + Request.UserLanguages.ElementAt(0);
}
}
I'm using this system here: http://filepublicator.com/ to check if the user has any previously uploaded files (try to upload something and close browser and go there again, it will be in the list).

Related

datacollection program not correctly collecting

I created an data collection app for our company which collect data from our remote devices.
The data is collected from a datamailbox which is comparable with an database that works like an 10 day buffer to store the data. this is all correctly working.
The data is collected through post api requests. for example :
var url = BuildUrl("syncdata");
var response = webClient.CallApi(url, new NameValueCollection() { { "createTransaction","" }, { "lastTransactionId", transactionId } });
var data = DynamicJson.Parse(response);
transactionId = data.transactionId;
I've been trying to collect multiple devices at one time but the problem is that it starts running and collect the data from the first device which works. Than our second device will start collecting the data but it only starts from where device one ended so i've been losing 12hours of data each run. For performance we use transactionId's.(each set of data has its own Id)
The workflow should be like this :
When the data is retrieved for the first time, the user specifies only
the createTransaction filter. The DataMailbox returns all the data of
all devices gateways – with historical data – of the account along a
transaction ID. For the next calls to the API, the client specifies
both createTransaction and lastTransactionId filters. The
lastTransactionId is the ID of the transaction that was returned by
the latest request. The system returns all the historical
data that has been received by the DataMailbox since the last
transaction and a new transaction ID. deviceIds is an additional
filter on the returned result. You must be cautious when using the
combination of lastTransactionId, createTransaction and deviceIds.
lastTransactionId is first used to determine what set of data — newer
than this transaction ID and from all the Device gateways — must be
returned from the DataMailbox, then deviceIds filters this set of data
to send data only from the desired device gateways. If a first request
is called with lastTransactionId, createTransaction and deviceIds, the
following request — implying a new lastTransactionId — does not
contain values history from the previous lastTransactionId of the
device gateways that were not in the deviceId from previous request.
I'm really struggling with the data collection and have no clue how to use the TransactionId and the LastTransActionId.This is the code for now
try
{
CheckLogin();
using (var webClient = new MyWebClient())
{
bool moreDataAvailable;
int samplesCount = 0;
string transactionId = Properties.Settings.Default.TransactionId;
string lastTransactionId = Properties.Settings.Default.LastTransactionId;
do
{
var url = BuildUrl("syncdata");
var response = webClient.CallApi(url, new NameValueCollection() { { "createTransaction","" }, { "lastTransactionId", transactionId } });
var data = DynamicJson.Parse(response);
transactionId = data.transactionId;
var talk2MMessage = getTalk2MMessageHeader(webClient);
if (talk2MMessage != null)
{
}
foreach (var ewon in data.ewons)
{
Directory.CreateDirectory(ewon.name);
foreach (var tag in ewon.tags)
{
try
{
Console.WriteLine(Path.Combine(ewon.name, tag.name + ""));
foreach (var sample in tag.history)
{
Console.WriteLine(ewon.name + " " + tag.name + " " + tag.description);
Console.WriteLine(transactionId);
samplesCount++;
}
}
catch (RuntimeBinderException)
{ // Tag has no history. If it's in the transaction, it's most likely because it has alarm history
Console.WriteLine("Tag {0}.{1} has no history.", ewon.name, tag.name);
}
}
}
Console.WriteLine("{0} samples written to disk", samplesCount);
// Flush data received in this transaction
if (Properties.Settings.Default.DeleteData)
{
//Console.WriteLine("Flushing received data from the DataMailbox...");
url = BuildUrl("delete");
webClient.CallApi(url, new NameValueCollection() { { "transactionId", transactionId } });
Console.WriteLine("DataMailbox flushed.");
}
//save the transaction id for next run of this program
Properties.Settings.Default.LastTransactionId = lastTransactionId;
Properties.Settings.Default.Save();
// Did we receive all data?
try
{
moreDataAvailable = data.moreDataAvailable;
}
catch (RuntimeBinderException)
{ // The moreDataAvailable flag is not specified in the server response
moreDataAvailable = false;
}
if (moreDataAvailable)
Console.WriteLine("There's more data available. Let's get the next part...");
}
while (moreDataAvailable);
Here are my credentials for starting the collection like all parameters
static void CheckLogin()
{
if (string.IsNullOrEmpty(Properties.Settings.Default.Talk2MDevId))
{
Properties.Settings.Default.Talk2MDevId = Prompt("Talk2MDevId");
Properties.Settings.Default.APIToken = Prompt("API Token");
string deleteInputString = Prompt("Delete data after synchronization? (yes/no)");
Properties.Settings.Default.DeleteData = deleteInputString.ToLower().StartsWith("y");
Properties.Settings.Default.TransactionId = "";
Properties.Settings.Default.LastTransactionId = "";
Properties.Settings.Default.Save();
}
I think it's something with the transactionId and LastTransaction id but i have no clue.
More information can be found here: https://developer.ewon.biz/system/files_force/rg-0005-00-en-reference-guide-for-dmweb-api.pdf
As I understand your question, you problem is that for the first few transactionIds, you only get data from device 1 and then only data from device 2.
I'm assuming the following in my answer:
You didn't specify somewhere else in code the filter on "ewonid"
When you say you lose 12 hours of data , you are assuming it because "device 2" data are streamed after "device 1" data.
You did try without the /delete call with no change
/syncdata is an endpoint that returns a block of data for an account since a given transactionId (or oldest block if you didn't provide a transactionID). This data is sorted by storage date by the server, which depends on multiple factors:
when was the device last "vpn online"
at which frequency the device is pushing data to datamailbox
when was that device packet digested by datamailbox service
You could technically have 1 year old data pushed by a device that gets connected back to vpn now, and those data would be registered in the most recent blocks.
For those reasons, the order of data block is not the order of device recording timestamp. You always have to look at the field ewons[].tags[].history[].date to known when that measure was made.
foreach (var sample in tag.history)
{
Console.WriteLine(ewon.name + " " + tag.name + " " + tag.description);
Console.WriteLine(sample.value + " at " + sample.date);
Console.WriteLine(transactionId);
samplesCount++;
}
In your case, I would assume both devices are configured to push their data once a day, one pushing it's backlog, let's say, at 6AM and the other at 6PM.

Kongregate API (Unity WebGL C#): What happens with the user data if the player is not using an account?

I am interested solely in what happens with the userinfo if a player is not signed into their Kongregate, I need to check for this as I will be saving game progress on a server and of course I don't want to be writing random save records into my database that will never actually be used.
My code is as follows
public void OnKongregateAPILoaded(string userInfoString)
{
var info = userInfoString.Split('|');
var userId = System.Convert.ToInt32(info[0]);
var username = info[1];
var gameAuthToken = info[2];
Debug.Log("Kongregate User Info: " + username + ", userId: " + userId);
}
More specifically what I'm asking for is, will something such as username return null? Or something in general that I can check for?
Username changes to: "Guest"
Id changes to: 0

how to cancel last subscription in paypal using asp.net

Hi i am using recurring paypal subscription button that works perfectly.But i want to know the way to cancel last subscription of same user.
Explanation:
I have 1 user,3 users and 6 users plans.
I did the subscription part for all types now what i want:
lets say user change from one user to three users
and go to payment screen to upgrade
Will the last subscription will end automatically or not.
i found this code for cancel subscription:
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_subscr-find&alias=SGGGX43FAKKXN">
this is the code i use for subscription button that works perfectly:
protected void btnsubscribe_Click(object sender, EventArgs e)
{
decimal amt = 0;
if (ddlPlanType.SelectedValue.ToString() != "6")
{
amt = Convert.ToDecimal(ddlPlanType.SelectedValue);
}
else
{
int userNo = 0;
if (txtusers.Text.Trim() != "")
userNo = Convert.ToInt32(txtusers.Text);
amt = Convert.ToDecimal(ddlPlanType.Items[2].Value) + Convert.ToDecimal(10.95 * userNo);
}
int qty = Convert.ToInt32(rdoplantype.SelectedValue);
StringBuilder sb = new StringBuilder();
sb.Append("business=" + ConfigurationManager.AppSettings["paypalemail"].ToString());
sb.Append("&return=" + ConfigurationManager.AppSettings["SuccessURL"].ToString());
sb.Append("&cancel_return=" + Server.UrlEncode(ConfigurationManager.AppSettings["FailedURL"].ToString()));
sb.Append("&button_subtype=services&upload=1&no_note=1&rm=2");
sb.Append("&currency_code=USD&cmd=_xclick-subscriptions&src=1&modify=0&item_number=Standard&p3=1");
if (qty == 1)
{
Server.UrlEncode(sb.AppendFormat("&t3={0}", "M").ToString());
Server.UrlEncode(sb.AppendFormat("&a3={0}", amt).ToString());
}
else if (qty == 12)
{
Server.UrlEncode(sb.AppendFormat("&t3={0}", "Y").ToString());
Server.UrlEncode(sb.AppendFormat("&a3={0}", amt*12).ToString());
}
Server.UrlEncode(sb.AppendFormat("&item_name={0}", ddlPlanType.SelectedItem.Text + " " + txtusers.Text).ToString());
Response.Redirect(ConfigurationManager.AppSettings["PayPalUrl"].ToString() + sb.ToString());
Response.Redirect("Success.aspx");
}
Does this code works for cancel last subscription?
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_subscr-find&alias=SGGGX43FAKKXN">
Thanks
The code does not actually cancel the subscription. This example was taken from the docuentation:
<IMG BORDER="0"SRC="https://www.paypalobjects.com/en_US/i/btn/btn_unsubscribe_LG.gif">
It displays an "Unsubscribe" button image to the user that links to the subscription cancellation function on the PayPal website. the user must log into their PayPal account to continue. the email address or payer ID here:
cmd=_subscr-find&alias=alice%40mystore%2ecom
is identifying you as the subscription provider to be cancelled. they will have to click another "Unsubscribe" button here to complete the process.
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_subscr-find&alias=SGGGX43FAKKXN">
<img src="https://www.paypalobjects.com/en_US/i/btn/btn_unsubscribe_LG.gif" BORDER="0">
</a>
This HTML makes it very easy for us to create an Unsubscribe button and place it wherever we want. Before we can use this, though, we need to make one change to the href attribute. At the end of the URL for the href, you’ll see alias=SGGGX43FAKKXN. This alias parameter is defined by PayPal as “the secure merchant account ID of the subscription provider’s PayPal account. This value is in the My business info section of your PayPal account profile.” Replace the value SGGGX43FAKKXN with your own ID.

Manage booking policy of resources in Exchange 2013 via Managed Api

I want to manage the booking policy of a room, maximum duration of a meeting for example. Do someone has idea how do you do that via Managed API?
The managed API cannot police max duration but what you need todo is validate the entry before you submit a reservation...
public override bool IsNoOverTimeLimit(Reservation reservation)
{
return reservation.End.Subtract(reservation.Start).TotalMinutes <= 120;
}
if(!IsNoOverTimeLimit)
{
var errorMsg = new Label();
var fontSize = FontUnit.Point(10);
errorMsg.Font.Size = fontSize;
errorMsg.Text = "Reservation time is limited to " + ((float)30 / 60).ToString(CultureInfo.InvariantCulture) + " hours at a time.<br /> ";
placeHolder.Controls.Add(errorMsg);
}
My version is way more complicated than this but you get the point. Just simply check the reservation before you submit and if over time limit, return to page with some pretty warning..

Address Validator using Google Maps

I am creating a address validator web application using google maps.my UI:
]
Now which I want is after pressing ok button address should be shown into your address look like field like this 701 1st, Sunnywale, CA 94089
now my ok button click event is
FullAddress.Text = AddressLine1.Text + ',' + ' ' + City.Text + ',' + ' ' + State.Text+ ' ' +Zip.Text;
but when i add javascript to call google maps with my program its not working its throgh a error like as sample pic. Please help me guys.
ok button :
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="OK"
Width="62px" style="margin-left: 0px" />
Validate & Locate Me Button code:
<asp:Button ID="Submit" runat="server" style="margin-left: 97px" Text="Validate & Locate Me" Width="137px" />
Now jQuery and geocode part:
<script type="text/javascript">
// The following code show execute only after the page is fully loaded
$(document).ready(function () {
if ($('#MyForm').exists()) {
// Enable jQuery Validation for the form
$("#MyForm").validate({ onkeyup: false });
// Add validation rules to the FullAddress field
$("#FullAddress").rules("add", {
fulladdress: true,
required: true,
messages: {
fulladdress: "Google cannot locate this address."
}
});
// This function will be executed when the form is submitted
function FormSubmit() {
$.submitForm = true;
if (!$('#MyForm').valid()) {
return false;
} else {
if ($("#FullAddress").data("IsChecking") == true) {
$("#FullAddress").data("SubmitForm", true);
return false;
}
alert('Form Valid! Submit!');
// return true; // Uncomment to submit the form.
return false; // Supress the form submission for test purpose.
}
}
// Attach the FormSubmit function to the Submit button
if ($('#Submit').exists()) {
$("#Submit").click(FormSubmit);
}
// Execute the ForumSubmit function when the form is submitted
$('#MyForm').submit(FormSubmit);
}
});
// Create a jQuery exists method
jQuery.fn.exists = function () { return jQuery(this).length > 0; }
// Position the Google Map
function Map(elementId, geolocation) {
var myOptions = {
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById(elementId), myOptions);
map.setCenter(geolocation);
}
// FullAddress jQuery Validator
function FullAddressValidator(value, element, paras) {
// Convert the value variable into something a bit more descriptive
var CurrentAddress = value;
// If the address is blank, then this is for the required validator to deal with.
if (value.length == 0) {
return true;
}
// If we've already validated this address, then just return the previous result
if ($(element).data("LastAddressValidated") == CurrentAddress) {
return $(element).data("IsValid");
}
// We have a new address to validate, set the IsChecking flag to true and set the LastAddressValidated to the CurrentAddress
$(element).data("IsChecking", true);
$(element).data("LastAddressValidated", CurrentAddress);
// Google Maps doesn't like line-breaks, remove them
CurrentAddress = CurrentAddress.replace(/\n/g, "");
// Create a new Google geocoder
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': CurrentAddress }, function (results, status) {
// The code below only gets run after a successful Google service call has completed.
// Because this is an asynchronous call, the validator has already returned a 'true' result
// to supress an error message and then cancelled the form submission. The code below
// needs to fetch the true validation from the Google service and then re-execute the
// jQuery form validator to display the error message. Futhermore, if the form was
// being submitted, the code below needs to resume that submit.
// Google reported a valid geocoded address
if (status == google.maps.GeocoderStatus.OK) {
// Get the formatted Google result
var address = results[0].formatted_address;
// Count the commas in the fomatted address.
// This doesn't look great, but it helps us understand how specific the geocoded address
// is. For example, "CA" will geocde to "California, USA".
numCommas = address.match(/,/g).length;
// A full street address will have at least 3 commas. Alternate techniques involve
// fetching the address_components returned by Google Maps. That code looks even more ugly.
if (numCommas >= 3) {
// Replace the first comma found with a line-break
address = address.replace(/, /, "\n");
// Remove USA from the address (remove this, if this is important to you)
address = address.replace(/, USA$/, "");
// Check for the map_canvas, if it exists then position the Google Map
if ($("#map_canvas").exists()) {
$("#map_canvas").show();
Map("map_canvas", results[0].geometry.location);
}
// Set the textarea value to the geocoded address
$(element).val(address);
// Cache this latest result
$(element).data("LastAddressValidated", address);
// We have a valid geocoded address
$(element).data("IsValid", true);
} else {
// Google Maps was able to geocode the address, but it wasn't specific
// enough (not enough commas) to be a valid street address.
$(element).data("IsValid", false);
}
// Otherwise the address is invalid
} else {
$(element).data("IsValid", false);
}
// We're no longer in the midst of validating
$(element).data("IsChecking", false);
// Get the parent form element for this address field
var form = $(element).parents('form:first');
// This code is being run after the validation for this field,
// if the form was being submitted before this validtor was
// called then we need to re-submit the form.
if ($(element).data("SubmitForm") == true) {
form.submit();
} else {
// Re-validate this property so we can return the result.
form.validate().element(element);
}
});
// The FullAddress validator always returns 'true' when initially called.
// The true result will be return later by the geocode function (above)
return true;
}
// Define a new jQuery Validator method
$.validator.addMethod("fulladdress", FullAddressValidator);
</script>
</body>
</html>
Please help after pressing ok button full address isnt shown into Your address look like field.Instead of that its through a message: This Field is required. If further more details needed please mention it
Simply use 2 FORMS to keep your controls. First one will have the address fields and the OK button.
Second will have the rest. Change your code accordingly. It should work. Otherwise you need to assign classes and group the controls into 2 sets.
What I mean by 2 sets is that "OK" button should validate the fields above it. And "Validate and Locate Me" button should validate only "Your address look like" text box. With jquery you can think of many ways how to group controls and validate them.
If this is not solving please provide the HTML as well or use http://jsfiddle.net/
-- edit --
The problem you have is when you press OK, it validates a field beneath it. Now what I feel is you have used a Required Field Validator without any grouping. Please specify a ValidationGroup property to separate the validation criteria of "OK" button and "Validate and Locate Me" button.
If you don't know how to use ValidationGroup let me know.
~ CJ

Categories