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
Related
I'm working on integrating Nethereum into my .NET 5 C# API and can do read queries against my chosen blockchain (BSC), but cannot get a SendTransactionAsync or SendRequestAsync to successfully execute. I'm consistently getting the following exception:
Nethereum.JsonRpc.Client.RpcResponseException: 'transaction type not supported: eth_sendRawTransaction'.
Here are code snippets of what I have tried:
// Setup
var account = new Account(privateKey, chainId);
var rpcUrl = "https://data-seed-prebsc-2-s2.binance.org:8545/";
var client = new RpcClient(new Uri(rpcUrl));
var web3 = new Web3(account, client);
var mediaTokenAddress = "0x1E4d1BFDa5d55C2176E9E3e8367BAe720525a8e0";
var mtSvc = new MediaTokenService(web3, mediaTokenAddress);
var mintMsg = new MintNftFunction
{
FromAddress = account.Address,
Recipient = "REDACTED",
MetadataHash = "TestMetaDataHash",
MediaHash = "TestMediaHash",
SeasonId = 1
};
// Attempt #1: Using C# classes generated by the Nethereum CodeGen library
var txReceipt = await mtSvc.MintNftRequestAndWaitForReceiptAsync(mintMsg);
// Attempt #2
var txHandler = web3.Eth.GetContractTransactionHandler<MintNftFunction>();
var signedTx = await txHandler.SignTransactionAsync(mediaTokenAddress, mintMsg);
var txReceipt = await web3.Eth.Transactions.SendTransaction.SendRequestAsync(signedTx);
// Attempt #3
var txInput = mintMsg.CreateTransactionInput(mediaTokenAddress);
var txReceipt = await web3.Eth.TransactionManager.SendTransactionAsync(txInput);
Is there a configuration step I'm missing? Any help is appreciated!
EDIT: I want to call a contract method that will change values within the contract, rather than sending currency. So I need help figuring out how to do that.
For those that come across this issue, I resolved it by setting the following flag on my web3 instance:
web3.TransactionManager.UseLegacyAsDefault = true;
If there is a way to do what I need without setting this flag, please feel free to leave a comment.
Here is an example of how I do this with Nethereum
var web3 = new Nethereum.Web3.Web3("YOUR_NODE_ADDRESS");
var privateKey = "someprivatekey";
var senderAddress = "0x..."; // put actual sender address
var receiveAddress = "0x..."; //put actual receiver address
var txCount = await web3.Eth.Transactions.GetTransactionCount.SendRequestAsync(senderAddress);
double sendAmount = 5.09540000; //this is ETH
var amountInWei = Web3.Convert.ToWei(sendAmount);
//600 GWEI = 0.000000600
//60 GWEI = 0.000000060
var gwei = 147; // this is 0.000000147 ETH. You will want to calculate this based on network fees
var gasPrice = Web3.Convert.ToWei(0.000000001 * gwei);
var gasLimit = Web3.Convert.ToWei(0.000000000000021);
var encoded = Web3.OfflineTransactionSigner.SignTransaction(privateKey, receiveAddress, amountInWei, txCount.Value, gasPrice, gasLimit);
//This is what prompts the transactions
Web3.OfflineTransactionSigner.GetSenderAddress(encoded).Dump();
//TX Returns from this action
var txId = await web3.Eth.Transactions.SendRawTransaction.SendRequestAsync("0x" + encoded);
//Dump out the TX if successful
txId.Dump();
I've used this many times and it has worked for me just fine.
This is pretty general, but I'm having a hell of a time figuring out how to consume some of the more complicated Sabre APIs.
I have built working .NET proxy classes in C# using the WSDL for the basic APIs (CreateSession, CloseSession) but for the more complicated APIs I have a really hard time parsing out the complicated XML schema to figure out which methods to call in my program.
Are there any other .NET resources/examples out there that aren't wrapped up in MVC like the code example that Sabre posted on GitHub?
I'm trying to figure out how to use APIs like OTA_AirPriceLLSRQ and TravelItineraryReadRQ.
Thanks in advance for any help!
As I mentioned on the comments, you should not focus on the actual MVC wrapping, as you'll be mainly putting stuff in the Model, or actually you'll put this somewhere else and consume it in the model.
Anyway, just for you to have as example, here's a VERY generic BFM (BargianFinderMax) class. With this approach it's required to create an instance, and after calling the Execute method it stores the response in the instance.
I hope it helps.
using BargainFinderMaxRQv310Srvc;
using System;
using System.IO;
namespace ServicesMethods
{
public class BFM_v310
{
private BargainFinderMaxService service;
private OTA_AirLowFareSearchRQ request;
public OTA_AirLowFareSearchRS response;
public BFM_v310(string token, string pcc, string convId, string endpoint)
{
//MessageHeader
MessageHeader mHeader = new MessageHeader();
PartyId[] pId = { new PartyId() };
pId[0].Value = "SWS";
From from = new From();
from.PartyId = pId;
To to = new To();
to.PartyId = pId;
mHeader.Action = "BargainFinderMaxRQ";
mHeader.Service = new Service()
{
Value = mHeader.Action
};
mHeader.ConversationId = convId;
mHeader.CPAId = pcc;
mHeader.From = from;
mHeader.To = to;
mHeader.MessageData = new MessageData()
{
Timestamp = DateTime.UtcNow.ToString()
};
//Security
Security security = new Security();
security.BinarySecurityToken = token;
//Service
service = new BargainFinderMaxService();
service.MessageHeaderValue = mHeader;
service.SecurityValue = security;
service.SoapVersion = System.Web.Services.Protocols.SoapProtocolVersion.Soap11;
service.Url = endpoint;
createRequest(pcc);
}
private void createRequest(string pcc)
{
request = new BargainFinderMaxRQv310Srvc.OTA_AirLowFareSearchRQ();
request.AvailableFlightsOnly = true;
request.Version = "3.1.0";
request.POS = new SourceType[1];
SourceType source = new SourceType();
source.PseudoCityCode = pcc;
source.RequestorID = new UniqueID_Type();
source.RequestorID.ID = "1";
source.RequestorID.Type = "1";
source.RequestorID.CompanyName = new CompanyNameType();
source.RequestorID.CompanyName.Code = "TN";
source.RequestorID.CompanyName.CodeContext = "Context";
request.POS[0] = source;
OTA_AirLowFareSearchRQOriginDestinationInformation originDestination = new OTA_AirLowFareSearchRQOriginDestinationInformation();
originDestination.OriginLocation = new OriginDestinationInformationTypeOriginLocation();
originDestination.OriginLocation.LocationCode = "BCN";
originDestination.DestinationLocation = new OriginDestinationInformationTypeDestinationLocation();
originDestination.DestinationLocation.LocationCode = "MAD";
originDestination.ItemElementName = ItemChoiceType.DepartureDateTime;
originDestination.Item = "2017-09-10T12:00:00";
originDestination.RPH = "1";
request.OriginDestinationInformation = new OTA_AirLowFareSearchRQOriginDestinationInformation[1] { originDestination };
request.TravelerInfoSummary = new TravelerInfoSummaryType()
{
AirTravelerAvail = new TravelerInformationType[1]
};
request.TravelerInfoSummary.AirTravelerAvail[0] = new TravelerInformationType()
{
PassengerTypeQuantity = new PassengerTypeQuantityType[1]
};
PassengerTypeQuantityType passenger = new PassengerTypeQuantityType()
{
Quantity = "1",
Code = "ADT"
};
request.TravelerInfoSummary.AirTravelerAvail[0].PassengerTypeQuantity[0] = passenger;
request.TravelerInfoSummary.PriceRequestInformation = new PriceRequestInformationType();
request.TravelerInfoSummary.PriceRequestInformation.CurrencyCode = "USD";
//PriceRequestInformationTypeNegotiatedFareCode nego = new PriceRequestInformationTypeNegotiatedFareCode();
//nego.Code = "ABC";
//request.TravelerInfoSummary.PriceRequestInformation.Items = new object[1] { nego };
request.TPA_Extensions = new OTA_AirLowFareSearchRQTPA_Extensions();
request.TPA_Extensions.IntelliSellTransaction = new TransactionType();
request.TPA_Extensions.IntelliSellTransaction.RequestType = new TransactionTypeRequestType();
request.TPA_Extensions.IntelliSellTransaction.RequestType.Name = "50ITIN";
}
public bool Execute()
{
response = service.BargainFinderMaxRQ(request);
return response.PricedItinCount > 0;
}
}
}
My advice is you should add separate models which are built based on Sabre models, and which flatten the whole structure.
For example, TravelItineraryReadRS is a quite complicated document. Using it properties in your program is a real "pain", because every time you need to remember the whole path that leads to to specific information (like, "what is passenger type for PersonName of NameNumber 01.01?").
I suggest you have dedicated model (let's name it Reservation), which have all information that you will need later in your application, extracted from TravelItineraryReadRs.
In order to achieve this you need a dedicated converter which will make convert TravelItineraryReadRs model into Reservation model. Now, inside Reservation model you could have list of Passenger models, which have in on place all important information (NameNumber, PassengerType, SSR codes, etc).
This improves readability and as a bonus you decouple your application from Sabre (imagine, one day someone asks "can we switch from Sabre to Amadeus?" - if you use dedicated models the answer is "yes". If you don't have, then the answer is "probably yes, but it will take 6-9 months).
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;
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,
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