FileStreamResult in ASP.NET core of a large file ( > 2 GB) results in System.IO.IOException: Stream was too long - asp.net-core

I am trying to send a large file using FileStreamResult -
return new UnbufferedFileStreamResult(new FileStream(apiResponse.url, FileMode.Open, FileAccess.Read), "text/csv") { FileDownloadName = new FileInfo(apiResponse.url).Name };
The UnbufferedFileStreamResult is:
public class UnbufferedFileStreamResult : FileStreamResult {
public UnbufferedFileStreamResult(Stream fileStream, string contentType) : base(fileStream, contentType) {
}
public override void ExecuteResult(ActionContext context) {
context.HttpContext.DisableOutputBuffering();
base.ExecuteResult(context);
}
}
This seems to work for files up to a certain size, but if they get too big I get the following exception:
System.IO.IOException: Stream was too long.
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.MemoryStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Http.Extensions.StreamCopyOperation.CopyToAsync(Stream source, Stream destination, Nullable`1 count, Int32 bufferSize, CancellationToken cancel)
at Microsoft.AspNetCore.Mvc.Infrastructure.FileResultExecutorBase.WriteFileAsync(HttpContext context, Stream fileStream, RangeItemHeaderValue range, Int64 rangeLength)
at Microsoft.AspNetCore.Mvc.Infrastructure.FileStreamResultExecutor.ExecuteAsync(ActionContext context, FileStreamResult result)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, O
So it appears that FileStreamResultExecutorBase is copying my file stream into a memory stream before it goes to the http output stream. My questions are 1) why is it doing this, 2) how can I prevent this behavior, and 3) are there implementations of results like FileStreamResult that can read directly from the input stream to the output stream without copying to memory first?

Related

Flutter web: How to upload Image to ASP .NET Core web API?

I have an API which is for a CMS that can change my entire 'AboutUs' web page. The following was the Data Model that holds all the contents of that 'About Us' webpage.
I have a Future method that goes this way to update the 'About Us' webpage contents within database only. (via ASP.Net Core web API)
Future updateAboutUsContent() async
Future<AboutUsContextModel> updateAboutUsContent(
String title,
String context,
String subcontext,
PlatformFile imageId,
) async {
final abUC =
await http.put(Uri.parse(urlAddress + "/api/AboutUsContextModels/2"),
headers: <String, String>{
"Content-Type": "multipart/form-data;charset=UTF-8",
},
body: jsonEncode(<String, dynamic>{
"title": title,
"context": context,
"subContext": subcontext
}));
final request = http.MultipartRequest(
"POST", Uri.parse(urlAddress + "/api/AboutUsContextModels/2"));
request.files.add(http.MultipartFile(
"imageFile",
imageId.readStream,
imageId.size,
filename: imageId.name.split("/").last);
var resp = await request.send();
String response = await resp.stream.bytesToString();
print("==================\nThis is the response:\n=================" +
response);
}
if (abUC.statusCode == 200) {
//If the server did return a 200 Created All green post
//then parse the JSON
return AboutUsContextModel.fromJson(jsonDecode(abUC.body));
} else if (abUC.statusCode == 400) {
throw Exception('Error code was 400. About Us Content Not Foun');
} else {
throw Exception('Nothing About Us Content created in Flutter');
}
}
And This Future will call the ASP web API which is as below:
[HttpPut("{id}")]
public async Task<ActionResult<AboutUsContextModel>> PutAboutUsContent(int id, string title, string context, string subcontext, IFormFile imageFile)
{
AboutUsContextModel abUC = await _context.AboutUsContextModel.Include(lim => lim.Image).FirstOrDefaultAsync(limy => limy.AboutUs_Context_Id == id);
if(abUC == null)
{
return BadRequest("No such About Us Content!");
}
if(imageFile != null)
{
ImageModel imgfrmDB = abUC.Image;
if(imgfrmDB != null)
{
string cloudDomaim = "https://privacy-web.conveyor.cloud";
string uploadDrcty = _webEnvr.WebRootPath + "\\Images\\";
if (!Directory.Exists(uploadDrcty))
{
Directory.CreateDirectory(uploadDrcty);
}
string filePath = uploadDrcty + imageFile.FileName;
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await imageFile.CopyToAsync(fileStream);
await fileStream.FlushAsync();
}
using (var memoryStream = new MemoryStream())
{
await imageFile.CopyToAsync(memoryStream);
imgfrmDB.Image_Byte = memoryStream.ToArray();
}
imgfrmDB.ImagePath = cloudDomaim + "/Images/" + imageFile.FileName;
imgfrmDB.Modify_By = "CMS Admin";
imgfrmDB.Modity_dt = DateTime.Now;
}
}
abUC.Title = title;
abUC.Context = context;
abUC.SubContext = subcontext;
abUC.Modify_By = "CMS Admin";
abUC.Modity_dt = DateTime.Now;
_context.Entry(abUC).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!AboutUsContextModelExists(abUC.AboutUs_Context_Id))
{
return NotFound();
}
else
{
throw;
}
}
return Ok("About Us Content Delivered, Edit Successful");
}
Unfortunately when I run the code, the following errors only shows:
TypeError: Cannot read properties of null (reading 'listen')
at byte_stream.ByteStream.new.listen (http://localhost:60452/dart_sdk.js:36349:31)
at _StreamControllerAddStreamState.new._AddStreamState.new (http://localhost:60452/dart_sdk.js:37160:37)
at new _StreamControllerAddStreamState.new (http://localhost:60452/dart_sdk.js:37191:53)
at _AsyncStreamController.new.addStream (http://localhost:60452/dart_sdk.js:36687:24)
at _AsyncStarImpl.new.addStream (http://localhost:60452/dart_sdk.js:33462:46)
at multipart_request.MultipartRequest.new._finalize (http://localhost:60452/packages/http/src/multipart_request.dart.lib.js:352:22)
at _finalize.next (<anonymous>)
at _AsyncStarImpl.new.runBody (http://localhost:60452/dart_sdk.js:33416:40)
at Object._microtaskLoop (http://localhost:60452/dart_sdk.js:40808:13)
at _startMicrotaskLoop (http://localhost:60452/dart_sdk.js:40814:13)
at http://localhost:60452/dart_sdk.js:36279:9
I used breakpoints to examine each of the lines to track where is the null (in the Flutter's updateAboutUsContent() Future), which this line
final abUC =
await http.put(Uri.parse(urlAddress + "/api/AboutUsContextModels/2"),
headers: <String, String>{
"Content-Type": "multipart/form-data;charset=UTF-8",
},
body: jsonEncode(<String, dynamic>{
"title": title,
"context": context,
"subContext": subcontext,
// 'imageFile': imageId
}));
and this line,
final request = http.MultipartRequest(
"POST", Uri.parse(urlAddress + "/api/AboutUsContextModels/2"));
The 'PlatformFile imageFile' receives the imageFile. It shows the filename, bytes,... all those in the VS Code 'Run and Debug'.
The 'PlatformFile imageFile' still gets the image file, but until this line
request.files.add(http.MultipartFile(
"imageFile",
imageId.readStream,
imageId.size,
filename: imageId.name.split("/").last);
it still execute this line but after that the aforementioned TypeError shows.
It seems that, MAYBE
http.MultipartFile(
"imageFile",
imageId.readStream,
imageId.size,
filename: imageId.name.split("/").last)
↑↑something here was wrong.↑↑
Referring to the first two codes I pasted at first, i.e. updateAboutUsContent(), and PutAboutUsContent() located in the Web API, Can I know
Where did I done wrong?
How can I correct my 'updateAboutUsContent()' method, so that it can connect and 'PUT' data to the 'PutAboutUsContent()' in the .Net Core web API?
How can I convert Flutter's 'PlatformFile' to ASP's 'IFormFile' so that it binds to the corresponding argument that accepts the imageFile?
I'm very new to Flutter web, ASP.NET Core 5.0 web API, and really don't have any idea/concepts about how to upload images to the ASP.NET from flutter web, so something in my updateAboutUsContent() in the Flutter may wrote wrong.
I have tested the PutAboutUsContent() situated in the Web API using Swagger UI, nothing there was wrong, and I was prohibited to change the codes there, I just can use it.
So, I plead. Is there someone could lend a hand, please?
UPDATE
Now the Future updateAboutUsContent() async is changed to this:
Future<AboutUsContextModel> putAboutUsContent(
String title,
String context,
String subcontext,
PlatformFile imageId,
) async {
final abUC =
await http.put(Uri.parse(urlAddress + "/api/AboutUsContextModels/2"),
headers: <String, String>{
"Content-Type": "multipart/form-data;charset=UTF-8",
},
body: jsonEncode(<String, dynamic>{
"title": title,
"context": context,
"subContext": subcontext,
// 'imageFile': imageId
}));
final request = http.MultipartRequest(
"PUT", Uri.parse(urlAddress + "/api/AboutUsContextModels/2"));
var fileadded =
new http.MultipartFile("imageFile",
imageId.readStream,
imageId.size,
filename: imageId.name);
if (fileadded != null) {
request.headers
.addAll(<String, String>{"Content-Type": "multipart/form-data"});
request.files.add(fileadded);
var resp = await request.send();
String response = await resp.stream.bytesToString();
print("==================\nThis is the response:\n=================" +
response);
}
if (abUC.statusCode == 200) {
//If the server did return a 200 Created All green post
//then parse the JSON
return AboutUsContextModel.fromJson(jsonDecode(abUC.body));
} else if (abUC.statusCode == 400) {
throw Exception('Error code was 400. About Us Content Not Foun');
} else {
throw Exception('Nothing About Us Content created in Flutter');
}
}
And the Future method can properly go until to the if(statusCode ==??) there, however, it still returns 400.
Now, the console appears:
==================
This is the response:
=================Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
---> Npgsql.PostgresException (0x80004005): 23502: null value in column "Title" of relation "AboutUs_Context" violates not-null constraint
at Npgsql.NpgsqlConnector.<ReadMessage>g__ReadMessageLong|194_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
Exception data:
Severity: ERROR
SqlState: 23502
MessageText: null value in column "Title" of relation "AboutUs_Context" violates not-null constraint
Detail: Detail redacted as it may contain sensitive data. Specify 'Include Error Detail' in the connection string to include this information.
SchemaName: WebContext
TableName: AboutUs_Context
ColumnName: Title
File: d:\pginstaller_13.auto\postgres.windows-x64\src\backend\executor\execmain.c
Line: 1953
Routine: ExecConstraints
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(DbContext _, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Privacy_Web.Controllers.AboutUsContextModelsController.PutAboutUsContent(Int32 id, String title, String context, String subcontext, IFormFile imageFile) in D:\distributor_dashboard_v2\Privacy_Web\privacy_web_backend\Privacy_Web\Controllers\AboutUsContextModelsController.cs:line 224
at lambda_method299(Closure , Object )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
HEADERS
=======
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: close
Content-Length: 263429
Content-Type: multipart/form-data; boundary=dart-http-boundary-zMVNRV2ehRqP4TYkdPpFn.dOrsckK2tfoxBV_s6z5coua9ye0+m
Host: localhost:44395
Referer: http://localhost:63925/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
origin: http://localhost:63925
sec-fetch-site: cross-site
sec-fetch-mode: cors
sec-fetch-dest: empty
x-server-sni: haproxy.privacy-web-kb5.conveyor.cloud
x-forwarded-for: (***IP address here, censored to be seen***)
When the first two lines of the updateAboutUsContent() method was executed, ie.
final abUC =
await http.put(Uri.parse(urlAddress + "/api/AboutUsContextModels/2"),
headers: <String, String>{
"Content-Type": "multipart/form-data;charset=UTF-8",
},
body: jsonEncode(<String, dynamic>{
"title": title,
"context": context,
"subContext": subcontext,
// 'imageFile': imageId
}));
final request = http.MultipartRequest(
"PUT", Uri.parse(urlAddress + "/api/AboutUsContextModels/2"));
The following shows:
where the readStream returns: Instance of '_ControllerStream<List>'.
So I think this was the reason statusCode 400 was returned.
So, how should I solve it? Or if I wrongly identified the issue causing the error, then where can I improved?
You have to send one request with all data.
Something like this:
Future<AboutUsContextModel> putAboutUsContent(
String title,
String context,
String subcontext,
PlatformFile imageId,
) async {
var request = http.MultipartRequest("PUT", Uri.parse(urlAddress + "/api/AboutUsContextModels/2"));
request.fields['title'] = title;
request.fields['context'] = context;
request.fields['subContext'] = subContext;
request.files.add(http.MultipartFile(
'imageFile',
imageId.readStream,
imageId.size,
filename: imageId.name,
));
final resp = await request.send();
if (resp.statusCode == 200) {
//If the server did return a 200 Created All green post
//then parse the JSON
return AboutUsContextModel.fromJson(jsonDecode(resp.body));
} else if (resp.statusCode == 400) {
throw Exception('Error code was 400. About Us Content Not Foun');
} else {
throw Exception('Nothing About Us Content created in Flutter');
}
}
Also, check this answer .

System.ObjectDisposedException: Cannot access a disposed object asp.net-core-webapi

I am using asp.net-core-webapi and I am also using iTextSharp to create pdf in memory steam.
[Route("preview/{Id}")]
[System.Web.Http.HttpGet]
public async Task<IActionResult> PreviewSpecSheet(int Id)
{
FileStreamResult fsr;
Document document = new Document(PageSize.A4, 25, 25, 30, 30);
using (MemoryStream ms = new MemoryStream())
{
using (PdfWriter writer = PdfWriter.GetInstance(document, ms))
{
//PdfWriter writer = PdfWriter.GetInstance(document, ms);
document.Open();
//header Image
iTextSharp.text.Image headerImg = iTextSharp.text.Image.GetInstance("D:\\go2\\Pixelle\\specsheet\\pixservice\\assets\\header.jpg");
headerImg.SetAbsolutePosition(0, 750);
headerImg.ScaleAbsolute(500f, 100.00f);
document.Add(headerImg);
fsr = File(ms, "application/pdf", "test.pdf");
return fsr;
}
}
}
I am getting following error :
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Cannot access a closed file.'.
at System.IO.FileStream.BeginRead(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback callback, Object state)
at System.IO.Stream.<>c.<BeginEndReadAsync>b__48_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, Object state)
at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMethod, Func`3 endMethod)
at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.FileStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.StreamCopyOperationInternal.CopyToAsync(Stream source, Stream destination, Nullable`1 count, Int32 bufferSize, CancellationToken cancel)
at Microsoft.AspNetCore.Mvc.Infrastructure.FileResultExecutorBase.WriteFileAsync(HttpContext context, Stream fileStream, RangeItemHeaderValue range, Int64 rangeLength)
at Microsoft.AspNetCore.Mvc.Infrastructure.FileStreamResultExecutor.ExecuteAsync(ActionContext context, FileStreamResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|21_0(ResourceInvoker invoker, IActionResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Edited after apply comment solution :
If I remove using its working fine but when I am using
document.Close();
writer.Close();
before fsr = File(ms, "application/pdf", "test.pdf"); its again same error and if I dont close the document and writer , downloaded pdf is in corrupt format , not able to open.
Okay, So I am able to figure this out what was the issue.
In original code issue was using block , as already mentioned in comments section.
But when I removed using still facing issue of stream closing when I close document and writer .
and the reason is The PdfWriter class may be closing your stream. Make sure to set the CloseStream property to false.
so I set writer CloseStream property to false , just after declare.
PdfWriter writer = PdfWriter.GetInstance(document, ms);
writer.CloseStream = false;
and its worked.
[Route("preview/{Id}")]
[System.Web.Http.HttpGet]
public async Task<IActionResult> PreviewSpecSheet(int Id)
{
FileStreamResult fsr;
Document document = new Document(PageSize.A4, 25, 25, 30, 30);
MemoryStream ms = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(document, ms);
writer.CloseStream = false;
document.Open();
//header Image
iTextSharp.text.Image headerImg = iTextSharp.text.Image.GetInstance("D:\\go2\\Pixelle\\specsheet\\pixservice\\assets\\header.jpg");
headerImg.SetAbsolutePosition(0, 750);
headerImg.ScaleAbsolute(500f, 100.00f);
document.Add(headerImg);
document.Close();
writer.Close();
ms.Position = 0;
fsr = File(ms, "application/pdf", "test.pdf");
return fsr;
}

How to get a user from an IGraphServiceClient object?

I have a POST method and want to get a user from an IGraphServiceClient object (in the Graph.Microsoft package and namespace).
The GET method works fine. Then I take a user from this list and set them as a parameter for my POST method.
public async Task<Dictionary<string, List<string>>> GetUserGroupsAsync(ICollection<string> userIds)
{
var aggregatedUserGroupMap = new Dictionary<string, List<string>>();
foreach (string userId in userIds)
{
try
{
var userMemberOfCollectionRequest = graphServiceClient.Users[userId].MemberOf.Request();
var userMemberOfCollection = await userMemberOfCollectionRequest.GetAsync().ConfigureAwait(false);
if (!aggregatedUserGroupMap.ContainsKey(userId)) { aggregatedUserGroupMap.Add(userId, new List<string>()); }
foreach (var memberOf in userMemberOfCollection) { aggregatedUserGroupMap[userId].Add(memberOf.Id); }
}
catch (Exception ex)
{
throw ex;
}
}
return aggregatedUserGroupMap;
}
The values in the incoming string collection, userIds, are user email addresses, copied from the GET result.
The value of userMemberOfCollectionRequest looks fine. The RequestUrl property contains "https://graph.microsoft.com:443/v1.0/users/my-email#compagny.com/memberOf". Headers and QueryOptions are empty collections.
In the above method, the following line throws an exception:
var userMemberOfCollection = await userMemberOfCollectionRequest.GetAsync().ConfigureAwait(false);
The exception message reads:
Request_ResourceNotFound
Resource 'my-email#compagny.com' does not exist or one of its queried reference-property objects are not present.
at Microsoft.Graph.HttpProvider.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at Microsoft.Graph.BaseRequest.SendRequestAsync(Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.BaseRequest.SendAsync[T](Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.UserMemberOfCollectionWithReferencesRequest.GetAsync(CancellationToken cancellationToken)
at xxx.xxx.BusinessComponent.GraphBC.GetUserGroupsAsync(ICollection`1 userIds) in C:\workspace\xxx\xxx.xxx\xxx.xxx.Core\BusinessComponent\GraphBC.cs:line 50
Does anyone have an idea for where I should look to solve this problem?
The solution was not to use the email, instead using the ObjectId property (a GUID instead of an email).

