I'm having problems getting RestSharp to deserialize some XML
this is a sample of the xml
<data xmlns:xlink="http://www.w3.org/1999/xlink">
<parameters xmlns="">
<query-strings>
<query-string value="testValue"></query-string>
</query-strings>
<sources>
<source id="database"></source>
</sources>
</parameters>
<objects>
<object xmlns="" type="testType">
<source id="database"></source>
</object>
<object xmlns="" type="testType">
<source id="database2"></source>
</object>
<object xmlns="" type="testType">
<source id="database3"></source>
</object>
</objects>
</data>
Below is the Class that I'm trying to deserialize to
public class Data
{
public Parameter Parameters { get; set; }
}
public class Parameter
{
public string InverseLookup { get; set; }
public string TypeFilters { get; set; }
public List<QueryString> QueryStrings { get; set; }
public List<Source> Sources { get; set; }
public List<Item> objects { get; set; }
}
public class QueryString
{
public string value { get; set; }
}
public class Source
{
public string Id { get; set; }
}
public class Item
{
public string Type { get; set; }
public Source Source { get; set; }
}
The problem that I have is the objects element, I just can't seem to get this to deserialize. Does anyone have any idea what's going on?
The problem appears to have been between the Keyboard and Chair. (aka I'm an idiot.)
public class Data
{
public Parameter Parameters { get; set; }
}
Should have been
public class Data
{
public Parameter Parameters { get; set; }
Public List<Item> Objects {get; set; }
}
Related
I am creating a ASP.NET Core web API that uses EF Core. I have a GET endpoint that returns a list of reports from the database. I have a related table which stores screenshots for the reports. The reportId is the foreign key in the images table.
I have a List item in the reports class which points to the ImagesList class.
I have the foreign key reportId in the ImageList class and identified as a foreign key. I also have a navigation property setup to the Reports class.
Reports Class:
[Table("Vw_ReportsList", Schema = "pbi")]
public class Reports
{
[Key]
public string reportId { get; set; }
[Required]
public string reportName { get; set; }
public string reportDescription { get; set; }
public string reportType { get; set; }
public string reportAuthor { get; set; }
public string reportLastUpdate { get; set; }
public string reportLastExecution { get; set; }
public List<ImagesList> Screenshots { get; set; }
//collection navigation property
}
ImageList Class:
[Table("Vw_ScreenshotsList", Schema = "pbi")]
public class ImagesList
{
[Key]
public int id { get; set; }
public string fileNameTest { get; set; }
public string imageData { get; set; }
public string created { get; set; }
public string reportId { get; set; }
[ForeignKey("reportId")]
public virtual Reports Reports { get; set; }
//navigation property
}
Context:
public class ServiceCatalogContext : DbContext
{
public ServiceCatalogContext(DbContextOptions<ServiceCatalogContext> options) : base(options) { }
public DbSet<Reports> Reports { get; set; }
public DbSet<ImagesList> ImagesLists { get; set; }
public DbSet<Images> Images { get; set; }
//used for the image upload POST call
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// modelBuilder.Entity<ImagesList>().HasOne<Reports>().WithMany().HasForeignKey(s => s.reportId);
modelBuilder.Entity<ImagesList>().HasOne(s => s.Reports).WithMany(s => s.Screenshots).HasForeignKey(s => s.reportId);
modelBuilder.Entity<Reports>().HasMany(r => r.Screenshots).WithOne().HasForeignKey(r => r.reportId);
}
}
My API works and returns the list of reports with no errors but I do not receive the screenshots list that I am expecting.
Here is a sample of the API output:
{
"reportId": "AC79F4CD-3771-42B2-B7F8-46AE4CE8DC80",
"reportName": "Dashboard Usage Metrics Report",
"reportDescription": "DESCRIPTION HERE - Dashboard Usage Metrics Report",
"reportType": "Excel",
"reportLastUpdate": "07/22/2020",
"reportLastExecution": "07/23/2020"
},
{
"reportId": "138CD5FA-6B5A-4C63-A449-DA9A9BBBF689",
"reportName": "Report Usage Metrics Report",
"reportDescription": "DESCRIPTION HERE - Report Usage Metrics Report",
"reportType": "Excel",
"reportLastUpdate": "07/22/2020",
"reportLastExecution": "07/23/2020"
}
I not receiving any error message from the API so I am not sure what I missed in order for each report to return the related images.
Edit: Adding Controller action
[HttpGet]
[EnableQuery()] //enabled OData querying
public IQueryable<Reports> Get()
{
return _context.Reports;
}
Edit: Updated ImagesList class
I also have Odata installed so here the metadata if that is of help:
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="ServiceCatalog.API.Entities" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Reports">
<Key>
<PropertyRef Name="reportId" />
</Key>
<Property Name="reportId" Type="Edm.String" Nullable="false" />
<Property Name="reportName" Type="Edm.String" Nullable="false" />
<Property Name="reportDescription" Type="Edm.String" />
<Property Name="reportType" Type="Edm.String" />
<Property Name="reportLastUpdate" Type="Edm.String" />
<Property Name="reportLastExecution" Type="Edm.String" />
<NavigationProperty Name="Screenshots" Type="Collection(ServiceCatalog.API.Entities.ImagesList)" />
</EntityType>
<EntityType Name="ImagesList">
<Key>
<PropertyRef Name="id" />
</Key>
<Property Name="id" Type="Edm.Int32" Nullable="false" />
<Property Name="fileNameTest" Type="Edm.String" />
<Property Name="imageData" Type="Edm.String" />
<Property Name="created" Type="Edm.String" />
<Property Name="reportId" Type="Edm.String" />
<NavigationProperty Name="Reports" Type="ServiceCatalog.API.Entities.Reports">
<ReferentialConstraint Property="reportId" ReferencedProperty="reportId" />
</NavigationProperty>
</EntityType>
</Schema>
<Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="Container">
<EntitySet Name="reports" EntityType="ServiceCatalog.API.Entities.Reports" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Design your model like below:
[Table("Vw_ReportsList", Schema = "pbi")]
public class Reports
{
[Key]
public string reportId { get; set; }
[Required]
public string reportName { get; set; }
public string reportDescription { get; set; }
public string reportType { get; set; }
public string reportAuthor { get; set; }
public string reportLastUpdate { get; set; }
public string reportLastExecution { get; set; }
public List<ImagesList> Screenshots { get; set; }
//collection navigation property
}
[Table("Vw_ScreenshotsList", Schema = "pbi")]
public class ImagesList
{
[Key]
public int id { get; set; }
public string fileNameTest { get; set; }
public string imageData { get; set; }
public string created { get; set; }
public string reportId { get; set; }
// [ForeignKey("reportId")]
public virtual Reports Reports { get; set; }
//navigation property
}
And your DbContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ImagesList>().HasOne(s => s.Reports)
.WithMany(s => s.Screenshots).HasForeignKey(s => s.reportId);
//modelBuilder.Entity<Reports>().HasMany(r => r.Screenshots).WithOne().HasForeignKey(r => r.reportId);
}
Your controller:
[HttpGet]
public IQueryable<Reports> Get()
{
return _context.Reports.Include(r=>r.Screenshots);
}
Be sure to install Microsoft.AspNetCore.Mvc.NewtonsoftJson then use the following code:
services.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
I searched many solutions but I can't understand why database does not create? My classes and context class are very simple.
public class News
{
[Key]
public int NewsID { get; set; }
public string NewsHeader { get; set; }
public string News { get; set; }
public int CategoryID;
public virtual Category Category { get; set; }
}
public class Category
{
[Key]
public int CategoryID { get; set; }
public string CategoryName{ get; set; }
public virtual ICollection<News> Newss { get; set; }
}
public class NewsContext: DbContext
{
public NewsContext(): base("NewsContext")
{
Database.SetInitializer<NewsContext>(new CreateDatabaseIfNotExists<NewsContext>());
}
public DbSet<News> Newss { get; set; }
public DbSet<Category> Categories { get; set; }
}
and my connection string is right below
<connectionStrings>
<add name="NewsContext" connectionString="Data Source=nevra\sqlexpress;Initial Catalog=NewsContext;Integrated Security=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
I have a entity class SEBLInBound as mentioned below
public class SEBLInbound
{
public int MEME_CK
{
get;
set;
}
public String EligibilityBeginDate
{
get;
set;
}
public String EligibilityEndDate
{
get;
set;
}
public Char VoidIndicator
{
get;
set;
}
public Char ReInstate
{
get;
set;
}
public char PriorToGoLive
{
get;
set;
}
}
I have declared a INOutArgument in XAML with type of this Entity class
<x:Members>
<x:Property Name="ErrorMsg" Type="OutArgument(x:String)" />
<x:Property Name="InboundProp" Type="InOutArgument(local:SEBLInbound)" />
<x:Property Name="argument1" Type="InArgument(x:String)" />
<x:Property Name="argument2" Type="InArgument(x:String)" />
</x:Members>
now from cs file i want to pass list value List to this Xaml for manipulation.
Please let me know, how to pass the value to workflow
THanks in advance
You pass objects into Workflow arguments using a dictionary object where the Keys are the name of the argument.
IDictionary<string, object> inParams = new Dictionary<string, object>
{
{"InboundProp", _yourDataObject01 },
{"argument1", _yourDataObject02 },
{"argument2", _yourDataObject03 },
};
_workflowApplication = new WorkflowApplication(new MyWorkFlow(), inParams)
_workflowApplication.Run();
I'm creating a wcf wrapper service that returns xml from another web service.
What I'm noticing is that not all the xml from the source is being serialized to my object.
Here's the source xml:
<?xml version="1.0" standalone="yes"?>
<methodResponse>
<requestId>234843080</requestId>
<errorCode>0</errorCode>
<errorText></errorText>
<processingTime>00:00:00.234</processingTime>
<results>
<resultCode>0</resultCode>
<resultText></resultText>
<resultCount>1</resultCount>
<totalResultCount>1</totalResultCount>
<result>
<contactId>123</contactId>
<sourceFolderId>3443</sourceFolderId>
<contactState>4</contactState>
<contactStateSortOrder>3</contactStateSortOrder>
<contactType>person</contactType>
<displayName>Bond, James</displayName>
<office>unknown</office>
<department></department>
<changeDate></changeDate>
<firstName>James</firstName>
<middleName></middleName>
<lastName>Bond</lastName>
<jobTitle>Spy</jobTitle>
<ape>
<address type='Street' typeId='1' relationship='Business' relationshipId='1'>
<addressLine></addressLine>
<city></city>
<state></state>
<postalCode></postalCode>
</address>
<phone type='Phone' typeId='1' relationship='Business' relationshipId='1'>
<phoneNumber></phoneNumber>
<description/>
<formattedPhone></formattedPhone>
</phone>
</ape>
</result>
</results>
</methodResponse>
The wcf wrapper service:
[DataContract(Name="methodResponse", Namespace = "")]
public partial class methodResponse {
[DataMember]
public int errorCode {
get;
set;
}
[DataMember]
public string errorText {
get;
set;
}
[DataMember]
public string requestId
{
get;
set;
}
[DataMember]
public methodResponseResults[] results
{
get;
set;
}
}
[DataContract(Namespace = "")]
public partial class methodResponseResults
{
[DataMember]
public string resultCode {
get;
set;
}
[DataMember]
public string resultText {
get;
set;
}
[DataMember]
public string resultCount {
get;
set;
}
[DataMember]
public string totalResultCount {
get;
set;
}
[DataMember]
public methodResponseResultsResult[] result {
get;
set;
}
}
[DataContract(Namespace="")]
public partial class methodResponseResultsResult {
public string contactId
{
get;
set;
}
public string displayName
{
get;
set;
}
}
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class WcfWrapperService
{
public Response GetXml()
{
string uri = ""; // uri to source web service
var dataContractSerializer = new DataContractSerializer(typeof(methodResponse));
using (XmlReader reader = XmlReader.Create(uri))
{
var result = (methodResponse)dataContractSerializer.ReadObject(reader);
//result object looks like:
//result.errorCode = 0;
//result.errorText = null;
//result.requestId = 234843080;
//result.results = methodResponseResults[0];
}
// return Response object
}
}
The errorCode, errorText, requestId values are there but no results.
The first thing that jumps out is that you are trying to de/serialize a contract which contains attributes. DataContractSerializer has a few restrictions, one of which is that it can only serialize/deserialize elements. In order to properly handle this Schema, you will need to use an XmlSerializer.
Your not setting any values for the Order property on your DataMember attributes. This means that the elements will be processed in alphabetical order which is most likely NOT what you want. You must explicitly set Order to ensure it matches the schema of the documents you will process. You may also need to set IsRequired = false if there are any elements that may or not be in the instance document.
The current xml output looks like:
<response xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<totalResultCount>10</totalResultCount>
<results xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a:anyType i:type="result">
<EmployeeCode>007</EmployeeCode>
<EmployeeName>Bond, James</EmployeeName>
</a:anyType>
<a:anyType i:type="result">
<EmployeeCode>006</EmployeeCode>
<EmployeeName>Foo, Bar</EmployeeName>
</a:anyType>
</results>
</response>
I would like the xml to be in this format:
<response xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<totalResultCount>10</totalResultCount>
<results xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<result>
<EmployeeCode></EmployeeCode>
<EmployeeName></EmployeeName>
</result>
</results>
</response>
Data Contracts
internal static class KnownTypesProvider
{
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
{
// collect and pass back the list of known types
List<Type> types = new List<Type>();
types.Add(typeof(EmployeeDTO));
return types;
}
}
[DataContract(Name = "response")]
public class Response
{
[DataMember(Order = 1)]
public int totalResultCount { get; set; }
[DataMember(Order = 2)]
public IEnumerable results { get; set; }
}
[DataContract(Name = "result")]
public class EmployeeDTO
{
[DataMember]
public string EmployeeCode { get; set; }
[DataMember]
public string EmployeeName { get; set; }
}
What am I missing here?
IEnumerable is a list of Object, so WCF is adding the type to the output. Can you use IEnumerable<EmployeeDTO> or List<EmployeeDTO>?