Self referencing loop detected using HttpClient PutAsJsonAsync Extension - asp.net-mvc-5

Using the PutAsJsonAsync extension method for HttpClient in an asp.net mvc 5 returns a Self referencing loop detected exception.
Here is the calling code:
httpClient.BaseAddress = _uri;
HttpResponseMessage response = await httpClient.PutAsJsonAsync<b>("index/1",b);
response.EnsureSuccessStatusCode();
The object b does have a self reference.
So my question is how do I set SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore in an asp.net mvc 5 application.

One way to solve this problem is to change from using the PutAsJsonAsync extension method to using the PutAsync extension method and setting the MediaTypeformatter explicitly.
var jsonformatter = new JsonMediaTypeFormatter();
jsonformatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
HttpResponseMessage response = await httpClient.PutAsync<b>("index/1",b,jsonformatter);
response.EnsureSuccessStatusCode();
This allows you to use whatever setting you need.

Related

Can not get token for TextToSpeechAPI

Here is the code:
private AccessTokenInfo GetToken()
{
WebRequest webRequest = WebRequest.Create("https://oxford-speech.cloudapp.net/token/issueToken");
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(_requestDetails);
webRequest.ContentLength = bytes.Length;
try
{
using (Stream outputStream = webRequest.GetRequestStream())
{
outputStream.Write(bytes, 0, bytes.Length);
}
// ...
I have got the exception:
the underlying connection was closed could not establish trust relationship
How can I fit it ?
I hope I'm not missing something here...
The URL you're using isn't the one that generates tokens for the Text-to-Speech API as documented here. (The "Oxford" that's referenced in your URL refers to the Project Oxford which Cognitive Services was formerly known as.)
Also, WebRequest is deprecated. Use the System.Net.Http package instead.
The code to invoke the new REST endpoint then would look something like:
using (var client = new HttpClient())
using (var request = new HttpRequestMessage(HttpMethod.Post, "https://api.cognitive.microsoft.com/sts/v1.0/issueToken"))
{
request.Headers.Add("Ocp-Apim-Subscription-Key", "YOUR-KEY-HERE");
var response = await client.SendAsync(req);
var token = await response.Content.ReadAsStringAsync();
}
Finally, there are several client libraries that may get you around from writing any code to hit the REST services at all.

Azure Schema Extensions in Graph Client

Whatever I tried I cannot set an extension property on a User object, here is a reproducible piece of code:
public async Task CleanTest(string extName)
{
ExtensionProperty ep = new ExtensionProperty
{
Name = extName,
DataType = "String",
TargetObjects = { "User" }
};
App app = (App)(await _client.Applications.Where(a => a.AppId == _managementAppClientId).ExecuteSingleAsync());
app.ExtensionProperties.Add(ep);
await app.UpdateAsync();
GraphUser user = (GraphUser)(await _client.Users.Where(u => u.UserPrincipalName.Equals("email")).ExecuteSingleAsync());
string propName = FormatExtensionPropertyName(extName); //formats properly as extesion_xxx_name
user.SetExtendedProperty(propName, "testvalue");
//user.SetExtendedProperty(extName, "testvalue");
await user.UpdateAsync(); // fails here
}
user.UpdateAsync() according to Fiddler doesn't even go out and application fails with an exception:
"The property 'extension_e206e28ff36244b19bc56c01160b9cf0_UserEEEqdbtgd3ixx2' does not exist on type 'Microsoft.Azure.ActiveDirectory.GraphClient.Internal.User'. Make sure to only use property names that are defined by the type."
This issue is also being tracked here:
https://github.com/Azure-Samples/active-directory-dotnet-graphapi-console/issues/28
I've got an alternative workaround for this bug, for those that want to use the version 5.7 OData libraries rather than redirecting to the v5.6.4 versions.
Add a request pipeline configuration handler.
// initialize in the usual way
ActiveDirectoryClient activeDirectoryClient =
AuthenticationHelper.GetActiveDirectoryClientAsApplication();
// after initialization add a handler to the request pipline configuration.
activeDirectoryClient.Context
.Configurations.RequestPipeline
.OnMessageWriterSettingsCreated(UndeclaredPropertyHandler);
In the handler, change the ODataUndeclaredPropertyBehaviorKinds value on the writer settings to SupportUndeclaredValueProperty.
private static void UndeclaredPropertyHandler(MessageWriterSettingsArgs args)
{
var field = args.Settings.GetType().GetField("settings",
BindingFlags.NonPublic | BindingFlags.Instance);
var settingsObject = field?.GetValue(args.Settings);
var settings = settingsObject as ODataMessageWriterSettings;
if (settings != null)
{
settings.UndeclaredPropertyBehaviorKinds =
ODataUndeclaredPropertyBehaviorKinds.SupportUndeclaredValueProperty;
}
}
Just in case you still looking for solution to this problem or someone else is facing the same issue:
I got similar issue and it looks like, at least for me, the problem was in latest version of "Microsoft.Data.Services.Client" package - 5.7.0 (or in one of it dependencies). When I downgraded to previous version - 5.6.4 it worked as a charm.
I had same symptoms - updating of extended property was failing even w/o any request is made (also used Fiddler)
Hope it helps!
Artem Liman

Can't Resolve a service using AppHostBase.ResolveService<T> API in ServiceStack 4

I'm using ASP.NET MVC 5 and attempting to resolve a few services using the example:
var authService = AppHostBase.Resolve<AuthService>();
authService.RequestContext = System.Web.HttpContext.Current.ToRequestContext();
var response = authService.Authenticate(new Auth
{
UserName = model.UserName,
Password = model.Password,
RememberMe = model.RememberMe
});
or I've also tried:
using (var helloService = AppHostBase.ResolveService<HelloService>())
{
ViewBag.GreetResult = helloService.Get(name).Result;
return View();
}
In the first case I needed the RequestContext injected so I tried that approach and in the second case I was using the example which I understand has the RequestContext automatically injected through Funq.
ResolveService could not be found when I tried the second approach and in the first approach RequestContext is not a valid property. Am I missing something simple or has there been changes to the API?
The documentation does appear to be wrong for this as there is no longer a ResolveService<T> on AppHostBase. It needs to be updated due to changes in the Api.
You can do this in ServiceStack v4 with MVC:
var authService = HostContext.Resolve<AuthService>();
...

ServiceStack - Switch off Snapshot

I've followed instructions on how creating a ServiceStack here at:
https://github.com/ServiceStack/ServiceStack/wiki/Create-your-first-webservice
I'm sure I have followed it to the letter, but as soon as I run the web application. I get a 'Snapshot' view of my response. I understand this happens when I don't have a default view/webpage. I set up the project as a ASP.net website, not a ASP.net MVC website. Could that be the problem?
I also wrote a test console application with the following C# code. It got the response as a HTML webpage rather than as a plain string e.g. "Hello, John".
static void sendHello()
{
string contents = "john";
string url = "http://localhost:51450/hello/";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentLength = contents.Length;
request.ContentType = "application/x-www-form-urlencoded";
// SEND TO WEBSERVICE
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(contents);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string result = string.Empty;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
Console.WriteLine(result);
}
How can I switch off the 'snapshot' view? What am I doing wrong?
The browser is requesting html so ServiceStack is returning the html snapshot.
There are a couple of ways to stop the snapshot view:
First is to use the ServiceClient classes provided by servicestack. These also have the advantage of doing automatic routing and strongly typing the response DTOs.
Next way would be to set the Accept header of the request to something like application/json or application/xml which would serialize the response into json or xml respectively. This is what the ServiceClients do internally
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Accept = "application/json";
...
Another method would be to add a query string parameter called format and set it to json or xml
string url = "http://localhost:51450/hello/?format=json";
Putting the specific format requesting is the practical way to do this
string url = "http://localhost:51450/hello/?format=json";
I suggest simply deleting this feature.
public override void Configure(Container container)
{
//...
this.Plugins.RemoveAll(p => p is ServiceStack.Formats.HtmlFormat);
//...
}
Now all requests with the Content-Type=text/html will be ignored.

HttpClient response ReadAsAsync() doesn't fully deserialize object

I'm trying to consume a web service with the Web API client library. My problem is that the ReadAsAsync doesn't seem to want to fully deserailize the returned object when the submitting function uses a POST method.
If I get the response as a string and manually deserailize it works. (I get a apmsgMessage with all the fields populated)
HttpClient client = GetClient();
var response = client.PostAsJsonAsync("api/robot/Preview", ad).Result;
var msg = response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<apmsgMessage>(msg.Result);
I originally tried the code below which returns an apmsgMessage Object, but all the fields are null.
HttpClient client = GetClient();
var response = client.PostAsJsonAsync("api/robot/Preview", ad).Result;
var msg = response.Content.ReadAsAsync<apmsgMessage>().Result;
return msg;
My question is why dosn't my orginal (the PostAsJsonAsync) return a apmsgMessage fully populated. Am I doing somethign wrong with the ReadAsAsync?
I just had the same issue, and in my case I solved it by removing the [Serializable] attribute from the class.
I don't know why this attribute conflicts with the deserialization process, but as soon as I took that out, the ReadAsAsync method worked as expected.

Resources