Необязательный параметр в методе службы asmx приводит к отказу другого метода
Чтобы воссоздать проблему, которую я вижу, используя VS2010, создайте пустой веб-сайт и добавьте веб-службу (asmx) с кодом.
Используя следующий код, оба веб-метода могут быть успешно задействованы:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
[WebMethod]
public void Method1(int x) {
// i'm good
}
[WebMethod]
public string Method2(int x) {
return "it worked";
}
}
Теперь, если я изменю parm на методе 2 на тип с нулевым значением, он будет работать нормально, но это сделает отказ метода 1...
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
[WebMethod]
public void Method1(int x) {
// no changes made to this method, but it no longer works
}
[WebMethod]
public string Method2(int? x) {
return "it worked";
}
}
Результирующая ошибка - это та, которую я видел раньше, если при вызове службы отсутствует параметр:
System.IndexOutOfRangeException: индекс находился за пределами массив. в System.Web.Services.Protocols.HttpServerType..ctor(Тип типа) при System.Web.Services.Protocols.HttpServerProtocol.Initialize() at System.Web.Services.Protocols.ServerProtocolFactory.Create(Тип типа, Контекст HttpContext, запрос HttpRequest, ответ HttpResponse, Логическое & abortProcessing)
Кроме того, это только кажется сломанным, если первый метод возвращает void, поэтому это также отлично работает:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
[WebMethod]
public string Method1(int x) {
return "works again";
}
[WebMethod]
public string Method2(int? x) {
return "it worked";
}
}
Любые идеи, что здесь происходит? Это произошло с использованием как 3.5, так и 4.0 в качестве целевой структуры.
edit: просто чтобы упредить дальнейшие ответы/комментарии по этим строкам... Я не ищу советы о лучших практиках, альтернативных решениях, asmx-месте в ландшафте сервиса, wcf и т.д. Это то, что я пришел во время отладки проблемы в устаревшем приложении, которое я не писал и которое уже исправлено, и мне интересно узнать причину конкретного поведения, которое я здесь изложил.
Ответы
Ответ 1
@heisenberg, вы передаете null из приложения, которое вызывает веб-метод.
Образец, который я пробовал, отлично работает на vs2010. ниже этого кода, который я пробовал.
Пример кода:
protected void Button1_Click(object sender, EventArgs e)
{
WebService1 objws = new WebService1();
objws.voidMethod(5);
Label1.Text = objws.HelloWorld(5);
}
Код службы ASMX
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld(int? x)
{
if (x != null)
{
return x.ToString();
}
return "Hello World";
}
[WebMethod]
public void voidMethod(int x)
{
}
}
Ответ 2
Я пробовал ваш код, и он работает. Хотя отладка не работает, возникает ошибка.
Я думаю, что это происходит потому, что Nullable int не является примитивным типом. См. Описание из WSDL службы "Тестовая форма доступна только для методов с примитивными типами в качестве параметров".
Я предполагаю, что проблема, с которой вы сталкиваетесь, происходит не из-за Nullable int.
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
public void Method1(int x)
{
// i'm good
}
[WebMethod]
public string Method2(int? x)
{
return "it worked";
}
}
Код сайта:
namespace Helper
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ServiceReference1.WebService1SoapClient web = new ServiceReference1.WebService1SoapClient();
web.Method1(5);
string x = web.Method2(5);
}
}
}
Ответ 3
Это может случиться, может быть, вы пытаетесь отправить один и тот же X на оба метода, хотя они не принимают один и тот же тип?
потому что одно значение равно null, а другое - нет.
Ответ 4
Нужно ли использовать Nullable (?)
в вашем решении? Я думаю, что вы можете реализовать очень простую логику, например: "Если я получаю пустую строку, то у меня есть значение Null или если я получаю строковое значение" Null ", то мне нужно использовать Null Object", и в будущем рассмотрим использование WCF с подходом Nullable-?
.
С другой стороны, я рекомендую вам изменить все методы void на строковое значение со словом "ok"
. Я думаю, что "запрос должен иметь ответ".