Dynamically generate anonymous type - asp.net-mvc-3

I have an application that deserializes this xml:
<SpecialRoutesList>
<SpecialRoutes>
<SpecialRoute>
<Name>TestRoute1</Name>
<Pattern>TestRouteUrl1</Pattern>
<Defaults>
<Controller>Home</Controller>
<Action>TestRoute1</Action>
<Params>
<Key>id</Key>
<Value>1</Value>
</Params>
</Defaults>
</SpecialRoute>
<SpecialRoute>
<Name>TestRoute2</Name>
<Pattern>TestRouteUrl2</Pattern>
<Defaults>
<Controller>Home</Controller>
<Action>TestRoute2</Action>
<Params>
<Key>id</Key>
<Value>1</Value>
</Params>
</Defaults>
</SpecialRoute>
</SpecialRoutes>
</SpecialRoutesList>
I'm interested to use this deserialized information to map each route:
foreach(SpecialRoute route in SpecialRoutesList.SpecialRoutes) {
routes.MapRoute(route.Name, route.Pattern, new { ?????????? }, ????????);
}
To set the defaults of a route it's needed to use anonymous types, so how can I use these anonymous types, taking the keys and values from my deserialized class at runtime?
Thanks
Regards
Jose

routes.MapRoute() builds RouteValueDictionary from defaults. So you may deserialize/build Dictionary<string,object> from your xml and pass it to routes.MapRoute(). Same with constraints paramenter.
Update: defaults built as dictionary
var defaults = new Dictionary<string, object> {{"controller", "Account"}, {"action", "Login"}};
routes.MapRoute(
"Default", // Route name
"{controller}/{action}", // URL with parameters
defaults
);

Related

How change namespace of Soap ns2 message in %SOAP.Webclient

