I have this code:
public void Put(int id, DistributionRuleModelListItem model)
{
CommonResultModel pre = new BLL.DistributionRules().Save(id, model, true);
if(!pre.success){
DAL.DBManager.DestroyContext();
var resp = new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(string.Format("Internal server error for distruleId: {0}", id)),
ReasonPhrase = pre.message.Replace(Environment.NewLine, " ")//.Substring(0,400)
};
throw new HttpResponseException(resp);
}
}
There is logic that can set the value of pre.message to be an exception.ToString() and if it is too long i receive the following application exception:
Specified argument was out of the range of valid values. Parameter
name: value
But if I uncomment .Substring(0,400) everything works fine and on client side I receive the correct response and it is possible to show it to the user.
What is the max length of ReasonPhrase? I can't find any documentation that specifies this value.
I couldn't find the max value documented anywhere, however through trial and error, I found it to have a maximum length of 512 bytes.
Related
I have the goal of being able to programmatically update OneNote page data using C#. The Microsoft Graph API reference documentation suggests this can only be done by page element, not by page, and gives the following C# Graph SDK example:
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var stream = new System.IO.MemoryStream(Encoding.UTF8.GetBytes(#"[
{
'target':'#para-id',
'action':'insert',
'position':'before',
'content':'<img src=""image-url-or-part-name"" alt=""image-alt-text"" />'
},
{
'target':'#list-id',
'action':'append',
'content':'<li>new-page-content</li>'
}
]
"));
var pages = new OnenotePage();
pages.Content = stream;
await graphClient.Me.Onenote.Pages["{onenotePage-id}"]
.Request()
.UpdateAsync(pages);
Below is the relevant snippet of my code:
GraphServiceClient client; // authenticated service client
CancellationToken cancellationToken; // a cancellation token
string userId; // identifier of user whose page contains the paragraph to be updated
string pageId; // identifier of page containing paragraph to be updated
string paragraphId; // identifier of paragraph to be updated
string filePath; // location of text file containing updated paragraph data
await client.Users[userId].Onenote.Pages[pageId]
.Request()
.UpdateAsync(new OnenotePage
{
Content = new MemoryStream(Encoding.UTF8.GetBytes(
// [
// {
// 'target':'{paragraphId}',
// 'action':'replace',
// 'content':'<p>{File.ReadAllText(filePath)}</p>'
// }
// ]
$"[{{'target':'{paragraphId}','action':'replace','content':'<p>{File.ReadAllText(filePath)}</p>'}}]"))
}, cancellationToken);
Microsoft's REST documentation includes PATCH /users/{id | userPrincipalName}/onenote/pages/{id}/content as a valid HTTP request, so my above code seems like it should work, even though it doesn't use the .Me option as in their example. For some reason, however, my code keeps throwing an InvalidOperationException, declaring that, "Timeouts are not supported on this stream," whenever it tries to execute the await command. Below are the details of the exception:
System.InvalidOperationException
HResult=0x80131509
Message=Timeouts are not supported on this stream.
Source=System.Private.CoreLib
StackTrace:
at System.IO.Stream.get_ReadTimeout()
When I try to run the raw REST command on the official Graph Explorer, I get a No Content - 204 message, confirming that the PATCH worked. Please note again, however, that I am instead simply using the C# MS Graph SDK.
Where am I going wrong? How can I accomplish my goal?
EDIT: I still don't have a solution to the SDK throwing InvalidOperationExceptions at me, and thus do not consider this matter resolved, but since the API seems to be working just fine, I went ahead and found a workaround to accomplish my goal. Posted here, in case anyone else encounters my same issue and needs something that works.
GraphServiceClient client; // authenticated service client
CancellationToken cancellationToken; // a cancellation token
string userId; // identifier of user whose page contains the paragraph to be updated
string pageId; // identifier of page containing paragraph to be updated
string paragraphId; // identifier of paragraph to be updated
string filePath; // location of text file containing updated paragraph data
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Patch,
client.Users[userId].Onenote.Pages[pageId].Content
.Request()
.RequestUrl)
{
Content = new StringContent(
// [
// {
// 'target':'{paragraphId}',
// 'action':'replace',
// 'content':'<p>{File.ReadAllText(filePath)}</p>'
// }
// ]
$"[{{'target':'{paragraphId}','action':'replace','content':'<p>{File.ReadAllText(filePath)}</p>'}}]",
Encoding.UTF8,
"application/json")
};
await client.AuthenticationProvider.AuthenticateRequestAsync(request);
await client.HttpProvider.SendAsync(request);
I am trying to use the following code, but am getting "Message: The audience claim value is invalid for current resource. Audience claim is 'https://graph.microsoft.com', request url is 'https://outlook.office.com/api/beta/Users..."
I get it on the provider.GetUploadChunkRequests(); call below:
AttachmentItem attachmentItem= new AttachmentItem
{
Name = [Name],
AttachmentType = AttachmentType.File,
Size = [Size]
};
var session = graphClient.Users[USEREMAIL].Messages[MESSAGEID].Attachments.CreateUploadSession(attachmentItem).Request().PostAsync().Result;
var stream = new MemoryStream(BYTEARRAY);
var maxSizeChunk = DEFAULT_CHUNK_SIZE;
var provider = new ChunkedUploadProvider(session, graphClient, stream, maxSizeChunk);
var chunkRequests = provider.GetUploadChunkRequests();
(I am using the graphClient to send emails successfully, and have also used it to upload large files using the uploadSession method)
From Andrue Eastman on GitHub:
You are most likely getting the error because of using the ChunkedUploadPorvider instead of using the FileUploadTask to upload the attachment which is setting the Auth header to cause the error you are receiving.
To use the file upload task, follow the following steps
First create an upload session and handing it over to the task as illustrated.
// Create task
var maxSliceSize = 320 * 1024; // 320 KB - Change this to your chunk size. 4MB is the default.
LargeFileUploadTask<FileAttachment> largeFileUploadTask = new LargeFileUploadTask<FileAttachment>(uploadSession, stream, maxSliceSize);
Create an upload monitor (optional)
// Setup the progress monitoring
IProgress<long> progress = new Progress<long>(progress =>
{
Console.WriteLine($"Uploaded {progress} bytes of {stream.Length} bytes");
});
The service only returns location URI which can be read off from the result object as follows.
UploadResult<FileAttachment> uploadResult = null;
try
{
uploadResult = await largeFileUploadTask.UploadAsync(progress);
if (uploadResult.UploadSucceeded)
{
Console.WriteLine(uploadResult.Location);//the location of the object
}
}
catch (ServiceException e)
{
Console.WriteLine(e.Message);
}
I need to read following elasticksearch metrics
Version
Up-time
No. of Jobs
Overall Health
No. of Nodes
Disk Available in %
JVM Heap Size
No. of Indices
Primary Shards
Replica Shards
in ASP.Net MVC application. My question :-
Is it possible to read all above metrics with one API call in elasticsearch?
I have written following method
private static string CheckESHealth()
{
string esurl = "http://localhost:9200/_cluster/health";
HttpClient httpClient = new HttpClient();
string strReturnVal = string.Empty;
try
{
var response = httpClient.GetAsync(new Uri(esurl)).Result;
if (response.IsSuccessStatusCode)
{
var esdata = response.Content.ReadAsStringAsync().Result;
if (!string.IsNullOrEmpty(esdata))
{
JObject jobject = JObject.Parse(esdata);
//as a example i have taken only status.. but i need all paramters mention above
strReturnVal = jobject["status"].ToString();
}
}
else
{
strReturnVal = "Errored : Received status code : " + response.StatusCode;
}
}
catch (Exception ex)
{
strReturnVal = "Errored : " + ex.Message;
}
return strReturnVal;
}
in above example i am using :- GET _cluster/health command which give following result
enter image description here
but i am trying to read all above metrics in one API call
I didn't find a way to read above[in question] mentioned metrics in one query. so, i used following queries to get metrics.
http://localhost:9200/_cat/health?h=cluster,status,node.total,shards,pri,relo&format=json
http://localhost:9200/_cat/nodes?h=version,uptime,heap.percent&format=json
http://localhost:9200/_cat/allocation?h=disk.percent&format=json
I am trying to pull some statistics for a TaskQueue using the TaskRouter.js SDK. For this I need to generate a capability router token, which allows access to the TaskQueue. According to the sample at twilio docs, I am supposed to pass null as the channel parameter(look in C# .Net sample), to generate the TaskRouterCapability token. But when I do this, I get an exception (object is null in get_Claims).
Looking at the source code, I should pass in the TaskQueue Sid as the channel id instead of null. When I did this a token was correctly generated.
To start off, am using the basic token generation example code at twilio docs :
class Program {
static void Main(string[] args)
{
// Find your Account Sid and Auth Token at twilio.com/console
const string accountSid = "ACbe0c12d747XXXXXXXXXXXXXXXXXb";
const string authToken = "your_auth_token";
const string workspaceSid = "WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const string taskQueueSid = "WQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var urls = new PolicyUrlUtils(workspaceSid, taskQueueSid);
var allowFetchSubresources = new Policy($"{urls.TaskQueue}/**",
HttpMethod.Get);
var allowUpdates = new Policy(urls.TaskQueue, HttpMethod.Post);
var policies = new List<Policy>
{
allowFetchSubresources,
allowUpdates
};
// By default, tokens are good for one hour.
// Override this default timeout by specifiying a new value (in seconds).
// For example, to generate a token good for 8 hours:
var capability = new TaskRouterCapability(
accountSid,
authToken,
workspaceSid,
null,
policies: policies,
expiration: DateTime.UtcNow.AddSeconds(28800) // 60 * 60 * 8
);
Console.WriteLine(capability.ToJwt());
} }
class PolicyUrlUtils {
const string taskRouterBaseUrl = "https://taskrouter.twilio.com";
const string taskRouterVersion = "v1";
readonly string _workspaceSid;
readonly string _taskQueueSid;
public PolicyUrlUtils(string workspaceSid, string taskQueueSid)
{
_workspaceSid = workspaceSid;
_taskQueueSid = taskQueueSid;
}
public string TaskQueue => $"{Workspace}/TaskQueue/{_taskQueueSid}";
string Workspace =>
$"{taskRouterBaseUrl}/{taskRouterVersion}/Workspaces/{_workspaceSid}";
}
This gives me an exception on the last line(capability.ToJwt()). Exception is:
System.NullReferenceException occurred
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=<Cannot evaluate the exception source>
StackTrace:
at Twilio.Jwt.Taskrouter.TaskRouterCapability.get_Claims()
at Twilio.Jwt.BaseJwt.ToJwt()
at DeleteMe.Program.Main(String[] args) in D:\Projects\DeleteMe\DeleteMe\Program.cs:line 46
Now, I looked at the source code of TaskRouterCapability at twilio-csharp github, and seems to be the queue sid should be passed as the channel parameter. When I do this, the token is created. So I took the token generated here, and put it into this HTML file:
<html>
<head>
<script type="text/javascript" src="https://media.twiliocdn.com/taskrouter/js/v1.11/taskrouter.min.js"></script>
<script type="text/javascript">
var taskQueue = new Twilio.TaskRouter.TaskQueue("token generated by console application");
taskQueue.on("ready", function (taskQueue) {
console.log(taskQueue.sid) // 'WQxxx'
console.log(taskQueue.friendlyName) // 'Simple FIFO Queue'
console.log(taskQueue.targetWorkers) // '1==1'
console.log(taskQueue.maxReservedWorkers) // 20
});
</script>
</head>
<body>
</body>
This then gives me some messages in the console:
taskrouter.min.js:1 Websocket opened: wss://event-bridge.twilio.com/v1/wschannels/ACxxxxxxxxxxxxxx/WQxxxxxxxx?token=eyJh.....&closeExistingSessions=false
taskrouter.min.js:1 Received a message of type [connected]
taskrouter.min.js:1 POST https://event-bridge.twilio.com/v1/wschannels/ACxxxxxxxxx/WQxxxxxxxxxxx 403 (Policies defined such that we cannot access the given resource)
So the connected event is called, but the ready event never happens.
Turns out there are 2 errors in the sample:
The channel parameter of TaskRouterCapability constructor should be passed the TaskQueue Sid rather than null. A value of null causes an Exception
System.NullReferenceException occurred HResult=0x80004003 Message=Object reference not set to an instance of an object. Source= StackTrace: at Twilio.Jwt.Taskrouter.TaskRouterCapability.get_Claims() at Twilio.Jwt.BaseJwt.ToJwt()
There is a typo in the TaskQueue property of PolicyUrlUtils. The URL should have TaskQueues instead of TaskQueue
Have submitted a pull request for the same https://github.com/TwilioDevEd/api-snippets/pull/539
I am making a web-application in ASP.NET. I have used oauth to get profile fields of a user. I need the names of the companies followed by the user, but the problem is that the default value is set to 20. so, if the user is following more than 20 companies i am not able to get it. Please tell me how can i modify the start and count values. Iv used this url to make the call http://api.linkedin.com/v1/people/~:(following:(people,companies,industries,news-sources),educations).. Please help asap..
var requestHeader = GetUserProfileAuthorizationHeader();
var queryString = CreateQueryString();
var request = WebRequest.Create(RequestProfileUrl + queryString);
request.Headers.Add("Authorization", requestHeader.ToString());
request.Method = HttpMethod.Get;
try
{
var response = request.GetResponse();
using (var responseStream = response.GetResponseStream())
{
var reader = new StreamReader(responseStream);
var responseText = reader.ReadToEnd();
reader.Close();
return responseText;
}
}
Here public static string RequestProfileUrl = "http://api.linkedin.com/v1/people/~:(following:(companies:(id,name,size,industry),industries))"; And the method CreateQueryString() does this queryString = "?format=xml"; whenever i try to add something like queryString = "?format=xml&start=0&count=40"; it gives error dispite the number of companies followed being more than 60.. maybe i need to pass the query parameters in between the RequestProfileUrl i.e near the company somehow..
Did you tried adding ?start=x&count=y to the url?
Probably if you're getting an error when you add query parameters to the URL, you're not adding those parameters in the way that your OAuth library expects them to be added. You need to figure out how to add the parameters so they're added to the signature generation process or your signature will be invalid and you'll get a 401 error back from the server.