Facebook Credits callback in a mobile web application - asp.net

I'm trying to create a Facebook Mobile Application using asp.net and MVC3 and integrate Facebook Credits as a payment method. First of all, taking the recent annoucements into consideration, is it now possible to have a mobile web application that accepts Facebook Credits?
If so, I've taken the example provided in the following post
http://www.m-webs.com/blog_facebookcredits.html
And implemented the following Controller action:
public JsonResult CallBack()
{
string fborder_info = Request.Form["order_info"];
string fborder_id = Request.Form["order_id"];
string fbmethod = Request.Form["method"];
if (fbmethod == "payments_get_items")
{
fborder_info = fborder_info.Substring(1, (fborder_info.Length - 2)); // remove the quotes
ulong credscost = 2; // Price of purchase in facebook credits
var theItem = new FacebookBuyItem()
{
item_id = 123456789,
description = "Own yours today!",
price = credscost,
title = "Digital Unicorn",
product_url = "http://www.facebook.com/images/gifts/21.png",
image_url = "http://www.facebook.com/images/gifts/21.png"
};
var res = new Dictionary<string, object>();
res["method"] = fbmethod;
res["order_id"] = fborder_id;
res["content"] = new object[] { theItem };
var jss = new JavaScriptSerializer();
var ob = jss.Serialize(res);
ob = ob.Replace("#$", #"\/".Replace("//", #"\/"));
return Json(ob, JsonRequestBehavior.AllowGet);
}
return null;
}
I've verified that the callback is being requested by facebook, and I've also captured the response being sent back, which appears to contain all of the required information to display the purchase dialog, but I'm still getting the following error message:
API Error Code: 1151
API Error Description: Sorry, but this app may not be eligible to accept Facebook Credits. If this app has accepted credits before, please try again.
Error Message: Invalid Application
and when tested from a mobile browser:
Sorry, but we're having trouble processing your payment. You have not been charged for this transaction. Please try again.
I've also noticed that my callback is being requested twice which doesn't seem right either.
Any insight into how to get my integration up and running would be greatly appreciated. My Facebook AppId is 177876855621874
Thanks.

Update: So I played around with the examples given and reverted back to webforms in order to test the example given at http://www.m-webs.com/blog_facebookcredits.html. In order to get this solution working in an asp.net MVC3 application I had to change the action type to HttpResponse instead of JsonResult which makes sense as the JsonResult leaves elements out that would normally be included in a HttpResponse.
So the Controller Action ended up looking like this:
[HttpPost]
public HttpResponse CallBack()
{
if (Request.Form["signed_request"] != null)
{
var decodeFbSignedRequest = FacebookSignedRequest.Parse(FacebookApplication.Current.AppSecret,
Request.Form["signed_request"]);
LogHelper.MicroLogMsg("SIGNED REQUEST DECODE:: " + decodeFbSignedRequest.Data);
}
string fborder_id = Request.Form["order_id"];
string fbmethod = Request.Form["method"];
string fborder_info = Request.Form["order_info"]; // Use this to look up a product on the database..
if (fbmethod == "payments_get_items")
{
int credscost = 2; // Price of purchase in facebook credits
var theItem = new FacebookBuyItem()
{
item_id = "123456AA",
description = "[Test Mode] Own yours today!",
price = credscost,
title = "[Test Mode] Digital Unicorn",
product_url = #"http:\/\/www.facebook.com\/images\/gifts\/21.png",
image_url = #"http:\/\/www.facebook.com\/images\/gifts\/21.png"
};
// Return the initial response to FB
//------------------------------------------
var res = new Dictionary<string, object>();
res["method"] = fbmethod;
res["content"] = new object[] { theItem };
var jss = new JavaScriptSerializer();
string ob = jss.Serialize(res);
LogHelper.MicroLogMsg(ob);
Response.ContentType = "application/json";
Response.Write(ob);
Response.End();
}
return null;
}
I hope this helps out anyone doing an MVC3 implementation for Facebook Credits.

Related

Web API is not able to serialize the DateTime sent as "LOGINDATE": "2020-04-05T01:00:21.45+04:00". it only accepts Date(milliseconds)

Maybe I am confused or due to working from home I am not able to think.
I have Web API 2.0 project which is receiving models in end points. I have android client which is sending Date in milliseconds format and for same end point i have MVC client which is sending date in "LOGINDATE": "2020-04-05T01:00:21.45+04:00". the date from MVC is not accepted by API and gives an error on model state like
System.FormatException: DateTime content
'2020-04-05T10:52:42.333+04:00' does not start with '/Date(' and end
with ')/' as required for JSON.
I have forced the WebApi to use the newtonsoft json formatter but when i debug the exception i found
System.Runtime.Serialization.Json.JsonReaderDelegator.ParseJsonDateInDefaultFormat(String originalDateTimeValue)
Following is the WEBAPICONFIG code for forcing use the newtonsoft mediatype.
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.UseDataContractJsonSerializer = true;
JsonSerializerSettings CustomJsonSetting = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
DateTimeZoneHandling = DateTimeZoneHandling.Local,
DateFormatHandling = DateFormatHandling.IsoDateFormat,
//DateFormatString = "yyyy-mm-dd HH:MM:ss"
};
CustomJsonSetting.Converters.Clear();
CustomJsonSetting.Converters.Add(new IsoDateTimeConverter());
JsonConvert.DefaultSettings = () => CustomJsonSetting;
jsonFormatter.SerializerSettings = CustomJsonSetting;
config.Formatters.Clear();
config.Formatters.Insert(0,jsonFormatter);
Then from MVC client i am compressing GZIP and sending the call like following:
var frmt = UniversalFormatters.GetJsonFormatter();
if (IsCompressionEnabled)
{
var json = JsonConvert.SerializeObject(request, frmt.SerializerSettings);
//new JavaScriptSerializer().Serialize(request);
//
client.DefaultRequestHeaders.Add("pHubCompression", "1");
var content = new CompressedContent(
new StringContent(json, Encoding.UTF8, "application/json"),
CompressionMethod.GZip);
return await client.PostAsync(EndPoint, content);
}
else
return await client.PostAsync(EndPoint, request, frmt);
And Universal Formatter is defined as
public static JsonMediaTypeFormatter GetJsonFormatter()
{
if (JsonFormatter==null)
{
JsonFormatter = new JsonMediaTypeFormatter();
JsonFormatter.UseDataContractJsonSerializer = true;
JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
JsonFormatter.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
JsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
JsonFormatter.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
JsonFormatter.SerializerSettings.DateFormatString = "yyyy-MM-ddTHH:mm:ss";
}
return JsonFormatter;
}
I have done a bit R&D and people mentioned to create my own date formater which is a work around but i wanted to know if there is something wrong with my setting.
My Model is defined like following:
[System.Runtime.Serialization.DataContractAttribute(Namespace = "http://MyProj.Core.Entities", Name = "RequestObject{0}")]
public class RequestObject<T> : IDisposable//, IEntity
//where T : IEntity, IEntityCollection, ICompositeEntity
{
private UserInfo m_userInfo;
private T m_obj;}
and UserInfo is defined like
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Namespace = "http://MyProj.Business.Contracts", Name = "UserInfo")]
public partial class UserInfo : BaseEntity, IEntity, IDisposable
{
[System.Runtime.Serialization.DataMember(EmitDefaultValue = true)]
public DateTime? LOGINDATE { set; get; }}
Sorry for my bad English.
according to above comment by #dbc I removed JsonFormatter.UseDataContractJsonSerializer = true; this line from my startups and everything starts working. Thanks for the help.

