kabul yanıta bakın. Çok fazla iş gibi görünebilir, ancak gerçekten okuyamıyor ve okumanız çok mantıklı. Sorunun özü, unresolved bug (.NET 4'ten itibaren) olduğundan, WebServiceHost özel QueryStringConverters kullanmadığı anlamına gelir. Bu yüzden biraz fazladan çalışmaya ihtiyaç duyuyorsunuz ve WebHttpEndpoints için WCF yapılandırmasının nasıl çalıştığını anlıyorsunuz. Aşağıda sizin için çözüm yatıyor.
Öncelikle nulls boş dize bunları ihmal ya sağlayarak sorgu dizesinde sağlanacak olanak sağlayan özel QueryStringConverter:
public class NullableQueryStringConverter : QueryStringConverter
{
public override bool CanConvert(Type type)
{
var underlyingType = Nullable.GetUnderlyingType(type);
return (underlyingType != null && base.CanConvert(underlyingType)) || base.CanConvert(type);
}
public override object ConvertStringToValue(string parameter, Type parameterType)
{
var underlyingType = Nullable.GetUnderlyingType(parameterType);
// Handle nullable types
if (underlyingType != null)
{
// Define a null value as being an empty or missing (null) string passed as the query parameter value
return String.IsNullOrEmpty(parameter) ? null : base.ConvertStringToValue(parameter, underlyingType);
}
return base.ConvertStringToValue(parameter, parameterType);
}
}
Şimdi özel WebHttpBehavior özel ayarlar Standart olan yerine kullanılacak QueryStringConverter. Not biz REST son nokta için gerekli davranışı devralması için önemlidir WebHttpBehaviorbu davranış derivces: bu yüzden o WebHttpEndpoint özel davranışı ekler
public class NullableWebHttpBehavior : WebHttpBehavior
{
protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
{
return new NullableQueryStringConverter();
}
}
Şimdi özel ServiceHost Özel QueryStringConverter kullanır.Bu kodda dikkat edilmesi gereken önemli nokta, ServiceHost ve WebServiceHost'dan türetilmesidir. Biz türeyen olmadığından
public sealed class NullableWebServiceHost : ServiceHost
{
public NullableWebServiceHost()
{
}
public NullableWebServiceHost(object singletonInstance, params Uri[] baseAddresses) : base(singletonInstance, baseAddresses)
{
}
public NullableWebServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses)
{
}
protected override void OnOpening()
{
if (this.Description != null)
{
foreach (var endpoint in this.Description.Endpoints)
{
if (endpoint.Binding != null)
{
var webHttpBinding = endpoint.Binding as WebHttpBinding;
if (webHttpBinding != null)
{
endpoint.Behaviors.Add(new NullableWebHttpBehavior());
}
}
}
}
base.OnOpening();
}
}
bunu bir iş yapmak ve bizim yapılandırma için doğru olduğundan emin olmak gerekir WebServiceHost: Aksi yukarıda belirtilen hata kullanılmaktan özel QueryStringConverter önleyecektir Bu önemlidir, çünkü REST servisinin çalışacağından emin olun. İhtiyacınız olan şey aşağıdaki gibi bir şey. Bu yapılandırmada, her iki C# (WS HTTP'yi daha güzel kullanarak) ve mobil aygıtlardan (REST kullanarak) bu hizmete erişmem gerektiğinden, bir WS HTTP son nokta kurulumuna da sahibim. İhtiyacınız yoksa, bu son nokta için yapılandırmayı atlayabilirsiniz. Dikkat edilmesi gereken önemli bir nokta, artık özel uç nokta davranışına ihtiyaç duymamanızdır. Bu, artık özel QueryStringConverter'u bağlayan kendi özel son nokta davranışımızı eklediğimiz içindir. Yapılandırmanın eklendiği WebHttpBehavior'dan türetilmiştir, bu da artık yedekli hale gelmektedir.
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyNamespace.Service1">
<endpoint binding="webHttpBinding" bindingConfiguration="WebHttpBinding" contract="MyNamespace.IService1" />
<endpoint address="ws" binding="wsHttpBinding" bindingConfiguration="WsHttpBinding" contract="MyNamespace.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="WebHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
<wsHttpBinding>
<binding name="WsHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="false" httpsHelpPageEnabled="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
yapılacak son şey, özel bir ServiceHostFactory oluşturmak ve tüm özel kodu kullanılacak neden olur, kullanmak için svc dosyası söylemek. Tabii ki, davranışı konfigürasyona eklemenize izin veren bir özel eleman da yaratabilirsiniz, fakat bu davranış için kod tabanlı bir yaklaşımın daha iyi olduğunu düşünüyorum çünkü olası olmayan türleri işlemek olasılığını ortadan kaldırmak isteyeceksiniz. o hizmetinizi kıracak şekilde:
public sealed class NullableWebServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new NullableWebServiceHost(serviceType, baseAddresses);
}
}
Değiştir sizin Service.svc biçimlendirme dosyasını, aşağıdaki:
<%@ ServiceHost Service="MyNamespace..Service1" CodeBehind="Service1.svc.cs" Factory="MyNamespace.NullableWebServiceHostFactory" %>
Artık sadece tarafından, herhangi bir sorun olmadan servis arayüzünde null türlerini kullanabilirsiniz Parametreyi atlamak veya boş bir dizeye ayarlamak. Aşağıdaki kaynaklar size daha fazla yardım olabilir:
Umut bu yardımcı olur!
Yukarıdaki kod referansında, QueryStringConverter türetilmiş sınıfları, framework 4'te kullanılamaz hale getiren bir hata vardır. Bunu denemeden önce hatayı gözden geçirdiğinizden emin olun. Pratikte işe yaramadığını keşfetmeden önce çok zaman harcadım. – Jim