How to create a site map using DNN and C# - c#

My website is http://www.bodytshirt.com
This site is built from DotNetNuke. It has default sitemap is http://www.bodytshirt.com/sitemap.aspx
This sitemap only shows the page URL without any parameters. I want my site map to show all product in my database. Such as http://www.bodytshirt.com/product/id/141/key/i-am-a-software-engineer
Please give my suggestion. Should I create a custom sitemap for my requirement?

You can do this with the Sitemap provider in DNN. My open source DNNSimpleArticle module has an example of this:
https://github.com/ChrisHammond/dnnsimplearticle/blob/6d5d2c5bb074dd2bdede40fac4eb3c78408ab884/Providers/Sitemap/Sitemap.cs
public override List<SitemapUrl> GetUrls(int portalId, PortalSettings ps, string version)
{
var listOfUrls = new List<SitemapUrl>();
foreach (Article ai in ArticleController.GetAllArticles(portalId))
{
var pageUrl = new SitemapUrl
{
Url = ArticleController.GetArticleLink(ai.TabID, ai.ArticleId),
Priority = (float)0.5,
LastModified = ai.LastModifiedOnDate,
ChangeFrequency = SitemapChangeFrequency.Daily
};
listOfUrls.Add(pageUrl);
}
return listOfUrls;
}
Then you will need to register that, you can do it with the .DNN file
https://github.com/ChrisHammond/dnnsimplearticle/blob/6d5d2c5bb074dd2bdede40fac4eb3c78408ab884/dnnsimplearticle.dnn
<component type="Config">
<config>
<configFile>web.config</configFile>
<install>
<configuration>
<nodes>
<node path="/configuration/dotnetnuke/sitemap/providers" action="update" key="name" collision="overwrite">
<add name="DNNSimpleArticleSiteMapProvider" type="Christoc.Modules.dnnsimplearticle.Providers.Sitemap.Sitemap, DNNSimpleArticle" providerPath="~\DesktopModules\dnnsimplearticle\Providers\Sitemap\" />
</node>
</nodes>
</configuration>
</install>
<uninstall>
<configuration>
<nodes />
</configuration>
</uninstall>
</config>
</component>

Related

How can I add a HttpModule in ApplicationHost.config for all websites on IIS Server from C#?

I am trying something like
public string[] RegisterInApplicationConfig()
{
using (ServerManager serverManager = new ServerManager())
{
Configuration config = serverManager.GetApplicationHostConfiguration();
var section = config.GetSection("location/system.webServer/modules");
}
}
but error I am getting is -
The configuration section location/system.webServer/modules cannot be read because it is missing a section declaration.
I am referring post from to add HttpModule -
How do I register a HttpModule in the machine.config for IIS 7?
So Basically in ApplicationHostConfig I need to get to
<location path="" overrideMode="Allow">
<system.webServer>
<modules>
<add name="IsapiFilterModule" lockItem="true" />
So I found the solution after some hit & trials. Might help someone in future-
I needed to do GetCollection on "system.webServer/modules" section
Configuration config = serverManager.GetApplicationHostConfiguration();
var section = config.GetSection("system.webServer/modules", "");
var collection = section.GetCollection();
var element = collection.CreateElement();
element.Attributes["name"].Value = "MyHttpModule";
element.Attributes["type"].Value = MyHttpModule.XXXModule, MyHttpModule, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bc88fbd2dc8888795";
collection.Add(element);
serverManager.CommitChanges();

How to read custom section data in web.config with minimum code

here is my custom section in web.config. now i want read data by c#
<configuration>
<MailList>
<MailID id="test-uk#mysite.com" Value="UK" />
<MailID id="test-us#mysite.com" Value="US" />
<MailID id="test-ca#mysite.com" Value="CA" />
</databases>
</configuration>
suppose i want technique by which i can only read data based on value. if i supply UK as value then function will return uk mail id test-uk#mysite.com.
guide me how easily i can do this writing very minimum code. thanks
First of all your XML seems to be broken:
It must be something like that:
<configuration>
<MailList>
<MailID id="test-uk#mysite.com" Value="UK" />
<MailID id="test-us#mysite.com" Value="US" />
<MailID id="test-ca#mysite.com" Value="CA" />
</MailList>
</configuration>
This code should do what you want:
string country = "UK";
var result =
XDocument.Load("~/web.config")
.Element("configuration")
.Element("MailList")
.Elements("MailID")
.First(el => el.Attribute("Value").Value.Equals(country))
.Attribute("id")
.Value;
Console.WriteLine(result);
You could use the appsettings tag in your webconfig like:
<configuration>
<appSettings>
<add key="test-uk#mysite.com" value="UK" />
<add key="test-us#mysite.com" value="US" />
<add key="test-ca#mysite.com" value="CA" />
And after that you have your class:
public class WebConfigreader
{
public static string AppSettingsKey(string key)
{
if (WebConfigurationManager.AppSettings != null)
{
object xSetting = WebConfigurationManager.AppSettings[key];
if (xSetting != null)
{
return (string)xSetting;
}
}
return "";
}
}
And in your logic you are calling just:
String strUk = WebConfigreader.AppSettingsKey("test-uk#mysite.com");

