Accessing Facebook C# SDK result Object using .NET 3.5 API? - dynamic

Consider the following in .NET 3.5 (using the Bin\Net35\Facebook*.dll assemblies):
using Facebook;
var app = new FacebookApp();
var result = app.Get("me");
// want to access result properties with no dynamic
... in the absence of the C# 4.0 dynamic keyword this provides only generic object members.
How best should I access the facebook properties of this result object?
Are there helper or utility methods or stronger types in the facebook C# SDK, or should I use standard .NET reflection techniques?

This code sample shows 3.5 usage, without needing the C# dynamic keyword:
// Using IDictionary<string, object> (.Net 3.5)
var client = new FacebookClient();
var me = (IDictionary<string,object>)client.Get("me");
string firstName = (string)me["first_name"];
string lastName = (string)me["last_name"];
string email = (string)me["email"];

var accesstoken = Session["AccessToken"].ToString();
var client = new FacebookClient(accesstoken);
dynamic result = client.Get("me", new { fields = "name,id,email" });
Details details = new Details();
details.Id = result.id;
details.Name = result.name;
details.Email = result.email;

You can also create a facade object around the IDictionary, as explained here.

Related

How to add HasReadLink to OData entity?

In OData when an entity had a media type, we should return along with the entity:
"odata.mediaReadLink": "Employees(1)/$value"
"odata.mediaContentType": "image/jpeg",
ref: http://docs.oasis-open.org/odata/odata-json-format/v4.0/cs01/odata-json-format-v4.0-cs01.html
I am using aspnet core and OData, but I cannot find the way to do this, well, at least not simply as I would expect this to be.
Below I show how I create the model builder, I add media type to the entity Assessment and then I try to specify the HasReadLink, but when I get an entity by Id, I do not receive back the odata media read link.
var builder = new ODataConventionModelBuilder(serviceProvider);
//This adds HasStream true in the metadata
var assessmentEntityType = builder.EntityType<Assessment>();
assessmentEntityType.MediaType();
var assessmentEntitySetConfiguration = builder.EntitySet<Assessment>(nameof(Assessment) + "s");
// Does not produce effects getting the entity by id
// UPDATE: this code below does have effect only if i set false in the second
// parameter, but anyway this has nothing to do with the media read link
assessmentEntitySetConfiguration.HasReadLink(c =>
{
return new Uri("/not-shown");
}, true);
// see NavigationSourceLinkBuilderAnnotation
// https://github.com/OData/WebApi/blob/d02bc61ea7b31ada1e54abbeebbecb3c5df0e3ac/src/Microsoft.AspNet.OData.Shared/Builder/NavigationSourceLinkBuilderAnnotation.cs
assessmentEntitySetConfiguration.EntityType
.Filter(QueryOptionSetting.Allowed, nameof(Assessment.IsDeleted))
.Filter(QueryOptionSetting.Disabled, nameof(Assessment.Description));
What am I missing?
I could not find an online example to do this in aspnet core, I found some old example to do it in net framework but it is hacky.
UPDATE 1:
In the OData for .net Framework I used SetHasDefaultStream to achieve this.
example:
var model = modelBuilder.GetEdmModel();
var answerTypeName = typeof(Answer).FullName;
var answerType = (IEdmEntityType) model.FindDeclaredType(answerTypeName);
model.SetHasDefaultStream(answerType, true);
In the new core I don't have an option to set the default stream.
I asked the same on OData.net Github project: https://github.com/OData/odata.net/issues/1555

How can i Replace the SoapFormatter Serialize and Deserialize with .net core 2.0?

