Необязательный параметр в UriTemplate в WCF

Я использовал подсказку в этой теме и предоставил значение по умолчанию, поэтому, когда пользователь не указывает виртуальный подкаталог, я предполагаю, что он имел в виду все вещи, которые будут перечислены. Оно работает.

[OperationContract]
[WebInvoke(UriTemplate = "GetStuff/{type=all}", ...]
IEnumerable<Stuff> GetStuff(String type);

Однако было бы лучше указать значение по умолчанию. Однако default(String) имеет значение null, и я хотел бы отправить фактическое значение. В частности, я положил свое сердце на String.Empty. Однако я заметил, что следующее не работает. Условие на стороне сервера не распознает пустую строку (... где 'type' in (ColName, '', 'all')).

[OperationContract]
[WebInvoke(UriTemplate = "GetStuff/{type=String.Empty}", ...]
IEnumerable<Stuff> GetStuff(String type);

Что делать?

4 ответа

Решение

На самом деле вы не можете иметь пустое значение по умолчанию в UriTemplate, но у вас может быть что-то, что будет означать значение по умолчанию, и в операции вы можете заменить это фактическим значением по умолчанию, которое вы хотите, как показано ниже.

public class Stackru_17251719
{
    const string DefaultValueMarker = "___DEFAULT_VALUE___";
    const string ActualDefaultValue = "";
    [ServiceContract]
    public class Service
    {
        [WebInvoke(UriTemplate = "GetStuff/{type=" + DefaultValueMarker + "}", ResponseFormat = WebMessageFormat.Json)]
        public IEnumerable<string> GetStuff(String type)
        {
            if (type == DefaultValueMarker)
            {
                type = ActualDefaultValue;
            }

            yield return type;
        }
    }
    public static void SendBodylessPostRequest(string uri)
    {
        HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
        req.Method = "POST";
        req.ContentType = "application/json";
        req.GetRequestStream().Close(); // no request body

        HttpWebResponse resp;
        try
        {
            resp = (HttpWebResponse)req.GetResponse();
        }
        catch (WebException e)
        {
            resp = (HttpWebResponse)e.Response;
        }

        Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
        foreach (string headerName in resp.Headers.AllKeys)
        {
            Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
        }

        Console.WriteLine();
        Stream respStream = resp.GetResponseStream();
        Console.WriteLine(new StreamReader(respStream).ReadToEnd());

        Console.WriteLine();
        Console.WriteLine("  *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*  ");
        Console.WriteLine();
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress));
        host.Open();
        Console.WriteLine("Host opened");

        SendBodylessPostRequest(baseAddress + "/GetStuff/nonDefault");
        SendBodylessPostRequest(baseAddress + "/GetStuff");

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}

Это сработало с "=null" для меня. Мой контракт выглядит так:

[WebInvoke(UriTemplate = "UploadFile/{fileName}/{patientId}/{documentId}/{providerName=null}", Method = "POST")]

void UploadFile(string fileName, string patientId, string documentId, string providerName, Stream fileContents);

При добавлении только '=' для получения значения по умолчанию, которое является пустым для строковой переменной, оно выдает сообщение

UriTemplate '/application /legal/statuses/{serviceId=}' недействителен; объявление переменной UriTemplate 'serviceId=' предоставляет пустое значение по умолчанию для переменной пути 'serviceId'. Обратите внимание, что переменные пути UriTemplate не могут быть связаны с нулевым или пустым значением. Смотрите документацию для UriTemplate для более подробной информации.

вместо этого назначьте значение по умолчанию и проверьте позже в коде:

 UriTemplate = "/applications/legal/statuses/{serviceId=default}"

идентификатор сервиса будет значением по умолчанию.

У вас есть возможность добавить необязательный параметр к вашему URITemplate. Однако это должен быть последний параметр.

Необязательный параметр UriTemplate, использующий WebGet

Другие вопросы по тегам