I build a WCF service with [XmlSerializerFormat] infrastructure. Each model component has multiple attributes ([XmlAttribute] annotations). How can i mark as required for "string" attributes in definition XSD.
Current model sample:
public partial class Header1Type : HeaderType
{
private string mSRefIdField;
private string sSNRefIdField;
private StatusCodeEnumType statusCodeField;
private string statusMessageField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string MSRefId
{
get
{
return this.mSRefIdField;
}
set
{
this.mSRefIdField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string SSNRefId
{
get
{
return this.sSNRefIdField;
}
set
{
this.sSNRefIdField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public StatusCodeEnumType StatusCode
{
get
{
return this.statusCodeField;
}
set
{
this.statusCodeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string StatusMessage
{
get
{
return this.statusMessageField;
}
set
{
this.statusMessageField = value;
}
}
}
Current wsdl definition:
<xs:complexType name="Header1Type">
<xs:complexContent mixed="false">
<xs:extension base="tns:HeaderType">
<xs:attribute name="MSRefId" type="xs:string"/>
<xs:attribute name="SSNRefId" type="xs:string"/>
<xs:attribute name="StatusCode" type="tns:StatusCodeEnumType" use="required"/>
<xs:attribute name="StatusMessage" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
I need string attributes to be decorated with use="required"
Related
Recently, I am occasionally facing an error at my AuthorizationPolicyProvider class:
public class AuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider
{
private readonly AuthorizationOptions options;
public AuthorizationPolicyProvider(IOptions<AuthorizationOptions> options)
: base(options)
{
this.options = options.Value;
}
/// this method is supposed to be the place where the error arises
public override async Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
AuthorizationPolicy policy = await base.GetPolicyAsync(policyName);
if (policy == null)
{
policy = new AuthorizationPolicyBuilder()
.AddRequirements(new PermissionRequirement(policyName))
.Build();
this.options.AddPolicy(policyName, policy);
}
return policy;
}
}
Here is some of the error stack:
System.NullReferenceException:
at System.Collections.Generic.Dictionary`2.TryInsert (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Collections.Generic.Dictionary`2.set_Item (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Authorization.AuthorizationOptions.AddPolicy (Microsoft.AspNetCore.Authorization, Version=3.1.6.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
.....
Based on the error stack, I have a guess that the error might be caused by multithreads problem of Dictionary, because the implementation of AuthorizationOptions use Dictionary, instead of ConcurrentDictionary:
namespace Microsoft.AspNetCore.Authorization
{
/// <summary>
/// Provides programmatic configuration used by <see cref="IAuthorizationService"/> and <see cref="IAuthorizationPolicyProvider"/>.
/// </summary>
public class AuthorizationOptions
{
// Why dont they use ConcurrentDictionary here
private IDictionary<string, AuthorizationPolicy> PolicyMap { get; } = new Dictionary<string, AuthorizationPolicy>(StringComparer.OrdinalIgnoreCase);
....
public AuthorizationPolicy GetPolicy(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
return PolicyMap.ContainsKey(name) ? PolicyMap[name] : null;
}
}
}
And I follow the guide of Microsoft in: link and add the custom AuthorizationPolicyProvider as Singleton:
services.AddSingleton<IAuthorizationPolicyProvider, AuthorizationPolicyProvider>();
So do you guys know why dont they use ConcurrentDictionary, is it a bug from Microsoft, or because of my implementation, thank you.
Do it yourself :
public class DynamicAuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider
{
private ConcurrentDictionary<string, AuthorizationPolicy> DynamicPolicyMap { get; } = new ConcurrentDictionary<string, AuthorizationPolicy>(StringComparer.OrdinalIgnoreCase);
public DynamicAuthorizationPolicyProvider(IOptions<AuthorizationOptions> options) : base(options)
{
}
public override async Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
AuthorizationPolicy policy = await base.GetPolicyAsync(policyName);
if (policy == null)
{
return DynamicPolicyMap.GetOrAdd(policyName, CreateDynamicPolicy);
}
return policy;
}
private AuthorizationPolicy CreateDynamicPolicy(string policyName)
{
}
}
I have a class that I am serializing
public partial class Security : MessageHeader
{
private Assertion assertionField;
[System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:oasis:names:tc:SAML:2.0:assertion")]
public Assertion Assertion
{
get
{
return this.assertionField;
}
set
{
this.assertionField = value;
}
}
public override string Name
{
get { return "Security"; }
}
public override string Namespace
{
get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
}
[XmlIgnoreAttribute]
public string UserID { get; set; }
[XmlIgnoreAttribute]
public string FirstName { get; set; }
[XmlIgnoreAttribute]
public string LastName { get; set; }
[XmlIgnoreAttribute]
public string ReasonForSearch { get; set; }
public Security()
{
Assertion = new Assertion(UserID, FirstName, LastName, ReasonForSearch);
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
XmlSerializer serializer = new XmlSerializer(typeof(Assertion));
serializer.Serialize(writer, Assertion, ns);
}
}
this is how i am adding code header
using (OperationContextScope scope = new OperationContextScope(healthixClient.InnerChannel))
{
Security msgHdr = new Security();
msgHdr.UserID = "TestUserID";
msgHdr.FirstName = "TestUserFirstName";
msgHdr.LastName = "TestUserLastName";
msgHdr.ReasonForSearch = "ReasonForSearch";
OperationContext.Current.OutgoingMessageHeaders.Add(msgHdr);
}
when i serialize this and add in my code header it looks like this
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<saml:Assertion ID="saml_6691a2b1-2a08-4d10-9d90-b006727d0e02" IssueInstant="2013-09-09T15:38:16Z" Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
< rest of the Xml is correct >
Now if I only change my override OnWriteHeaderContents method to
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
XmlSerializer serializer = new XmlSerializer(typeof(Security));
serializer.Serialize(writer, new Security(), ns);
}
the header looks like this
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<Security xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Assertion ID="saml_6691a2b1-2a08-4d10-9d90-b006727d0e02" IssueInstant="2013-09-09T15:29:09Z" Version="2.0">
< rest of the Xml is correct >
What i want the header to look like is this
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Assertion ID="saml_6691a2b1-2a08-4d10-9d90-b006727d0e02" IssueInstant="2013-07-29T20:17:30.846Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
Try this option in OnWriteHeaderContents method
writer.WriteStartElement("saml", "Assertion", "urn:oasis:names:tc:SAML:2.0:assertion");
writer.WriteString("Value");
writer.WriteEndElement();
I have found a dozen of question similar to mine but none of them offered a solution to my problem.
Thank you in advance
Ok,
I have this class
public class User : IEntity
{
private int id;
public virtual int Id { get { return id; } }
private string email;
public virtual string Email
{
get { return email; }
//private set { email = value; }
}
private string password;
public virtual string Password
{
get { return password; }
//private set { password = value; }
}
private bool isActive;
public virtual bool IsActive
{
get { return isActive; }
//private set { isActive = value; }
}
private bool isRegistered;
public virtual bool IsRegistered
{
get { return isRegistered; }
//private set { isRegistered = value; }
}
private bool hasRequestedApplication;
public virtual bool HasRequestedApplication
{
get { return hasRequestedApplication; }
//private set { hasRequestedApplication = value; }
}
private ContactInfo contactInformation;
public virtual ContactInfo ContactInformation
{
get { return contactInformation; }
//private set { contactInformation = value; }
}
public User(string email)
{
this.email = email;
}
public User(string email, string password):this(email)
{
this.password = password;
}
public User()
{ }
}
this is the mapping....
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain"
namespace="Domain.User" default-access="field">
<class name="User" table="[User]">
<id name="id" column="UserID">
<generator class="identity" />
</id>
<property name="email" column="Email" not-null="true"></property>
<property name="password" column="HashedPassword" not-null="false"></property>
<property name="isRegistered" column="IsRegistered" not-null="true"></property>
<property name="isActive" column="IsActive" not-null="true"></property>
<property name="hasRequestedApplication" column="HasRequestedApplication" not-null="true"></property>
<one-to-one name="contactInformation" class="Domain.User.ContactInfo"/>
</class>
</hibernate-mapping>
and this is how i am calling it
public class UserRepository: IUserRepository
{
Func<ISession> session;
public UserRepository(Func<ISession> _session)
{
session = _session;
}
[Transaction]
public User FindByEmail(string emailAddress)
{
using (var tx = session())
{
return tx.QueryOver<User>().Where(u => u.Email == emailAddress).SingleOrDefault();
}
}
}
Error...
{"could not resolve property: Email of: Domain.User.User"}
StackTrace...
at NHibernate.Persister.Entity.AbstractPropertyMapping.ToType(String propertyName)
at NHibernate.Persister.Entity.AbstractEntityPersister.GetSubclassPropertyTableNumber(String propertyPath)
at NHibernate.Persister.Entity.BasicEntityPropertyMapping.ToColumns(String alias, String propertyName)
at NHibernate.Persister.Entity.AbstractEntityPersister.ToColumns(String alias, String propertyName)
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumns(ICriteria subcriteria, String propertyName)
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumnsUsingProjection(ICriteria subcriteria, String propertyName)
at NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingPropertyName(ICriteriaQuery criteriaQuery, ICriteria criteria, String propertyName, Object value, ICriterion critertion)
at NHibernate.Criterion.SimpleExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary2 enabledFilters)
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary2 enabledFilters)
at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary2 enabledFilters)
at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary2 enabledFilters)
at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results)
at NHibernate.Impl.CriteriaImpl.List(IList results)
at NHibernate.Impl.CriteriaImpl.UniqueResultT
at NHibernate.Criterion.QueryOver1.SingleOrDefault()
at NHibernate.Criterion.QueryOver1.NHibernate.IQueryOver.SingleOrDefault()
at DataObjects.NHibernate.UserRepository.FindByEmail(String emailAddress) in E:\Projects\DataObjects.NHibernate\UserRepository.cs:line 26
at Castle.Proxies.Invocations.IUserRepository_FindByEmail.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Facilities.AutoTx.TransactionInterceptor.SynchronizedCase(IInvocation invocation, ITransaction transaction) in d:\BuildAgent-03\work\9844bdf039249947\src\Castle.Facilities.AutoTx\TransactionInterceptor.cs:line 137
EDIT:
OK. Solved to some extent. I changed all my properties and components name to capital in my mapping.
Instead of...
<property name="email" column="emailaddress" />
set it to...
<property name="Email" column="emailaddress" />
and it works. Now, is that a guarantee that NHibernate is populating/reading my properties via the fields? I hope so.
This should help: Change the settings to be different for get and set
<hibernate-mapping ... default-access="field.camelcase">
and map the properties:
<property name="Email" column="emailaddress" />
NHibernate will use field for set and the Property for get. This QueryOver:
return tx.QueryOver<User>()
.Where(u => u.Email == emailAddress)
.SingleOrDefault();
...will work now
I believe the "name" of the properties in your mapping should match the case of the public virtual properties in your class. Try changing <property name="email"... to <property name="Email"... and so on.
This is the full code for mapping of the tables I am doing. But dont know why I am getting
java heap space error. I am using Jboss server and the exact error message is java.lang.OutOfMemoryError: Java heap space.
package com.mercer.chat.app.dataobject;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class MHRContChatSessionDO {
private Long id;
private String chatBucketHeadline;
private String preChatLongHeadline;
private String postChatLongHeadline;
private String preChatSummary;
private String postChatSummary;
private String chatBucketImage;
private String chatLogPath;
private Integer roomId;
private List<MHRContChatAlertsDO> chatAlerts;
public MHRContChatSessionDO() {
super();
}
public MHRContChatSessionDO(Long id, String chatBucketHeadline, String preChatLongHeadline,
String postChatLongHeadline, String preChatSummary, String postChatSummary, String chatBucketImage,
String chatLogPath,Integer roomId, List<MHRContChatAlertsDO> chatAlerts) {
super();
this.id = id;
this.chatBucketHeadline = chatBucketHeadline;
this.preChatLongHeadline = preChatLongHeadline;
this.postChatLongHeadline = postChatLongHeadline;
this.preChatSummary = preChatSummary;
this.postChatSummary = postChatSummary;
this.chatBucketImage = chatBucketImage;
this.chatLogPath = chatLogPath;
this.roomId = roomId;
this.chatAlerts = chatAlerts;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getChatBucketHeadline() {
return chatBucketHeadline;
}
public void setChatBucketHeadline(String chatBucketHeadline) {
this.chatBucketHeadline = chatBucketHeadline;
}
public String getPreChatLongHeadline() {
return preChatLongHeadline;
}
public void setPreChatLongHeadline(String preChatLongHeadline) {
this.preChatLongHeadline = preChatLongHeadline;
}
public String getPostChatLongHeadline() {
return postChatLongHeadline;
}
public void setPostChatLongHeadline(String postChatLongHeadline) {
this.postChatLongHeadline = postChatLongHeadline;
}
public String getPreChatSummary() {
return preChatSummary;
}
public void setPreChatSummary(String preChatSummary) {
this.preChatSummary = preChatSummary;
}
public String getPostChatSummary() {
return postChatSummary;
}
public void setPostChatSummary(String postChatSummary) {
this.postChatSummary = postChatSummary;
}
public String getChatBucketImage() {
return chatBucketImage;
}
public void setChatBucketImage(String chatBucketImage) {
this.chatBucketImage = chatBucketImage;
}
public String getChatLogPath() {
return chatLogPath;
}
public void setChatLogPath(String chatLogPath) {
this.chatLogPath = chatLogPath;
}
public Integer getRoomId() {
return roomId;
}
public void setRoomId(Integer roomId) {
this.roomId = roomId;
}
public List<MHRContChatAlertsDO> getChatAlerts() {
return chatAlerts;
}
public void setChatAlerts(List<MHRContChatAlertsDO> chatAlerts) {
this.chatAlerts = chatAlerts;
}
}
public class MHRContChatAlertsDO implements Serializable {
private Long id;
private String userId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public MHRContChatAlertsDO() {
}
public MHRContChatAlertsDO(Long id,String userId) {
this.id=id;
this.userId=userId;
}
#Override
public boolean equals(Object arg0) {
if(arg0 == null) return false;
if(!(arg0 instanceof MHRContChatAlertsDO)) return false;
MHRContChatAlertsDO arg1 = (MHRContChatAlertsDO) arg0;
return (this.id.longValue() == arg1.getId().longValue()) && (this.userId.equals(arg1.getUserId()) );
}
#Override
public int hashCode() {
int hsCode;
hsCode = id.hashCode();
hsCode = 19 * hsCode+ userId.hashCode();
return hsCode;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-lazy="true">
<class name="com.mercer.chat.app.dataobject.MHRContChatSessionDO"
table="QA_TEST2">
<cache usage="read-only" include="all"/>
<id name="id" type="java.lang.Long">
<column name="ID_CHAT_SESSION" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="chatBucketHeadline" type="string">
<column name="CHAT_BUCKET_HEADLINE" />
</property>
<property name="preChatLongHeadline" type="string">
<column name="PRE_CHAT_LONGHEADLINE" scale="0" />
</property>
<property name="postChatLongHeadline" type="string">
<column name="POST_CHAT_LONGHEADLINE" />
</property>
<property name="preChatSummary" type="string">
<column name="PRE_CHAT_SUMMARY" />
</property>
<property name="postChatSummary" type="string">
<column name="POST_CHAT_SUMMARY" not-null="true" />
</property>
<property name="chatBucketImage" type="string">
<column name="CHAT_BUCKET_IMAGE_PATH" />
</property>
<property name="chatLogPath" type="string">
<column name="CHAT_LOG_PATH" />
</property>
<property name="roomId" type="java.lang.Integer">
<column name="ROOM_ID" scale="0" />
</property>
<list name="chatAlerts" batch-size="5" cascade="all" lazy="false">
<cache usage="read-only" include="all" />
<key column="ID_CHAT_SESSION" />
<list-index column="ID_USER" />
<one-to-many
class="com.mercer.chat.app.dataobject.MHRContChatAlertsDO" />
</list>
</class>
</hibernate-mapping>
<hibernate-mapping default-lazy="true">
<class name="com.mercer.chat.app.dataobject.MHRContChatAlertsDO" table="QA_TEST3">
<cache usage="read-only" include="all" />
<composite-id >
<key-property name="id" type="java.lang.Long">
<column name="ID_CHAT_SESSION" precision="22" scale="0" />
</key-property>
<key-property name="userId" type="string">
<column name="ID_USER" />
</key-property>
</composite-id>
</class>
</hibernate-mapping>
Following is the wsdl file of my service:
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://localhost:3789/VideoUpload.svc?xsd=xsd0" namespace="http://tempuri.org/" />
<xsd:import schemaLocation="http://localhost:3789/VideoUpload.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xsd:import schemaLocation="http://localhost:3789/VideoUpload.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/UploadVideoProtocol" />
</xsd:schema>
</wsdl:types>
-----
<wsdl:definitions>
<wsdl:service name="VideoUpload">
<wsdl:port name="BasicHttpBinding_IVideoUpload" binding="tns:BasicHttpBinding_IVideoUpload">
<soap:address location="http://localhost:3789/VideoUpload.svc" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
In the above, I could change the namespace by specifying the custom namespace inside the code in service contract and behavior.
But I need to change the endpoint address specified in the schema location,
schemaLocation="http://localhost:3789/VideoUpload.svc?xsd=xsd0"
To my own defined endpoint address as:
schemaLocation="http://myservice.com:8080/VideoUpload.svc?xsd=xsd0"
What is the procedure to achieve this? what has to be mentioned in the code to change the default endpoint generated? Can anyone please help me on this?
You could dynamically update the WCF endpoint address in the WSDL meta data by adding a new behavior that implements "IWsdlExportExtension"
public class HostNameAddressBehavior : Attribute, IWsdlExportExtension, IEndpointBehavior, IServiceBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint,
ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
public void AddBindingParameters(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
{
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
public void ExportContract(WsdlExporter exporter,
WsdlContractConversionContext context)
{
}
/// <summary>
/// Overwrite service meta data
/// </summary>
/// <param name="exporter"></param>
/// <param name="context"></param>
public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
{
var address = "YOUR_ENDPOINT";
context.Endpoint.Address = new System.ServiceModel.EndpointAddress(address);
XmlSchemaSet schemaSet = exporter.GeneratedXmlSchemas;
foreach (System.Web.Services.Description.ServiceDescription wsdl in exporter.GeneratedWsdlDocuments)
{
foreach (XmlSchema schema in wsdl.Types.Schemas)
{
ChangeSchemaLocation(schemaSet, schema, address);
}
}
}
/// <summary>
/// Update XSD location
/// </summary>
/// <param name="xmlSchemaSet"></param>
/// <param name="xsdDoc"></param>
/// <param name="address"></param>
private void ChangeSchemaLocation(XmlSchemaSet xmlSchemaSet, XmlSchema xsdDoc, string address)
{
foreach (XmlSchemaExternal external in xsdDoc.Includes)
{
if ((external != null) && string.IsNullOrEmpty(external.SchemaLocation))
{
string str = (external is XmlSchemaImport) ? ((XmlSchemaImport)external).Namespace : xsdDoc.TargetNamespace;
foreach (XmlSchema schema in xmlSchemaSet.Schemas(str ?? string.Empty))
{
if (schema != xsdDoc)
{
external.SchemaLocation = address + "/?xsd=xsd0"; // set the location;
break;
}
}
continue;
}
}
}
}
Add your new behavior by code or in the config file.
By code:
var endpoint = listener.ServiceHost.Description.Endpoints.First();
endpoint.Behaviors.Add(new HostNameAddressBehavior());
OR
By Config:
Create extension:
public class HostNameAddressBehaviorExtension : BehaviorExtensionElement
{
public override Type BehaviorType
{
get
{
return typeof(HostNameAddressBehavior);
}
}
protected override object CreateBehavior()
{
return new HostNameAddressBehavior();
}
}
Then add:
<extensions>
<behaviorExtensions>
<add name="hostNameAddress" type="YourService.HostNameAddressBehaviorExtension, YourService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>