Can't get two-way SSL to work with HttpWebRequest

I have a WCF service application that is supposed to connect to another server X to retrieve data. When server X is configured with one-way SSL, the WCF service application is able to connect to it without problem. But when server X is configured with two-way SSL, the WCF service application will have problem connecting to it.
The WCF service application uses a self-signed certificate. This certificate was exported without private key into a .cer file, and imported into server X's trust store. The same exported certificate was used in the WCF service application's codes:
string URL = "https://11.205.112.49:5311/Ping";
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(URL);
X509Certificate2 Certificate = new X509Certificate2("F:\\cert.cer");
Request.ClientCertificates.Add(Certificate);
Request.Method = "GET";
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
The last line of the codes above will throw WebException with the following message:
The request was aborted: Could not create SSL/TLS secure channel.
The above error does not provide much details.
Help is appreciate.
Thanks in advance.
EDIT:
This is my entire program:
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.IO;
namespace TestTwoWaySSL
{
class Program
{
static void Main(string[] args)
{
HttpWebResponse Response = null;
try
{
string URL = "https://11.205.112.49:5311/Ping";
Console.WriteLine("URL: [{0}].", URL);
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(URL);
X509Certificate2 Certificate = new X509Certificate2("F:\\cert.pfx", "password");
Request.ClientCertificates.Add(Certificate);
Request.Method = "GET";
Console.WriteLine("Sending request.");
Response = (HttpWebResponse)Request.GetResponse();
Console.WriteLine("Request sent.");
}
catch (WebException webException)
{
Console.WriteLine("Web exception occurred: [{0}].", webException.Message);
Console.WriteLine(webException.StackTrace);
Response = webException.Response as HttpWebResponse;
}
catch (Exception exception)
{
Console.WriteLine("Exception occurred: [{0}].", exception.Message);
Console.WriteLine(exception.StackTrace);
}
Console.WriteLine("Response status code: [{0}].", Response.StatusCode);
Console.WriteLine("Response \"Content-Type\" header value: [{0}].", Response.ContentType);
Console.WriteLine("Response \"Content-Length\" header value: [{0}].", Response.ContentLength);
String ResponseMessageBody = new StreamReader(Response.GetResponseStream()).ReadToEnd();
Console.WriteLine("Response message body: [{0}].", ResponseMessageBody);
}
}
}
When it reaches the line Request.GetResponse(), an AccessVioationException is thrown:
Unhandled Exception: System.AccessViolationException: Attempted to read or write
protected memory. This is often an indication that other memory is corrupt.
at System.Net.UnsafeNclNativeMethods.SafeNetHandles_SECURITY.AcquireCredentialsHandleW(String principal, String moduleName, Int32 usage, Void* logonID, SecureCredential& authData, Void* keyCallback, Void* keyArgument, SSPIHandle& handlePtr, Int64& timeStamp)
at System.Net.SafeFreeCredentials.AcquireCredentialsHandle(SecurDll dll, String package, CredentialUse intent, SecureCredential& authdata, SafeFreeCredentials& outCredential)
at System.Net.SSPISecureChannelType.AcquireCredentialsHandle(String moduleName, CredentialUse usage, SecureCredential& authdata, SafeFreeCredentials& outCredential)
at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface SecModule, String package, CredentialUse intent, SecureCredential scc)
at System.Net.Security.SecureChannel.AcquireCredentialsHandle(CredentialUse credUsage, SecureCredential& secureCredential)
at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint)
at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset, Int32 count, Byte[]& output)
at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offset, Int32 count)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.TlsStream.CallProcessAuthentication(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
at System.Net.HttpWebRequest.EndSubmitRequest()
at System.Net.HttpWebRequest.SetRequestSubmitDone(ConnectStream submitStream)
at System.Net.Connection.CompleteConnection(Boolean async, HttpWebRequest request)
at System.Net.Connection.CompleteStartConnection(Boolean async, HttpWebRequest httpWebRequest)
at System.Net.Connection.CompleteStartRequest(Boolean onSubmitThread, HttpWebRequest request, TriState needReConnect)
at System.Net.Connection.SubmitRequest(HttpWebRequest request, Boolean forcedsubmit)
at System.Net.ServicePoint.SubmitRequest(HttpWebRequest request, String connName)
at System.Net.HttpWebRequest.SubmitRequest(ServicePoint servicePoint)
at System.Net.HttpWebRequest.GetResponse()
at TestTwoWaySSL.Program.Main(String[] args)
The problem is that you are missing private key. You are using only the certificate.
Either use pkcs#12 when loading certificate into X509Certificate2 class
X509Certificate2 Certificate = new X509Certificate2("F:\\cert.p12", "p12 password");
or load certificate from store
X509Store store = new X509Store("MY",StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2 certificate = collection.Find(...)[0];
store.Close();

WSACancelBlockingCall Exception with Amazon

I have occasional exception when reading / storing objects with Amazon S3 from asp.net application.
Exception says:
Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall. A blocking operation was interrupted by a call to WSACancelBlockingCall
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
Any ideas about how I can locate what is reason of this error?
here is my read function:
public Image GetImage(string fullKey, out string errorMessage)
{
errorMessage = null;
try
{
GetObjectResponse response = s3Client.GetObject(new GetObjectRequest()
{
BucketName = BucketName,
Key = fullKey,
Timeout = ImportTimeout
});
return Image.FromStream(response.ResponseStream);
}
catch (Exception e)
{
errorMessage = e.Message;
Log.Current.WriteError(e);
}
return null;
}
s3Client is initialised in constructor of this class:
s3Client = AWSClientFactory.CreateAmazonS3Client(AWSAccessKey, AWSSecretKey);
According to aws documentation it is correct to wrap call to GetObject with using:
http://docs.amazonwebservices.com/sdkfornet/latest/apidocs/html/M_Amazon_S3_AmazonS3_GetObject.htm
This eliminates all exceptions related to GetObject method