Publishing stream appears with no images - Facebook - c#

I am building a small facebook application using the Facebook developer toolkit 3.0 in c#. I had this piece of code that used to work a week ago. From some reason, when I try publishing my feed it appears without an image and without a Flash movie. Here is my code:
string userName = FacebookAPI.Users.GetInfo().name;
string message = "";
attachment attach = new attachment();
attach.href = string.Format(#"http://apps.facebook.com/{0}/?uId={1}&uName={2}", Consts.APP_NAME, ViewerUserId, userName);
attachment_media_flash flash = new attachment_media_flash();
flash.type = attachment_media_type.flash;
flash.expanded_width = 320;
flash.expanded_height = 260;
flash.height = 100;
flash.width = 130;
message = "";
attach.name = ""
attach.caption = "this works";
attach.description = ""
flash.imgsrc = string.Format(#"{0}/flash/Pinguin.JPG", Consts.DOMAIN_NAME);
flash.swfsrc = string.Format(#"{0}/flash/pinguin.swf", Consts.DOMAIN_NAME);
List<attachment_media> attach_media_list = new List<attachment_media>();
attach_media_list.Add(flash);
attach.media = attach_media_list;
/* action links */
List<action_link> actionlink = new List<action_link>();
action_link al1 = new action_link();
al1.href = string.Format(#"http://apps.facebook.com/{0}", Consts.APP_NAME);
al1.text = "myApp";
actionlink.Add(al1);
FacebookAPI.Stream.Publish(message, attach, actionlink, null , Convert.ToInt64 (ViewerUserId));

Make sure that:
1: The URL you pass is not the one that of the FB app, like http://apps.fb.co/whatever/image.jpg;
it should be your domain URL, like http://www.example.com/images/myimage.jpg.
2: You need to pass the full URL of the image including the protocol (http:// / https://), like this:
http://www.example.com/images/myimage.jpg
The following is wrong:
www.example.com/images/myimage.jpg

Related

Xamarin iOS post image to Instagram

Goal: Using an iOS native method, push a user made picture onto their Instagram feed in C#.
public bool ShareImage(byte[] imageByte)
{
bool result = false;
//string fileName = "xxx.png";
//string path = Path.Combine(FileSystem.CacheDirectory, fileName);
//File.WriteAllBytes(path, imageByte);
NSData data = NSData.FromArray(imageByte);
UIImage image = UIImage.LoadFromData(data);
//NSUrl url = NSUrl.FromString($"instagram://library?AssetPath={path}"); // Only opens
NSUrl url = NSUrl.FromString($"instagram://library?LocalIdentifier={1}");
if (UIApplication.SharedApplication.CanOpenUrl(url))
{
UIApplication.SharedApplication.OpenUrl(url);
}
return result;
}
As far as I'm aware the way I have to do this is to save my image to the device and get a Local Identifier for this.
I have constructed this from the snippets of objective-c code I have seen. Sharing photos only works with the native app installed, as I have learnt from my trials to get the facebook module working.
Edit: Using PHAssetChangeRequest from the iOS Photos namespace does not work.
A collegue has pointed out to me about the possibility of saving then using a photo picker to get the PHAsset for the Local Identifier. But this is an extra step I do not want the users of the App to go through. Better to just remove Instagram support as I just can go through the generic share method as shown below. The disadvantage of this method is that the user has then to pick the medium to share over.
public async void ShareImage(byte[] imageByte)
{
string fileName = "xxx.png";
string path = Path.Combine(FileSystem.CacheDirectory, fileName);
File.WriteAllBytes(path, imageByte);
await Share.RequestAsync(
new ShareFileRequest()
{
File = new ShareFile(path),
Title = "xxx"
}
);
}
Edit 2
Tried a different way using UIDocumentInteractionController but it is showing nothing and not posting, it is not throwing any exceptions to give me any clues as to what I'm doing wrong.
public bool ShareImage(byte[] imageByte)
{
bool result = false;
string fileName = "xxx.igo";
string path = Path.Combine(FileSystem.CacheDirectory, fileName);
File.WriteAllBytes(path, imageByte);
//string caption = "xxx";
string uti = "com.instagram.exclusivegram";
UIImageView view = new UIImageView();
//UIDocumentInteractionController controller = UIDocumentInteractionController.FromUrl(NSUrl.FromString(path));
UIDocumentInteractionController controller = new UIDocumentInteractionController
{
//controller.Url = NSUrl.FromString(path);
Url = NSUrl.FromFilename(path),
Uti = uti
};
//CoreGraphics.CGRect viewDimensions = new CoreGraphics.CGRect(0, 0, 200, 100);
_ = controller.PresentOpenInMenu(CoreGraphics.CGRect.Empty, view, true);
//_ = controller.PresentOpenInMenu(viewDimensions, view, true);
return result;
}
Edit 3
Using
UIView view = new UIImageView();
if (UIApplication.SharedApplication.KeyWindow.RootViewController is UIViewController uiController && uiController.View != null)
{
view = uiController.View;
}
I was able to get the possible share options to show. I was logged in to Instagram using the native App, but the post did not show.
Change
Url = NSUrl.FromFilename(path)
to
Url = new NSUrl(path,false)
The second way is pointing to the correct file path not the file name .
Change
controller.PresentOpenInMenu(CoreGraphics.CGRect.Empty, view, true);
to
controller.PresentOptionsMenu(UIScreen.MainScreen.Bounds, (UIApplication.SharedApplication.Delegate as AppDelegate).Window, true);
Show UIDocumentInteractionController inside current Window and set the proper frame.

C# - Check URL is valid for TemplateString

I'm currently using a TemplateString to load an image with a link, where {Url} is the file name obtained from the database.
Here is the code I use, as a reference:
Ext.Net.TemplateColumn TheColumn = new Ext.Net.TemplateColumn();
TheColumn.Text = "Image";
TheColumn.DataIndex = "Url";
TheColumn.Align = Alignment.Center;
TheColumn.Flex = 1;
TheColumn.MinWidth = 70;
TheColumn.TemplateString = "<a href='http://example.com/{Url}' data-lightbox='{Url}'><img style='width:60px;height:60px;' src='http://example.com/{Url}'/></a>";
What I would like to do is that I could check if the requested image exists, and if it doesn't, I use an alternative TemplateString instead.
Since I'm using jQuery, I´m leaving the tag in case. The project is an ASP.NET website.

Create annotation via CRM Web API

Anyone knows how to create an "annotation" using CRM Web API. I can create other objects such as account and contacts but annotation attachment is a no go. Seems like my object is missing something.
JObject notes = null;
notes = new JObject();
notes["isdocument"] = true;
notes["objecttypecode"] = "mfr_ownermlslistingwaiver";
notes["ownerid#odata.bind"] = "/systemusers(E94126AC-64FB-E211-9BED-005056920E6D)";
notes["owneridtype"] = 8;
notes["documentbody"] = "/9j/4VmjRXhpZgAASUkqAAgAAAANAAABBAABAAAAIBAAAAEBB...";
notes["minetype"] = "image/jpeg";
notes["filename"] ="2213 Scrub Jay Rd.jpg";
notes["objectid#odata.bind"] = "/mfr_ownermlslistingwaivers(137C660B-ADAA-E711-80CD-005056927DF7)";
HttpResponseMessage createResponse =
await httpClient.SendAsJsonAsync(HttpMethod.Post, "annotations", notes);
You have couple of issues in code.
1. Typo in mimetype
2. Incorrect Single valued navigation property - objectid#odata.bind and it should be objectid_[entity]#odata.bind
Necessary properties should look like below:
note["notetext"] = "Invoice Report Attached"
note["subject"] = "Invoice";
note["filename"] = "Invoice.pdf";
note["mimetype"] = "application/pdf";
note["objectid_account#odata.bind"] = "/accounts(C5DDA727-B375-E611-80C8-00155D00083F)";
note["documentbody"] = [base64String];
Reference & similar thread

Rally C#: Is it possible to create a new user story along with an attachment? (Avoiding to query for the user-story reference)

Please be patient I have already gone through the example from: How to Add an Attachment to a User Story using Rally REST .NET
However the sample code requires a query to identify the newest user story reference. The sample illustrates how to add an attachment to an existing user story. I would like to accomplish: Creating a new user story along with an attachment.
Here is my method.
public void createUsWithAttachment(string workspace, string project,
string userStoryName, string userStoryDescription){
//Authenticate with Rally
this.EnsureRallyIsAuthenticated();
//UserStory Setup
DynamicJsonObject toCreate = new DynamicJsonObject();
toCreate[RallyField.workSpace] = workspace;
toCreate[RallyField.project] = project;
toCreate[RallyField.name] = userStoryName;
toCreate[RallyField.description] = userStoryDescription;
//get the image reference - assume that this is where the image lives after being downloaded from Outlook
String imageFilePath = "C:\\Users\\secret\\...";
String imageFileName = "file.png";
String fullImageFile = imageFilePath + imageFileName;
Image myImage = Image.FromFile(fullImageFile);
// Convert Image to Base64 format
string imageBase64String = imageToBase64(myImage, System.Drawing.Imaging.ImageFormat.Png);
// Length calculated from Base64String converted back
var imageNumberBytes = Convert.FromBase64String(imageBase64String).Length;
// DynamicJSONObject for AttachmentContent
DynamicJsonObject myAttachmentContent = new DynamicJsonObject();
myAttachmentContent["Content"] = imageBase64String;
try
{
//create user story
CreateResult createUserStory = _api.Create(RallyField.hierarchicalRequirement, toCreate);
//create attachment
CreateResult myAttachmentContentCreateResult = _api.Create("AttachmentContent", myAttachmentContent);
String myAttachmentContentRef = myAttachmentContentCreateResult.Reference;
Console.WriteLine("Created: " + myAttachmentContentRef);
// DynamicJSONObject for Attachment Container
DynamicJsonObject myAttachment = new DynamicJsonObject();
//Note the below commented line
/*myAttachment["Artifact"] = ;*/
myAttachment["Content"] = myAttachmentContentRef;
myAttachment["Name"] = "AttachmentFromREST.png";
myAttachment["Description"] = "Attachment Desc";
myAttachment["ContentType"] = "image/png";
myAttachment["Size"] = imageNumberBytes;
//create attachment
CreateResult myAttachmentCreateResult = _api.Create("Attachment", myAttachment);
}
catch (WebException e)
{
Console.WriteLine(e.Message);
}
}
In the above commented line I need to get a reference to the created user story which I can do, but that would require another method to fetch the user story which I have.
However I am wondering if this can be accomplished a different way similar to how we can create a user story with the dynamicJsonObject staging.
I was thinking something like this would work, but I am having a tough time.
DynamicJsonObject toCreate = new DynamicJsonObject();
toCreate[RallyField.workSpace] = workspace;
toCreate[RallyField.project] = project;
toCreate[RallyField.name] = userStoryName;
toCreate[RallyField.description] = userStoryDescription;
toCreate["Content"] = imageToBase64;
CreateResult createUserStory = _api.Create(RallyField.hierarchicalRequirement, toCreate);
My above assumption is not going as planned and I was wondering if there is a way to create a new user story with an attachment, without having to query for the userstory reference as neatly illustrated in the example from the link provided.
Thanks and credit to the author from the example in the link.
You should already have what you need to associate it from the create result:
myAttachment["Artifact"] = createUserStory.Reference;

How to create New EPT by using CSOM

I try to create a new EPT (project server 2013) using C# CSOM library.
But It has following error occurred.
"PJClientCallableException: EnterpriseProjectTypeInvalidCreatePDPUid"
Couple of article tell to change the "IsCreate=true". But it does not success for me. Here is the code what I have done.
public void CreateEnterpriseProjectType(Guid eptGuid, string eptName, string eptDescription)
{
ProjectContext pwaContext = new ProjectContext(this.PWA_URL);
EnterpriseProjectTypeCreationInformation eptData = new EnterpriseProjectTypeCreationInformation();
eptData.Id = eptGuid;
eptData.Name = eptName;
eptData.Description = eptDescription;
eptData.IsDefault = false;
eptData.IsManaged = true;
eptData.WorkspaceTemplateName = "PROJECTSITE#0";
eptData.ProjectPlanTemplateId = Guid.Empty;
eptData.WorkflowAssociationId = Guid.Empty;
eptData.Order = 4;
List<ProjectDetailPageCreationInformation> projectDetailPages = new
List<ProjectDetailPageCreationInformation>() {
new ProjectDetailPageCreationInformation() {
Id = pwaContext.ProjectDetailPages[1].Id, IsCreate = true }
};
eptData.ProjectDetailPages = projectDetailPages;
pwaContext.Load(pwaContext.EnterpriseProjectTypes);
pwaContext.ExecuteQuery();
EnterpriseProjectType newEpt = pwaContext.EnterpriseProjectTypes.Add(eptData);
pwaContext.EnterpriseProjectTypes.Update();
pwaContext.ExecuteQuery();
}
Can anyone explain the issue or provide the working code part.
I would like to suggest the following:
Define an enterprise project type:
string basicEpt = "Enterprise Project"; // Basic enterprise project type.
int timeoutSeconds = 10; // The maximum wait time for a queue job, in seconds.
And then, when you create the new project, work like this:
ProjectCreationInformation newProj = new ProjectCreationInformation();
newProj.Id = Guid.NewGuid();
newProj.Name = "Project Name";
newProj.Description = "Test creating a project with CSOM";
newProj.Start = DateTime.Today.Date;
// Setting the EPT GUID is optional. If no EPT is specified, Project Server
// uses the default EPT.
newProj.EnterpriseProjectTypeId = GetEptUid(basicEpt);
PublishedProject newPublishedProj = projContext.Projects.Add(newProj);
QueueJob qJob = projContext.Projects.Update();
// Calling Load and ExecuteQuery for the queue job is optional.
// projContext.Load(qJob);
// projContext.ExecuteQuery();
JobState jobState = projContext.WaitForQueue(qJob, timeoutSeconds);
When the last line of that piece of code ends, the project must be created and published in order to define tasks or whatever.
I don't know what is happening to your code, seems great.
Hope it helps to you,

Categories