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. Я думал, что он будет вызываться автоматически для каждого вызова службы, если вы правильно настроили его в интернете.конфиг.

479   2  

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

    Ничего не найдено.