I am working on migrating an old wcf project to .net core 2.0. At some places the code uses SoapFormatter class to serialize and deserialize data in Soap format.The Soap Formatter is no more supported in .net core 2.0 so i need to replace the piece of code to start using XMLSerialization. There is already some data stored in database which is serialized using SoapFormatter so i can't migrate the already stored data. Is there any way i can serialize and deserialize the already existing data with Xml Serialization without breaking it?
The piece of code using deserialization using soapformatter is:
var buffer = Convert.FromBase64String(piqBlob);
---------
public UserQuestionAnswers Deserialize(byte[] buffer)
{
using (var stream = new MemoryStream(buffer))
{
var questionsAnswers =
Serializer.Deserialize(stream) as BusinessProcesses.Authentication.UserQuestionAnswers;
if (questionsAnswers == null) return null;
var uQuestionAnswers = new UserQuestionAnswers
{
Domain = questionsAnswers.Domain,
KeyLabel = questionsAnswers.KeyLabel,
Username = questionsAnswers.Username,
UserUid = questionsAnswers.UserUid,
QuestionAnswers = (from item in questionsAnswers.QuestionAnswers
where item != null
select new QuestionAnswer
{
QuestionId = item.QuestionId,
QuestionHash = item.QuestionHash,
AnswerHmac = item.AnswerHMAC,
QuestionText = string.Empty
}).ToArray()
};
return uQuestionAnswers;
}
}
Please let me know if you need more information on this.
I am also open to any third part library if have a good rating?

Content issue in .NET Core app Consuming a WCF service

I am trying to call a WCF service method from an .NET Core Web API using the new Visual Studio WCF Connected service.
But when I am testing this, I get the following error:-
The content type multipart/related; type="application/xop+xml"; start="http://tempuri.org/0"; boundary="uuid:9e7f9b02-4d9c-4ec1-bad4-1007704a579a+id=1197"; start-info="text/xml" of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response were: '
--uuid:9e7f9b02-4d9c-4ec1-bad4-1007704a579a+id=1197
Content-ID: http://tempuri.org/0
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
The exposed WCF service uses MTOM MessageEncoding and in traditional .NET framework client application, we can set the client to use MTOM in the application's config file but in .NET core, we don't have the config file where we can set the MessageEncoding and all this configuration
is taken care of in the code present in Reference.cs(which is a generated file).
I thinking changing this generated file to set the MessageEncoding is not a good option.
Any idea on what is the best way to handle this issue?
I just came to know from WCF Core team that currently MTOM encoding is not supported in .NET Core based clients. This is a requested feature which will be available in future versions.
Here is github link which has more information: Adding MTOM support in WCF runtime
I was facing the same MTOM consumtion issue in my project, and had to find a way to be able to consume the service.
It ended up in some (ugly) code, but functional.
I just wanted to share the solution (as I wasn't able to find anything on the web) :
To start, generate the Client with Visual Studio (2017 in my case) by adding a connected service (as you would do for a regular SOAP client).
This will help you save lot a dummy code typing ;)
then, use RestSharp to call the endpoint, and serialize manually the response/request :
var client = new RestClient("http://myService/Service");
var request = new RestRequest(Method.POST);
request.AddHeader("accept", "text/plain");
request.AddHeader("content-type", "text/xml");
// create parameter
var serializer = new XmlSerializer(typeof(myParameter));
var requestParameter = new myParameter(1,2,3,4);
string requestParameterStr;
var namepsaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
var settings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true, NamespaceHandling = NamespaceHandling.OmitDuplicates }; // some parameters to make it clean, only OmitXmlDeclaration is mandatory
using (var stringWriter = new StringWriter())
{
using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
{
serializer.Serialize(xmlWriter, requestParameter, namepsaces);
requestParameterStr = stringWriter.ToString();
}
}
// patch parameter to add the namespace prefix required by consumer service
requestParameterStr = requestParameterStr.Replace("myParameter", "myNs:myParameter");
// wrap parameter in a soap envelop
requestParameterStr =
$"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:myNs=\"http://myService/Service/\"><soapenv:Header/><soapenv:Body>{requestParameterStr}</soapenv:Body></soapenv:Envelope>";
request.AddParameter(
"text/xml",
requestParameterStr,
ParameterType.RequestBody);
var response = client.Execute(request);
var mtomMsg = response.Content;
// remove MTOM elements from the received Content. here comes the ugly part ^^
var responseContentType = response.ContentType;
var contentTypeElements = responseContentType.Split(";");
var boundary = contentTypeElements.FirstOrDefault(x => x.TrimStart().StartsWith("boundary="))?.Trim().Substring("boundary=".Length);
var startElement = contentTypeElements.FirstOrDefault(x => x.TrimStart().StartsWith("start="))?.Trim().Substring("start=".Length);
boundary = boundary.Trim('"');
startElement = startElement.Trim('"');
var startIndex = mtomMsg.IndexOf(startElement) + startElement.Length;
var endIndex = mtomMsg.LastIndexOf("--" + boundary + "--", startIndex);
var cleanedMtomMsg = mtomMsg.Substring(startIndex, endIndex - startIndex);
// Get the result inside the Soap envelop
var soapDocument = XDocument.Parse(cleanedMtomMsg);
var envelopeElt = soapDocument.Root;
var bodyElt = (System.Xml.Linq.XElement)envelopeElt.FirstNode;
var responseStr = bodyElt.FirstNode.ToString();
// deserialize the result
var memstream = new MemoryStream(Encoding.UTF8.GetBytes(responseStr));
var reader = XmlDictionaryReader.CreateTextReader(memstream, XmlDictionaryReaderQuotas.Max);
var deserializer = new XmlSerializer(typeof(myResponse), "http://myService/Service/"); // don't forget the namespace
var result = deserializer.Deserialize(reader) as myResponse;
note : myParameter & myResponse are the classes generated at step 1
There could be easier ways, but at least, this works.
Hope some of you find this helpfull.
In my case, I solved this issue by using WcfCoreMtomEncoder package in my .NET Core 2.1 project. You can learn more about using it here
I fixed the problem by installing latest version of visual studio 2017. by installing latest version of visual studio it will automatically update your net core to the latest verion (1.1.2).
you can also use "binaryMessageEncodingBindingElement":
ChannelFactory<ITestService> factory = null;
ITestService serviceProxy = null;
BinaryMessageEncodingBindingElement binaryMessageEncodingBindingElement = new BinaryMessageEncodingBindingElement();
binaryMessageEncodingBindingElement.CompressionFormat = CompressionFormat.GZip;
HttpTransportBindingElement httpTransportBindingElement = new HttpTransportBindingElement();
httpTransportBindingElement.MaxReceivedMessageSize = int.MaxValue;
CustomBinding customBinding = new CustomBinding(new BindingElement[] { binaryMessageEncodingBindingElement, httpTransportBindingElement });
factory = new ChannelFactory<ITestService>(customBinding, new EndpointAddress("http://localhost/test.svc/mex"));
serviceProxy = factory.CreateChannel();
var result = serviceProxy.GetResultData(50);