Wrong wsdl URL in webservice.asmx?disco when proxy is use

My application is running on a Windows server in the intra net. Application URL is like this: win_serv/APP_DIR/. And webserwice.asmx URL is a "win_serv/APP_DIR/webservice.asmx"
Public application URL is like this: app.domain.com (APP_DOMAIN) and public Webservice.asmx URL is like this APP_DOMAIN/webservice.asmx.
In this configuration auto generated discovery XML (APP_DOMAIN/webservice.asmx?disco) is like this:
<?xml version="1.0" encoding="utf-8"?>
<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
<contractRef ref="http://APP_DOMAIN/APP_DIR/webservice.asmx?wsdl" docRef="http://APP_DOMAIN/APP_DIR/webservice.asmx" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<soap address="http://APP_DOMAIN/APP_DIR/webservice.asmx" xmlns:q1="http://NAMESPACE/" binding="q1:WebServiceSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
<soap address="http://APP_DOMAIN/APP_DIR/webservice.asmx" xmlns:q2="http://NAMESPACE/" binding="q2:WebServiceSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
</discovery>
So I used class SoapExtensionReflector:
public override void ReflectDescription()
{
ServiceDescription description = ReflectionContext.ServiceDescription;
foreach (Service service in description.Services)
{
foreach (Port port in service.Ports)
{
foreach (ServiceDescriptionFormatExtension extension in port.Extensions)
{
SoapAddressBinding binding = extension as SoapAddressBinding;
if (null != binding)
{
binding.Location = ConfigurationManager.AppSettings["SoapAddress"]; //http://APP_DOMAIN/webservice.asmx
}
}
}
}
}
But this solution fixes only soap address is valid (http://APP_DOMAIN/webservice.asmx). WSDL URL is still invalid (http://APP_DOMAIN/APP_DIR/webservice.asmx?wsdl). Discovery looks like this:
<?xml version="1.0" encoding="utf-8"?>
<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
<contractRef ref="http://APP_DOMAIN/APP_DIR/webservice.asmx?wsdl" docRef="http://APP_DOMAIN/APP_DIR/webservice.asmx" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<soap address="http://APP_DOMAIN/webservice.asmx" xmlns:q1="http://NAMESPACE/" binding="q1:WebServiceSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
<soap address="http://APP_DOMAIN/webservice.asmx" xmlns:q2="http://NAMESPACE/" binding="q2:WebServiceSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
</discovery>
How to fix wsdl URL?
p.s. sorry for my english

WebService behind reverse proxy

I have a web service which is behind a reverse proxy like this:
Now what is happening is when I try to add a web reference to test the web service then it says that it is unable to download the wsdl file. That is because when the request is sent it it is https://uat.mywebservice.com/Service/Service.asmx but when it hits the reverse proxy and then tires to download the wsdl and disco files it changes the link to http://myservice.comp.com/Service/Service.asmx?wsdl and this is not the right link as myservice.comp.com is just a name space on reverse proxy.
What is happening is headers in the soap file are getting updated to this namespace instead of the actual host name which is uat.mywebservice.com, I was able to see this using fiddler disco file has incorrect address. I had a worked out by creating a proxy class using wsdl.exe tool and then updated all the incorrect links in that class to right host name.
Is there any way that I can make sure the address remains correct when hitting the reverse proxy.
Incorrect:   mywebservice.comp.com
<?xml version="1.0" encoding="utf-8" ?>
<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
<contractRef ref="http://mvwebservice.comp.com/Service/Service.asmx?wsdl" docRef="http://mvwebservice.comp.com/Service/Service.asmx" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<soap address="http://mywebservice.comp.com/Service/Service.asmx" xmlns:q1="http://tempuri.org/" binding="q1:ServiceSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
<soap address="http://mywebservice.comp.com/Service/Service.asmx" xmlns:q2="http://tempuri.org/" binding="q2:ServiceSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
</discovery>
Correct:   uat.mywebservice.com
<?xml version="1.0" encoding="utf-8" ?>
<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
<contractRef ref="https://uat.mvwebservice.com/Service/Service.asmx?wsdl" docRef="https://uat.mvwebservice.com/Service/Service.asmx" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<soap address="https://uat.mywebservice.com/Service/Service.asmx" xmlns:q1="http://tempuri.org/" binding="q1:ServiceSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
<soap address="https://uat.mywebservice.com/Service/Service.asmx" xmlns:q2="http://tempuri.org/" binding="q2:ServiceSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
</discovery>
What I did to solve a similar problem was to force the webservice to emit the correct headers.
You can do the following:
Create the following class in the App_Code folder:
using System;
using System.Web.Services.Description;
namespace Msdn.Web.Services.Samples
{
/// <summary> Summary description for WSDLReflector </summary>
public class WSDLReflector : SoapExtensionReflector
{
public override void ReflectMethod()
{
//no-op
}
public override void ReflectDescription()
{
ServiceDescription description = ReflectionContext.ServiceDescription;
foreach (Service service in description.Services)
{
foreach (Port port in service.Ports)
{
foreach (ServiceDescriptionFormatExtension extension in port.Extensions)
{
SoapAddressBinding binding = extension as SoapAddressBinding;
if (null != binding)
{
binding.Location = binding.Location.Replace("http://mywebservice.comp.com", "https://uat.mywebservice.com");
}
}
}
}
}
}
}
And add this to web.config:
<webServices>
<diagnostics suppressReturningExceptions="true" />
<soapExtensionReflectorTypes>
<add type="Msdn.Web.Services.Samples.WSDLReflector,App_Code"/>
</soapExtensionReflectorTypes>
</webServices>

RIA Service/oData ... "Requests that attempt to access a single element using key values from a result set are not supported."

I've recently started working up a sample project to play with an oData feed coming from a RIA service. I am able to view the feed and the metadata via any web browser, however, if I try to perform certain query operations on the feed I receive "unsupported" exceptions.
Sample oData feed:
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<feed
xml:base="http://localhost:50880/Services/
Rebirth-Web-Services-ProductService.svc/OData/"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
<title type="text">ProductSet</title>
<id>http://localhost:50880/Services/
Rebirth-Web-Services-ProductService.svc/OData/ProductSet/</id>
<updated>2010-04-28T14:02:10Z</updated>
<link rel="self" title="ProductSet" href="ProductSet" />
<entry>
<id>http://localhost:50880/Services/
Rebirth-Web-Services-ProductService.svc/OData/ProductSet
(guid'b0a2b170-c6df-441f-ae2a-74dd19901128')</id>
<title type="text"></title>
<updated>2010-04-28T14:02:10Z</updated>
<author>
<name />
</author>
<link rel="edit" title="Product"
href="ProductSet(guid'b0a2b170-c6df-441f-ae2a-74dd19901128')" />
<category term="Rebirth.Web.Models.Product"
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:Id m:type="Edm.Guid">b0a2b170-c6df-441f-ae2a-74dd19901128</d:Id>
<d:Name>Product 0</d:Name>
<d:ProductType>Type 1</d:ProductType>
<d:Status>Active</d:Status>
</m:properties>
</content>
</entry>
Sample web.config entry:
<add name="OData"
type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory,
System.ServiceModel.DomainServices.Hosting.OData,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
Sample service:
[EnableClientAccess()]
public class ProductService : DomainService {
[Query(IsDefault = true)]
public IQueryable<Product> GetProducts() {
IList<Product> products = new List<Product>();
for (int i = 0; i < 90; i++) {
Product product = new Product {
Id = Guid.NewGuid(),
Name = "Product " + i.ToString(),
ProductType = i < 30 ? "Type 1" :
((i > 30 && i < 60) ? "Type 2" : "Type 3"),
Status = i % 2 == 0 ? "Active" : "NotActive"
};
products.Add(product);
}
return products.AsQueryable();
}
}
If I provide the url "http://localhost:50880/Services/Rebirth-Web-Services-ProductService.svc/OData/ProductSet(guid'b0a2b170-c6df-441f-ae2a-74dd19901128')" to my web browser I receive the following xml:
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code/>
<message xml:lang="en-US"
xmlns:xml="http://www.w3.org/XML/1998/namespace">
Requests that attempt to access a single element using key values
from a result set are not supported.
</message>
</error>
I'm new to RIA and oData. Could this be something as simple as my web browsers not supporting this type of querying on the result set or something else?
EDIT: This is what I see in LinqPad:
Member qRuntimeMethodInfo
QueryResult.Execute ()
StackTrace
at System.Data.Services.Client.QueryResult.Execute()
at System.Data.Services.Client.DataServiceRequest.Execute[TElement]
(DataServiceContext context, QueryComponents queryComponents)
Refer here: RIA Services OData "Query options are not allowed."
It still not implemented in 2010 SP1. Just checked.

Categories