JsonConvert DataSet .NET Core 2.0 not working - asp.net-core

This example no longer seems to work in .NET Core 2.0, it now serializes using an XmlDiffGram. Any easy way to get it working? Do I need to do this whole thing?

As of 25/04/2018. Download latest version of Newtonsoft. I upgraded to 11.0.2. It now works with ASP Core 2. Datasets get converted to JSON.

It's looks like the Netonsoft crew have written a specific converters for DataSet & DataTables which should point you in the right direction.
Quick update:
It looks like these are not quite in the latest nuget release yet, but coming soon.
when they are released, you'll need to change the line in the example to something like.
string json = JsonConvert.SerializeObject(dataSet, Formatting.Indented, new JsonSerializerSettings { Converters = new[] { new Newtonsoft.Json.Converters.DataSetConverter() } });

Well this works...
var xml = new XDocument();
using (var writer = xml.CreateWriter())
{
dataSet.WriteXml(writer);
writer.Flush();
}
return Json(xml);

Related

.Net Core NewtonsoftJson DateTimeZoneHandling setting not working

I started porting our .Net Framework WebAPIs to .Net Core 5 at work. I noticed that dates being returned in the SPA were off and upon further investigation I saw that after the objects were serialized that the dates were being set as UTC.
I've found that I can get it to work at serialization/deserialization by adding the option as an argument, but it seems like this should be able to be done globally instead of each time the serializer runs.
I've tried adding the following in the WebAPI Startup.cs to change how the dates were being returned but it doesn't seem to work in the startup:
services.AddControllers().AddNewtonsoftJson(o => o.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Unspecified);
Add this:
services.AddControllers().AddNewtonsoftJson();
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Unspecified
};
I had to convert to UTC format(DateTimeZoneHandling.Utc) and the above ways(DateTimeZoneHandling) did not work for me. Finally below worked:
.AddNewtonsoftJson(opts =>
{
opts.SerializerSettings.Converters.Add(new IsoDateTimeConverter
{
DateTimeStyles = DateTimeStyles.AdjustToUniversal
});
}
I hope this helps to people who are looking to convert date time format to UTC globally.

Rendering .rdlc reports with ASP .NET Core

Is it possible to render .rdlc reports with ASP.NET Core? Currently this only seems to be possible if I target the .NET Framework as opposed to .NET Core.
I don't need a report viewer I just need to render the results of an .rdlc report as a byte array.
If you want to create pdf/excel/word using rdlc report I recommend you can use AspNetCore.Reporting library. This is open source and comes as a nuget package. you can integrate this in your .NET Core API or .NET Core Azure function. You can generate a byte array convert it to base 64 string and retrieve that to your client side. More on the link in the comment.
You very well can render rdlc into a byte array. Please see a related question I asked a while back. RDLC Local report viewer for ASP.NET Core and Angular(>2.0).
Eventually a creative discussion on that thread resulted in an angular package(https://www.npmjs.com/package/ng2-pdfjs-viewer - Disclosure; I am the author) with consumable rdlc byte array functionality on client side. Of course, instead of this package, you may choose another javascript library to display the byte array.
A simple usage on angular would be like this. Please note, most of the code can be reused even if you are using plain js or another framework.
The below code demonstrates
1. Spitting byte array using RDLC report viewer control on aspnet core action method(on server side) and sending it over wire using http. (Code is in C#)
2. Processing response's byte array into a blob object (Js)
3. Feeding blob object into ng2-pdfjs-viewer.
4. ng2-pdfjs-viewer internally uses Mozilla's PDFJS to accomplish the feat of displaying the PDF on browser.
(FYI.. I took code from samples provided on ng2-pdfjs-viewer package. Replace step 3 and 4 if you are using another library or plain javascript)
<!-- your.component.html -->
<button (click)="showPdf();">Show</button>
<div style="width: 800px; height: 400px">
<ng2-pdfjs-viewer #pdfViewer></ng2-pdfjs-viewer>
</div>
export class MyComponent implements OnInit {
#ViewChild('pdfViewer') pdfViewer
...
private downloadFile(url: string): any {
return this.http.get(url, { responseType: ResponseContentType.Blob }).map(
(res) => {
return new Blob([res.blob()], { type: "application/pdf" });
});
}
public showPdf() {
let url = "http://localhost/api/GetMyPdf";
this.downloadFile(url).subscribe(
(res) => {
this.pdfViewer.pdfSrc = res; // <---- pdfSrc can be Blob or Uint8Array
this.pdfViewer.refresh(); // Ask pdf viewer to load/reresh pdf
}
);
}
[HttpGet]
[Route("MyReport")]
public IActionResult GetReport()
{
var reportViewer = new ReportViewer {ProcessingMode = ProcessingMode.Local};
reportViewer.LocalReport.ReportPath = "Reports/MyReport.rdlc";
reportViewer.LocalReport.DataSources.Add(new ReportDataSource("NameOfDataSource1", reportObjectList1));
reportViewer.LocalReport.DataSources.Add(new ReportDataSource("NameOfDataSource2", reportObjectList1));
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string extension;
var bytes = reportViewer.LocalReport.Render("application/pdf", null, out mimeType, out encoding, out extension, out streamids, out warnings);
return File(bytes, "application/pdf")
}
In case anyone is still looking for a similar solution, I would recommend using "ReportViewerCore.NETCore".
Here is the nuGet reference - https://www.nuget.org/packages/ReportViewerCore.NETCore/
Here is the github link to the repo - https://github.com/lkosson/reportviewercore/
Basic usage
Stream reportDefinition; // your RDLC from file or resource
IEnumerable dataSource; // your datasource for the report
LocalReport report = new LocalReport();
report.LoadReportDefinition(reportDefinition);
report.DataSources.Add(new ReportDataSource("source", dataSource));
report.SetParameters(new[] { new ReportParameter("Parameter1", "Parameter value") });
byte[] pdf = report.Render("PDF");
You can not render .rdlc reports in .NET Core, using .rdlc as a byte array.
Rendering RDLC reports relies on WinForms and WebForms and is currently only supported on .NET Framework. Hopefully Microsoft will make a (slimmed down) version available (just rendering the reports for starters) on .NET Core or .NET 5, but no word as of yet.
As an alternative, you could go for a solution where you run report rendering as a separate ASP.NET 2 app targeting .NET Framework, while the rest of your app could target .NET Core 3 or later. That way, you can call the reporting endpoints with the appropriate data, and it returns a rendered report.
This is what I've done, creating a sort of microservices architecture where multiple .Net Core 3.1 apps can post both the XML RDLC report definition and data to an endpoint running on net48, which uses the LocalReport class to render the report to the desired format, returning it as a byte array.
Angular app | ----> | APIs (.Net Core 3.1) | ----> | API (.Net Framework 4.8)

How to get users/group list on active directory in .net core 2

Working on a project, where all users are created in active directory under a domain.
What I want is get all users that are in the domain, is this possible?
I am new to active directory, using .net core2.0.
Any suggestions and guidance is appreciated.
There is an implementation of System.DirectoryServices.AccountManagement for .NET Core 2, published by the .Net Foundation. See the nuget reference here
This will allow you to make calls like this:
using (var ctx = new PrincipalContext(ContextType.Domain, "MyDomain")){
var myDomainUsers = new List<string>();
var userPrinciple = new UserPrincipal(ctx);
using (var search = new PrincipalSearcher(userPrinciple)){
foreach (var domainUser in search.FindAll()){
if (domainUser.DisplayName != null){
myDomainUsers.Add(domainUser.DisplayName);
}
}
}
}
Exact what i was looking for...
You can use the Microsoft Graph API to interact with the data users in the Microsoft cloud(Including AAD).
Link here
Documentation

Migirating to Stimulsoft Core

For getting Pdf report in Asp.net MVC I am working with Stimulsoft 2015. The problem is that I have no idea how to convert my code in order to work with Stimulsoft Core in Asp.net Core. it seems some features are not available anymore in Stimulsoft Core (like StiReport).
This is the code which works fine in Asp.net MVC
public ActionResult GetReportSnapshot(string sort)
{
StiReport report = new StiReport();
report.Load(Server.MapPath("~/Reports/Jobs.mrt"));
report["#PrjectId"] = 1;
report["#OrderBy"] = sort;
report.Dictionary.Variables["title"] = new Stimulsoft.Report.Dictionary.StiVariable("title", sort);
report.Render();
MemoryStream stream = new MemoryStream();
report.ExportDocument(StiExportFormat.Pdf, stream);
stream.Position = 0;
FileStreamResult fsr = new FileStreamResult(stream, "application/pdf");
return fsr;
}
I will appreciate any help.
In NuGet Package Stimulsoft.Reports.Web.NetCore version 2018.3.5.
and Asp.Net core 2.0.
This is working for me, Try this:
public IActionResult GetReportSnapshot(string sort)
{
StiReport report = new StiReport();
report.Load(#"C:\Users\Admin\Desktop\report.mrt"); // laod report
report.Render();
report["#PrjectId"] = 1;
report["#OrderBy"] = sort;
report.Dictionary.Variables["title"] = new Stimulsoft.Report.Dictionary.StiVariable("title", sort);
// Create an PDF settings instance. You can change export settings.
var settings = new Stimulsoft.Report.Export.StiPdfExportSettings();
// Create an PDF service instance.
var service = new Stimulsoft.Report.Export.StiPdfExportService();
// Create a MemoryStream object.
var stream = new MemoryStream();
// Export PDF using MemoryStream.
service.ExportTo(report, stream, settings);
return File(stream.ToArray(), "application/octet-stream");
}
What nuget packages are you using? It could be you are missing the nuget packages containing the StiReport class. (I see they split up their library over multiple nuget packages)
Also it could be they have not migrated this part to dotnet core yet.
i'd advise you to click around there github repo and see if you can find any information there: https://github.com/stimulsoft, or on there website.
By the looks of nuget they have only recently started to migrate to dotnet core so this would suppose my second suggestion is the right suggestion.

How can I make RestSharp use BSON?

I'm using RestSharp, and using Json.NET for serialization (see here).
Json.NET supports BSON, and since some of my requests have huge blocks of binary data, I think this would speed up my application dramatically. However, as far as I can tell, RestSharp does not seem to have any in-built support for BSON.
The use of Json.NET is implemented as a custom serializer for RestSharp, and so at first glance it looks like it would be possible to modify that custom serializer to use BSON. But, the Serialize method of the RestSharp.Serializers.ISerializer interface returns a string - which is (I assume) unsuitable for BSON. So, I assume that it would take some more significant changes to RestSharp to implement this change.
Has anyone figured out a way to do this?
Update: I looked at the RestSharp source, and discovered that the RestRequest.AddBody method that takes my object and serializes it into the request body eventually calls Request.AddParameter (with the serialized object data, and the parameter type RequestBody).
I figured that I might be able to serialize my object to BSON and then call Request.AddParameter directly - and indeed I can. However, when RestSharp then executes the RestRequest, it fails to put the binary content into the request, because there are other embedded assumptions about the request content being UTF-8 encoded.
Thus it looks like this hack would not work - there would need to be some changes made to RestSharp itself, and I'm not the man for the job...
Update 2: I decided to have a go at using the debugger to figure out how much of RestSharp I'd have to change to overcome the body-encoding issue, so I swapped out my NuGet version of RestSharp and included the RestSharp project in my solution. And... it worked.
It turns out that there has been a change to RestSharp in the last few months that isn't yet in the NuGet version.
So, you can now use AddParameter and pass in an already-BSON-encoded object, and RestSharp will send it off to the server without complaint.
Per the updates in my question, it turns out that if you have the latest RestSharp source, then instead of this:
request.AddBody(myObject);
... you can do this instead whenever you have a payload that would benefit from using BSON:
using (var memoryStream = new System.IO.MemoryStream())
{
using (var bsonWriter = new Newtonsoft.Json.Bson.BsonWriter(memoryStream))
{
var serializer = new Newtonsoft.Json.JsonSerializer();
serializer.Serialize(bsonWriter, myObject);
var bytes = memoryStream.ToArray();
request.AddParameter("application/bson", bytes, RestSharp.ParameterType.RequestBody);
}
}
Note that the first parameter to AddParameter is supposedly the parameter name, but in the case of ParameterType.RequestBody it's actually used as the content type. (Yuk).
Note that this relies on a change made to RestSharp on April 11 2013 by ewanmellor/ayoung, and this change is not in the current version on NuGet (104.1). Hence this will only work if you include the current RestSharp source in your project.
Gary's answer to his own question was incredibly useful for serializing restful calls. I wanted to answer how to deserialize restful calls using JSON.NET. I am using RestSharp version 104.4 for Silverlight. My server is using Web API 2.1 with BSON support turned on.
To accept a BSON response, create a BSON Deserializer for RestSharp like so
public class BsonDeserializer : IDeserializer
{
public string RootElement { get; set; }
public string Namespace { get; set; }
public string DateFormat { get; set; }
public T Deserialize<T>(IRestResponse response)
{
using (var memoryStream = new MemoryStream(response.RawBytes))
{
using (var bsonReader = new BsonReader(memoryStream))
{
var serializer = new JsonSerializer();
return serializer.Deserialize<T>(bsonReader);
}
}
}
}
Then, ensure your request accepts "application/bson"
var request = new RestRequest(apiUrl, verb);
request.AddHeader("Accept", "application/bson");
And add a handler for that media type
var client = new RestClient(url);
client.AddHandler("application/bson", new BsonDeserializer());