I've created a soap client connection using the wizard of Atelier and it has created all messages (request and response) and the business operation object.
This soap connection will be used to connecto with other SOAP Webservices (changing the URL) but the namespace of the envelope will be different for the destination.
I've done a change into the Soap class to add my namespace for the envelope
Property Namespace As %String
Parameter SETTINGS = "Namespace:Basic";
Method methodFind(idEspecialist As %String(REQUIRED=1), actList As %ListOfObjects(Myapp.ns2.actType") [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
Quit ..WebMethod("methodFind").Invoke($this,..Namespace_"/methodFind",.idEspecialist,.actList)
}
and it works, only I have to create a new BO item in the producction and set the namespace for the destination.
But the ns.actType has the property namespace in the definition (as I said, this object has been created with the wizard of Atelire (SOAP)) and it is used for all BO.
/// created from: http://mywsservice.salutic.org/EspecialistWS?wsdl=EspecialistWSSoap.wsdl
Class Myapp.ns2.actoType Extends (%SerialObject, %XML.Adaptor) [ ProcedureBlock ]
{
Parameter ELEMENTQUALIFIED = 1;
Parameter NAMESPACE = "http://mywsservice.salutic.org/";
Parameter XMLNAME = "actType";
Parameter XMLSEQUENCE = 1;
Property ActCode As %String(MAXLEN = "", XMLNAME = "ActCode") [ Required ];
Property description As %String(MAXLEN = "", XMLNAME = "description") [ Required ];
......
......
}
So, when the invokeClient method is creating the SOAP Envelope, it looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:s='http://www.w3.org/2001/XMLSchema'>
<SOAP-ENV:Body>
<methodFind xmlns="http://customer.namespace.org/">
<idEspecialist xsi:type="s:string">TAC</idEspecialist>
<actList>
<act xmlns:s01="http://mywsservice.salutic.org/" xsi:type="s01:actoType">
<ActCode xsi:type="s:string">1032001</ActCode>
<description xsi:type="s:string">Torax</description>
</act>
</actList>
</methodFind>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Is there any way to change the namespace of the node programmatically?
Best regards,
Kurro López
I can't see your code to give specifics but when the client object is created it should have a %SOAP.SessionHeader that has a NAMESPACE property. It should be attached to the HeadersOut property of the SOAP.WebClient
This is all from memory though so you need to check.

Remove XML Namespaces from action Result

Using Web API and .NET Core and when I return an XML result I get the following:
<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Response>
<Status>0</Status>
</Response>
</Test>
How do I remove the namespaces?
Here's part of my startup.cs file
services
.AddMvc(config =>
{
// Add XML Content Negotiation
config.RespectBrowserAcceptHeader = true;
config.InputFormatters.Add(new XmlSerializerInputFormatter());
config.OutputFormatters.Add(new XmlSerializerOutputFormatter(new XmlWriterSettings
{
OmitXmlDeclaration = true,
}));
})
.AddXmlDataContractSerializerFormatters()
.AddXmlSerializerFormatters()
.AddMvcOptions(opt => opt.FormatterMappings.SetMediaTypeMappingForFormat("xml", new MediaTypeHeaderValue("application/xml")));
Both XmlSerializer and DataContractSerializer formatters look for Content-Type or Accept header values for application/xml and text/xml. So if you register both the first formatters its possible that only one formatter in them would take effect.
If you want to support XmlSerializer, then register only that formatter and if you want to support both for some reason, make sure to change the content-types they look for. Example: application/xml-dcs, text/xml-dcs, application/xml-xmlser, text/xml-ser
In case of above issue, DataContractSerializerOutputFormatter is probably writing out the response and hence you are not seeing it take effect.

Error validating Xml against Xsd Schema

I have the following Xml which I want to validate against Xsd Schema (below).
I am trying to validate the Xml against the given Xsd Schema using the C# function given below. I am getting this generic kind error message "Data at the root level is invalid. Line 1, position 1". This happens at "while(vr.Read())".
Can you please explain what is the cause and resolution to this problem or is there a way I can troubleshoot these type of generic errors.
As you can see from my Xsd schema that it has references to other child xsd files also. I am wondering if it has something to do with the error.
Warm Regards
XML File
<?xml version="1.0" encoding="utf-8"?>
<n1:Form109495CTransmittalUpstream xmlns="urn:us:gov:treasury:irs:ext:aca:air:6.2" xmlns:irs="urn:us:gov:treasury:irs:common" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:n1="urn:us:gov:treasury:irs:msg:form1094-1095Ctransmitterupstreammessage" xsi:schemaLocation="urn:us:gov:treasury:irs:msg:form1094-1095Ctransmitterupstreammessage IRS-Form1094-1095CTransmitterUpstreamMessage.xsd">
<Form1094CUpstreamDetail recordType="C" lineNum="0">
<--MORE XML TAGS HERE -->
</Form1094CUpstreamDetail>
</n1:Form109495CTransmittalUpstream>
XSD Schema
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="urn:us:gov:treasury:irs:msg:form1094-1095Ctransmitterupstreammessage"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:irs="urn:us:gov:treasury:irs:common"
xmlns:air6.2="urn:us:gov:treasury:irs:ext:aca:air:6.2"
targetNamespace="urn:us:gov:treasury:irs:msg:form1094-1095Ctransmitterupstreammessage"
elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">
<xsd:annotation>
<xsd:appinfo>
<release>ACA Release 6.2</release>
</xsd:appinfo>
<xsd:documentation>Form-1094C (Issuer) Transmittal and Form 1095C - Transmittal of Health Insurance Coverage Statements
<VersionNum>5.2</VersionNum>
<VersionEffectiveBeginDt>2015-01-06</VersionEffectiveBeginDt>
</xsd:documentation>
</xsd:annotation>
<!-- ===== Imports ===== -->
<xsd:import namespace="urn:us:gov:treasury:irs:common" schemaLocation="common-IRS-CAC.xsd"/>
<xsd:import namespace="urn:us:gov:treasury:irs:ext:aca:air:6.2"
schemaLocation="ext-IRS-EXT-ACA-AIR-6.2.xsd"/>
<xsd:element name="Form109495CTransmittalUpstream" type="Form109495CTransmittalUpstreamType">
<xsd:annotation>
<xsd:documentation>
<Component>
<DictionaryEntryNm>Form109495C Transmission Upstream</DictionaryEntryNm>
<MajorVersionNum>1</MajorVersionNum>
<MinorVersionNum>1</MinorVersionNum>
<VersionEffectiveBeginDt>2015-01-06</VersionEffectiveBeginDt>
<VersionDescriptionTxt>Initial Version</VersionDescriptionTxt>
<DescriptionTxt>The elements associated with 1094C data generated EOY report</DescriptionTxt>
</Component>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:complexType name="Form109495CTransmittalUpstreamType">
<xsd:annotation>
<xsd:documentation>
<Component>
<DictionaryEntryNm>Form109495C Transmission Upstream Type</DictionaryEntryNm>
<MajorVersionNum>1</MajorVersionNum>
<MinorVersionNum>1</MinorVersionNum>
<VersionEffectiveBeginDt>2014-11-05</VersionEffectiveBeginDt>
<VersionDescriptionTxt>Initial Version</VersionDescriptionTxt>
<DescriptionTxt>Transmission type for 1094C forms upstream data generated EOY report</DescriptionTxt>
</Component>
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element ref="air6.2:Form1094CUpstreamDetail" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Following is the C# Validation Function:
/// <SUMMARY>
/// This method validates an xml string against an xml schema.
/// </SUMMARY>
/// <PARAM name="xml">StringReader containing xml</PARAM>
/// <PARAM name="schemaNamespace">XML Schema Namespace</PARAM>
/// <PARAM name="schemaUri">XML Schema Uri</PARAM>
/// <RETURNS>bool</RETURNS>
public bool ValidXmlDoc(StringReader xml,
string schemaNamespace, string schemaUri)
{
// Continue?
if(xml == null || schemaNamespace == null || schemaUri == null)
{
return false;
}
isValidXml = true;
XmlValidatingReader vr;
XmlTextReader tr;
XmlSchemaCollection schemaCol = new XmlSchemaCollection();
schemaCol.Add(schemaNamespace, schemaUri);
try
{
// Read the xml.
tr = new XmlTextReader(xml);
// Create the validator.
vr = new XmlValidatingReader(tr);
// Set the validation tyep.
vr.ValidationType = ValidationType.Schema;
// Add the schema.
if(schemaCol != null)
{
vr.Schemas.Add(schemaCol);
}
// Set the validation event handler.
vr.ValidationEventHandler +=
new ValidationEventHandler(ValidationCallBack);
// Read the xml schema.
while(vr.Read())
{
}
vr.Close();
return isValidXml;
}
catch(Exception ex)
{
this.ValidationError = ex.Message;
return false;
}
finally
{
// Clean up...
vr = null;
tr = null;
}
}
AFAIK XmlValidatingReader is obsolete. I think you would be much better of using XmlReader. In order to control URI resolutions(should schema has references to other schemes as relative paths) you could create your own XML URL resolver class by inheriting from XmlUrlResolver and overriding ResolveUri method. Then assign it to the XmlResolver member of XmlReaderSettings class. But I hope things would not deteriorate to that, though.:) Hopefully.:) Here is schematic code I could suggest:
XmlTextReader reader = new XmlTextReader(pathToXSD);
XmlSchema schema = XmlSchema.Read(reader, ValidationEventHandler);
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationEventHandler);
settings.Schemas.Add(schema);
using (StringReader xmlStream = new StringReader(xml))
{
using (XmlReader xmlReader = XmlReader.Create(xmlStream, settings))
{
while (xmlReader.Read()) { }
}
}