Sitecore Glass mapper GetItem<TypeName>(guid) always return null

I saw a related question:
Sitecore Glass Mapper always null
But unfortunately it does not give a solution for my case.
Here goes a code snippet:
var db = Factory.GetDatabase("master");
var context = new SitecoreContext();
// the ID of Needed item
var g = new Guid("{F21C04FE-8826-41AB-9F3C-F7BDF5B35C76}");
// just to test if it's possible to fetch item using db.GetItem
var i = db.GetItem(new ID(g), Language.Current, Sitecore.Data.Version.Latest);
// Grab item
var t = context.GetItem<Article>(g);
In the code above:
i is not null
t is null
Article is the simple class like:
[SitecoreType(TemplateId = "{4C4EC1DA-EB77-4001-A7F9-E4C2F61A9BE9}")]
public class Article
{
[SitecoreField(FieldName = "Title")]
public string Title { get; set; }
}
There are only one language installed in Sitecore - en, it has been specified in the web.config in the items as well.
Also I have added GlassMapperSc.Start(); to Application_Start in the Global.asax.cs and added my assembly to the list of included assemblies via var attributes = new AttributeConfigurationLoader(new[] { "Assembly.Name" }); and I succeeded to find my class in the SitecoreContext mappings.
It does not looks like a language issue, as stated in the link provided in the very beginning. And I'm struggling with it already for a pretty long time, but no luck...
Thank You!
I just noticed that you are using master db for the Sitecore DB and SitecoreContext for Glass.
The SitecoreContext class will use the database that is defined by the Sitecore.Context.Database property at runtime. This probably means that it is using the web database.
Can you check that you have published the item to the web database or instead using:
var context = new SitecoreService("master");