Response on created context keeps giving me NullStream

I'm trying to write a middleware for batch requests i .net core 2.0.
So far the I have splitted the request, pipe each request on to the controllers.
The controllers return value, but for some reason the response on the created context that I parse to the controllers keeps giving me a NullStream in the body, so I think that there is something that I miss in my setup.
The code looks like this:
var json = await streamHelper.StreamToJson(context.Request.Body);
var requests = JsonConvert.DeserializeObject<IEnumerable<RequestModel>>(json);
var responseBody = new List<ResponseModel>();
foreach (var request in requests)
{
var newRequest = new HttpRequestFeature
{
Body = request.Body != null ? new MemoryStream(Encoding.ASCII.GetBytes(request.Body)) : null,
Headers = context.Request.Headers,
Method = request.Method,
Path = request.RelativeUrl,
PathBase = string.Empty,
Protocol = context.Request.Protocol,
Scheme = context.Request.Scheme,
QueryString = context.Request.QueryString.Value
};
var newRespone = new HttpResponseFeature();
var requestLifetimeFeature = new HttpRequestLifetimeFeature();
var features = CreateDefaultFeatures(context.Features);
features.Set<IHttpRequestFeature>(newRequest);
features.Set<IHttpResponseFeature>(newRespone);
features.Set<IHttpRequestLifetimeFeature>(requestLifetimeFeature);
var innerContext = _factory.Create(features);
await _next(innerContext);
var responseJson = await streamHelper.StreamToJson(innerContext.Response.Body);
I'm not sure what it is I'm missing in the setup, since innerContext.Response.Body isn't set.
One of the endpoints that I use for testing and that gets hit looks like this
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
I found the error, or two errors for it to work.
First I had to change my newResponse to
var newRespone = new HttpResponseFeature{ Body = new MemoryStream() };
Since HttpResponseFeature sets Body to Stream.Null in the constructor.
When that was done, then Body kept giving an empty string when trying to read it. That was fixed by setting the Position to Zero like
innerContext.Response.Body.Position = 0;

Preserve text line breaks to when collecting from database in ASP.NET MVC

I'm very new to programming and are trying hard to learn. I've been struggling with an issue for a few hours without understanding what I'm doing wrong.
My goal is to save text (article with a lot of line breaks) to a database, and then retrieve the text and view the output as it was written, with all line breaks preserved.
The text is part of an object named KaseriInfo.
I've read some topics regarding this and tried the following:
Before saving to the Db I use the inputText.Replace("\r\n", "<br />");
After retrieving from Db I user the inputText.Replace("<br />", "\r\n");
I've been mixing with the .Replace-methods in different ways but I won't get the result I wish for.
This is my code for adding to the database using a local web service:
public bool AddKaseri(KaserierInfo kaseri)
{
bool successOrNot = false;
Kaserier kaseriToBeAdded = new Kaserier();
kaseriToBeAdded.Title = kaseri.Title;
kaseriToBeAdded.Content = kaseri.Content.Replace("\r\n", "<br />");
kaseriToBeAdded.About = kaseri.About;
kaseriToBeAdded.Uploaded = DateTime.Now;
db.Kaseriers.Add(kaseriToBeAdded);
try
{
db.SaveChanges();
successOrNot = true;
}
catch (Exception e)
{
Console.WriteLine(e);
}
return successOrNot;
}
And this is the code for retrieving the data from the Db:
public KaserierInfo GetOneKaseri(int id)
{
var result = from row in db.Kaseriers
where row.Id == id
select row;
KaserierInfo kaseri = new KaserierInfo();
var kas = result.FirstOrDefault();
if (kas != null)
{
kaseri.Id = kas.Id;
kaseri.Title = kas.Title;
kaseri.About = kas.About;
kaseri.Content = kas.Content.Replace("<br />", "\r\n");
kaseri.UploadedDateOnly = kas.Uploaded.ToString();
kaseri.Uploaded = kas.Uploaded;
kaseri.UploadedDateOnly = kaseri.Uploaded.ToLongDateString();
}
return kaseri;
}
What is stored in the Db
The HTML-output won't come with line breaks for some reason. This is what is displayed:
Output on website
Here is the C# code inside the controller responsible:
public ActionResult ViewKaseri(int id)
{
//Getting the object from WS
var kas = kasref.GetOneKaseri(id);
//Moving to local object
KaseriModel kaseri = new KaseriModel();
kaseri.Id = kas.Id;
kaseri.About = kas.About;
kaseri.Title = kas.Title;
kaseri.Content = kas.Content;
kaseri.UploadedDateOnly = kas.UploadedDateOnly;
return View(kaseri);
}
I would be glad to solve this so that the line breaks will be rendered correctly. Please keep in mind that my skills are low.
Best
/J
you need to use #Html.Raw(). This will allow you to display the contents

upload image to twitter with twitterizer

I try to upload image with my tweet in twitterizer component.I send tweet without any error but UpdateWithMedia Has Error.
I think this happen because My Request Url Is "https://upload.twitter.com/1/statuses/update_with_media.json" while Shoujd be "https://upload.twitter.com/1.1/statuses/update_with_media.json".
How can i change My RequestUrl.
My Contetnt Error is : "{"errors":[{"message":"The Twitter REST API v1 is no longer active. Please migrate to API v1.1. https://dev.twitter.com/docs/api/1.1/overview.","code":64}]}"
I see many solution in stackoverflow But it was not any thing to solve this problem
var oauth_consumerkey = "UEI02iC13cR8o8rgNyLpBpOmW";
var oauth_consumersecret = "RaTQoZaxq51eHR51TbTKK762eSu5u5s7FoPPswyWMJlscuC6j0";
const string callbackurl = "http://localhost:2008/WebForm1.aspx";
if (Request["oauth_token"] == null)
{
OAuthTokenResponse reqtoken = OAuthUtility.GetRequestToken(
oauth_consumerkey,
oauth_consumersecret,
callbackurl);
Response.Redirect(string.Format("http://twitter.com/oauth/authorize?oauth_token={0}", reqtoken.Token));
}
else
{
string requesttoken = Request["oauth_token"].ToString();
string pin = Request["oauth_verifier"].ToString();
var token = OAuthUtility.GetAccessToken(
oauth_consumerkey,
oauth_consumersecret,
requesttoken,
pin);
OAuthTokens accesstoken = new OAuthTokens()
{
AccessToken = token.Token,
AccessTokenSecret = token.TokenSecret,
ConsumerKey = oauth_consumerkey,
ConsumerSecret = oauth_consumersecret
};
byte[] photo = ImageToByteArray("C:\\black_arrow.png");
TwitterResponse<TwitterStatus> response = TwitterStatus.UpdateWithMedia(accesstoken, "Testing!! Send Image", photo, new StatusUpdateOptions() { UseSSL = true, APIBaseAddress = "http://api.twitter.com/1.1/" });
if (response.Result == RequestResult.Success)
{ Response.Write("OK"); }
else
{ Response.Write("Faild"); }
}
solved,
I've used the latest version of which was in Nuget, apparently has a problem.
This time, instead of using these tools,i use the open-source project twittrizer from git and added as reference to the project and my problem was solved.
many Thanks to #DigitallyBorn, who had helped on this subject.
get open source twittrizer from www.twitterizer.net

access ASP.Net Session variable in Facebook C# SDK

I've my ASP.Net HTML 5 Application, Which have the image byte array in Session,
I'm using the Latest 5.X C# facebook SDK from CodePlex.
But when user is authorized and Coming back to my canvas page at that time I can't access my ASP.Net Session, its give me a null value.
Here is my Code.
CanvasAuthorizer _authorizer = new CanvasAuthorizer { Perms = "publish_stream,offline_access,manage_pages" };
if (!_authorizer.IsAuthorized())
{
_authorizer.HttpContext.Session["ImageByte"] = Session["ImageByte"];
// Go for Login,
_authorizer.HandleUnauthorizedRequest();
}
else
{
//After Login
//Here its give me a null instead of Byte Array(My Image Byte Array).
byte[] imageByte = (byte[])(_authorizer.HttpContext.Session["ImageByte"]);
var mediaObject = new FacebookMediaObject
{
FileName = "sample.png",
ContentType = "image/png"
};
mediaObject.SetValue(imageByte);
dynamic parameters = new ExpandoObject();
parameters.source = mediaObject;
parameters.uid = _authorizer.Session.UserId;
var fb = new FacebookClient(Facebook.FacebookContext.Current.AppId, Facebook.FacebookContext.Current.AppSecret);
parameters.access_token = _authorizer.Session.AccessToken;
string path = "/me/photos";
dynamic param = new ExpandoObject();
param.access_token = _authorizer.Session.AccessToken;
param.uid = _authorizer.Session.UserId;
param.source = mediaObject;
dynamic result = fb.Post(path, param);
Now pls give me some suggestion, Where I'm missing, How can I access my Application Session.
Thanks,
Jigar Shah
Try this:
protected void Page_Load(object sender, EventArgs e)
{
Response.AppendHeader("P3P", "CP=\"CAO PSA OUR\"");
if (!Page.IsPostBack)
{
}
}
I recently found that the following hidden field is required for proper functioning.
Please make shore u have it.
<input type="hidden" name="signed_request" value="<%: Request.Params["signed_request"]%>"/>
Link to my Question

Resources