Web API Help Pages and API Explorer returning 0 descriptions

I have this project that is just a Web API project. At some point in the past I removed the HelpPages and I made the app use OWIN.
Now I have been asked to add API HelpPages back in which I have done.
I have set my Startup class to look a bit like this:
public void Configuration(IAppBuilder app)
{
// Needs to be first
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
var httpConfig = new HttpConfiguration();
// Register all areas
AreaRegistration.RegisterAllAreas();
ConfigureOAuthTokenGeneration(app);
ConfigureOAuthTokenConsumption(app);
ConfigureWebApi(httpConfig);
app.UseWebApi(httpConfig);
}
So that my route for the help pages is working.
As far as I can tell, that should just work but the problem is that the ApiExplorer doesn't pull back any descriptions.
In my ConfigureWebApi method I remove formatting, I have commented that out but and still it doesn't work, here is the method:
private void ConfigureWebApi(HttpConfiguration config)
{
// Web API configuration and services
var formatters = config.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var serializerSettings = jsonFormatter.SerializerSettings;
// Remove XML formatting
formatters.Remove(config.Formatters.XmlFormatter);
jsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
jsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
// Configure our JSON output
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
serializerSettings.Formatting = Formatting.Indented;
serializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
serializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
I actually edited the HelpController and put a breakpoint on the return view line which is how I know the ApiExplorer has no descriptions:
public ActionResult Index()
{
var docProdivder = Configuration.Services.GetDocumentationProvider();
var desciptions = Configuration.Services.GetApiExplorer().ApiDescriptions;
ViewBag.DocumentationProvider = docProdivder;
return View(desciptions);
}
I read somewhere that if I do this:
public void Configuration(IAppBuilder app)
{
// Needs to be first
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
var httpConfig = new HttpConfiguration();
var exploerer = new ApiExplorer(httpConfig);
var descriptions = exploerer.ApiDescriptions;
// Register all areas
AreaRegistration.RegisterAllAreas();
ConfigureOAuthTokenGeneration(app);
ConfigureOAuthTokenConsumption(app);
ConfigureWebApi(httpConfig);
app.UseWebApi(httpConfig);
}
I should see the descriptions, but it still doesn't work.
So then I read somewhere else to set my project to output the xml description file and configure the HelpPageConfig file to use the documentProvider. I generated the Xml description file and can verify that my descriptions are in there, here is a snippet:
<member name="T:Melanite.Controllers.CollectionsController">
<summary>
Controller for all collection related functions
</summary>
</member>
<member name="M:Melanite.Controllers.CollectionsController.#ctor">
<summary>
Default constructor
</summary>
</member>
<member name="M:Melanite.Controllers.CollectionsController.Get(System.Int32)">
<summary>
Get all the collections for the given center
</summary>
<param name="centerId">The id of the center that the collection belongs to</param>
<returns>A list of collections</returns>
</member>
<member name="M:Melanite.Controllers.CollectionsController.Get(System.Int32,System.DateTime)">
<summary>
Get all the collections for the given center on a specific date
</summary>
<param name="centerId">The id of the center that the collection belongs to</param>
<param name="date">The planned collection date for the collections</param>
<returns>A list of collections</returns>
</member>
I uncommented out the lines in the HelpPageConfig like this:
// Uncomment the following to use the documentation from XML documentation file.
config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));
and made sure that the XML file was in the App_Data folder. The names are all correct, but when I run my project I still get no descriptions from the ApiExplorer.
So, as you can see I am at my wits end. I hope that someone has come across this before and knows how to fix it. If you do, please help!
I have the same problem. If I added
GlobalConfiguration.Configure(WebApiConfig.Register)
in Startup class (I don't use global.asax) everything worked properly. I hope this will help you, too.
If you don't have access to WebApiConfig.Register, which I didn't with my Owin WebApi project, the following code seems to work for me.
GlobalConfiguration.Configure((config) => { config.MapHttpAttributeRoutes(); });

Dynamic routing in camel en-queues messages infinitely

I am working on camel’s dynamic router to derive and dispatch to the relevant queue by referring http://camel.apache.org/dynamic-router.html
Following is the camel config xml:
<route id="dynamicRouter" autoStartup="true">
<from uri="vm://service1?concurrentConsumers=10&timeout=0" />
<choice>
<when>
<simple>${body.documentStatus} == 'SUCCESS' </simple>
<log message="routing to dynamic router" />
<dynamicRouter>
<!-- use a method call on a bean as dynamic router -->
<method ref="messageRouter" method="route" />
</dynamicRouter>
</when>
</choice>
</route>
Following is my dynamic router bean:
public class MessageRouter {
private static final String QUEUE_BROKER = "activemq";
private static final String DEFAULT_QUEUE = "queue";
/**
*
* #param obj
* message
* #return the dynamically generated queue name
*/
public String route(ServiceObject obj) {
RecordObject record = obj.getRecordObject();
if(record != null){
return QUEUE_BROKER + ":"
+ record.getId() + "." + DEFAULT_QUEUE;
}
return null;
}
}
I am able to en-queue messages in dynamically created queue but messages are getting enqueued infinitely. Any help in identifying what could be the reason would be of great help.
Thanks in advance!!!
Read the documentation about dynamic router at
http://camel.apache.org/dynamic-router.html
And see the beware box, it says the method must return null to signal to the dynamic router to break out.
So in your code above, then this code line
RecordObject record = obj.getRecordObject();
... the record object is never null and therefore the dynamic router keeps going forever.
If you only want this dynamic routing one time then use the dynamic receipient list eip instead, see
http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html
http://camel.apache.org/recipient-list.html
And your xml route is
<recipientList>
<!-- use a method call on a bean as dynamic router -->
<method ref="messageRouter" method="route" />
</recipientList>

Resources