Http 400 неверный запрос при вызове операции Службы WCF?
Когда я звоню http://localhost/TestService.svc / GetColors , я получаю http (400) плохой запрос. Когда я запускаю это в fiddler, я также получаю плохой запрос. Когда я вызываю службу через тестовый клиент wcf, она работает нормально. Что могло стать причиной этого?
Контракт на обслуживание:
[ServiceContract]
public interface ITestService
{
[OperationContract]
string GetColors();
}
Реализация ITestService:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class TestService : ITestService
{
public List<Color> GetColors()
{
List<Color> colors= new List<Color>();
colors.Add(new Color { Name = "Red", Code = "123" });
colors.Add(new Color { Name = "Blue", Code = "323" });
colors.Add(new Color { Name = "Green", Code = "3394" });
return colors;
}
}
Вот моя паутина.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="CustomAuthentication">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<services>
<service name="TestService.TestService"
behaviorConfiguration="CustomValidator" >
<endpoint
address=""
binding="wsHttpBinding"
bindingConfiguration="CustomAuthentication"
contract="TestService.ITestService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/TestService/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CustomValidator">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="TestService.CustomUserNameValidator, TestService"/>
<serviceCertificate findValue="Test" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
<serviceMetadata httpGetEnabled="True"/>
</behavior>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Когда я вызываю его, я просто открываю любой браузер и ставлю url http://localhost/TestService.svc/GetColors. Если я сделаю это через Дэва среда, я вижу http 400 плохой запрос. Если я делаю это через IIS, я просто вижу пустую страницу.
Вот внутреннее исключение:
<ExceptionString>System.Xml.XmlException: The body of the message cannot be read
because it is empty.</ExceptionString>
Еще один вопрос, касающийся моего CustomUserNameValidation:
Я реализую пользовательскую проверку с помощью метода Validate UserNamePasswordValidator, но когда я вызываю что-то вроде GetColors через клиент wcf, он не вызывает метод Validate. Единственный способ заставить его вызвать validate - это вызвать Validate (user, pass) прямо в GetColors. Я думал, что он будет вызываться автоматически для каждого вызова службы, если вы правильно настроили его в интернете.конфиг.
2 ответов:
Похоже, что ваш контракт на обслуживание и его реализация не совпадают....
Контракт на обслуживание определяет один
string, который должен быть возвращен изGetColors():[ServiceContract] public interface ITestService { [OperationContract] string GetColors(); }Но реализация возвращает
List<Color>вместо:[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] public class TestService : ITestService { public List<Color> GetColors() {Есть ли вероятность, что вы изменили свою реализацию сервиса и забыли обновить контракт на обслуживание??
Также: поскольку это SOAP-сервис с
wsHttpBinding, Вы не можете просто вызвать метод из браузера, перейдя по его адресу - вам нужно использовать тестовый клиент WCF (который работает, как вы говорите). Вы также не можете просто вызвать его из Fiddler - вам придется вручную создать весь конверт SOAP с заголовком, телом и всем остальным-совсем не простая задача.Что вы можете попробовать, так это пойти в
http://localhost/TestService.svc?wsdl, чтобы проверить, получите ли вы обратно правильный WSDL для службы.
Это может быть вызвано многими причинами. Я предлагаю вам сначала включить трассировку WCF, это обычно очень полезно, Так как это дает вам вывод на стороне сервера того, что действительно происходит. Вот ссылка, которая должна помочь: Как включить трассировку WCF
EDIT : Одна маленькая вещь, чтобы отметить с WCF: в отличие от автоматически генерируемого ole ' ASMX web service он не позволяет просматривать на базовый адрес с помощью стандартного браузера. Вы можете перейти к адресу метаданных (mex-адрес), но не к корень. Это просто дизайн (метод HTTP не поддерживается, я полагаю).
Comments