How can I do a search with Google Custom Search API for .NET?

I just discovered the Google APIs Client Library for .NET, but because of lack of documentation I have a hard time to figure it out.
I am trying to do a simple test, by doing a custom search, and I have looked among other, at the following namespace:
Google.Apis.Customsearch.v1.Data.Query
I have tried to create a query object and fill out SearchTerms, but how can I fetch results from that query?
My bad, my first answer was not using the Google APIs.
As a pre-requisite, you need to get the Google API client library
(In particular, you will need to reference Google.Apis.dll in your project). Now, assuming you've got your API key and the CX, here is the same code that gets the results, but now using the actual APIs:
string apiKey = "YOUR KEY HERE";
string cx = "YOUR CX HERE";
string query = "YOUR SEARCH HERE";
Google.Apis.Customsearch.v1.CustomsearchService svc = new Google.Apis.Customsearch.v1.CustomsearchService();
svc.Key = apiKey;
Google.Apis.Customsearch.v1.CseResource.ListRequest listRequest = svc.Cse.List(query);
listRequest.Cx = cx;
Google.Apis.Customsearch.v1.Data.Search search = listRequest.Fetch();
foreach (Google.Apis.Customsearch.v1.Data.Result result in search.Items)
{
Console.WriteLine("Title: {0}", result.Title);
Console.WriteLine("Link: {0}", result.Link);
}
First of all, you need to make sure you've generated your API Key and the CX. I am assuming you've done that already, otherwise you can do it at those locations:
API Key (you need to create a new browser key)
CX (you need to create a custom search engine)
Once you have those, here is a simple console app that performs the search and dumps all the titles/links:
static void Main(string[] args)
{
WebClient webClient = new WebClient();
string apiKey = "YOUR KEY HERE";
string cx = "YOUR CX HERE";
string query = "YOUR SEARCH HERE";
string result = webClient.DownloadString(String.Format("https://www.googleapis.com/customsearch/v1?key={0}&cx={1}&q={2}&alt=json", apiKey, cx, query));
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> collection = serializer.Deserialize<Dictionary<string, object>>(result);
foreach (Dictionary<string, object> item in (IEnumerable)collection["items"])
{
Console.WriteLine("Title: {0}", item["title"]);
Console.WriteLine("Link: {0}", item["link"]);
Console.WriteLine();
}
}
As you can see, I'm using a generic JSON deserialization into a dictionary instead of being strongly-typed. This is for convenience purposes, since I don't want to create a class that implements the search results schema. With this approach, the payload is the nested set of key-value pairs. What interests you most is the items collection, which is the search result (first page, I presume). I am only accessing the "title" and "link" properties, but there are many more than you can either see from the documentation or inspect in the debugger.
look at API Reference
using code from google-api-dotnet-client
CustomsearchService svc = new CustomsearchService();
string json = File.ReadAllText("jsonfile",Encoding.UTF8);
Search googleRes = null;
ISerializer des = new NewtonsoftJsonSerializer();
googleRes = des.Deserialize<Search>(json);
or
CustomsearchService svc = new CustomsearchService();
Search googleRes = null;
ISerializer des = new NewtonsoftJsonSerializer();
using (var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
googleRes = des.Deserialize<Search>(fileStream);
}
with the stream you can also read off of webClient or HttpRequest, as you wish
Google.Apis.Customsearch.v1 Client Library
http://www.nuget.org/packages/Google.Apis.Customsearch.v1/
you may start from Getting Started with the API.