У меня есть отдыхающий веб-сервис wcf 3.5, размещенный в IIS 7.5.Это настройка для использования базовой аутентификации через https.Я добавил как можно больше информации ниже (названия классов и т. Д. Были немного изменены).Будем благодарны за любые советы или предложения.
Каждый раз, когда я пытаюсь отправить POST либо через Fiddler, либо через клиентское приложение, я получаю это сообщение:
HTTP / 1.1 400 Bad Request
Я включил журналы svctrace, которые дают мне эту информацию:
System.Runtime.Serialization.SerializationException, mscorlib, Версия = 2.0.0.0, Культура = нейтральная, PublicKeyToken = b77a5c561934e089
Невозможнодесериализовать тело XML с корневым именем 'user-search-request' и корневым пространством имен '' (для операции 'FetchMatchingUsers' и контракта ('IMyService', 'http://tempuri.org/')) с использованием DataContractSerializer. Убедитесь, что тип, соответствующий XML, добавлен вколлекция известных типов службы.
URL-адрес службы выглядит следующим образом: https://mysite.com/program/user/v1.0/MyService.svc
Мой договор на обслуживание выглядит следующим образом:
[ServiceContract]
interface IMyService
{
[WebInvoke(UriTemplate = "",
Method = "POST",
RequestFormat = WebMessageFormat.Xml,
ResponseFormat = WebMessageFormat.Xml)]
[OperationContract]
Users FetchMatchingUsers(User u);
}
Моя реализация службы выглядит следующим образом:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MyService : IMyService
{
static Users _users = new Users();
public Users FetchMatchingUsers(User u)
{
return SearchByFullName(u.FirstName, u.LastName);
}
}
DataContract выглядит следующим образом:
[CollectionDataContract(Name = "user-search-request", Namespace = "")]
public class Users : List<User>
{ }
[DataContract(Name = "user", Namespace = "")]
public class User
{
[DataMember(Name = "first-name")]
public string FirstName { get; set; }
[DataMember(Name = "last-name")]
public string LastName { get; set; }
}
Модель службы настроена следующим образом:
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
</serviceHostingEnvironment>
<services>
<service behaviorConfiguration="basic" name="MyService">
<clear />
<endpoint address="/program/user/v1.0" binding="basicHttpBinding"
name="Default" contract="MyService.IMyService"
listenUriMode="Explicit">
<identity>
<certificateReference storeName="My" storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="https://mysite.com" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="basic">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding">
<readerQuotas maxStringContentLength="10500" />
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
Мой POST настроен так:
private void DoPost
{
String firstname = "Test";
String lastname = "User";
User user = new User();
user.FirstName = firstname;
user.LastName = lastname;
String uristring = @"https://mysite.com/program/user/v1.0/MyService.svc/";
Uri uri = new Uri(uristring);
HttpWebRequest client = (WebRequest.Create(uri)) as HttpWebRequest;
NetworkCredential cred = new NetworkCredential(_username, _password, _domain);
String username = cred.Domain + "\\" + cred.UserName;
byte[] credentialBuffer = new UTF8Encoding().GetBytes(username + ":" + cred.Password);
client.Credentials = cred;
client.Method = "POST";
client.ContentType = "application/xml";
client.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer);
List<User> users = new List<User>();
users.Add(user);
SerializeUsers sa = new SerializeUsers();
String output = sa.SerializeUsers(users);
client.ContentLength = output.Length;
// Write the request StreamWriter
StreamWriter requestWriter = new StreamWriter(client.GetRequestStream(), System.Text.Encoding.ASCII);
requestWriter.Write(output.ToString());
requestWriter.Close();
// Do the request to get the response
try
{
StreamReader responseReader = new StreamReader(client.GetResponse().GetResponseStream());
String response = responseReader.ReadToEnd();
responseReader.Close();
}
catch (WebException ex)
{
String message = ex.Message;
}
}
Мой десериализатор сейчас является просто тестом, поэтому xml на самом деле жестко закодирован, но мне нужнозаставьте его работать правильно, как только я решу эту проблему.
public class SerializeUsers
{
public String SerializeUsers(List<User> ts)
{
String xml = @"<user-search-request xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"">";
foreach (User t in ts)
{
xml += @"<user>";
xml += @"<first-name>" + t.FirstName + "</first-name>";
xml += @"<last-name>" + t.LastName + "</last-name></user>";
}
xml += @"</user-search-request>";
return xml;
}
}