В WCF можно ли использовать символ подстановки в буквальном сегменте моего UriTemplate?

Я создаю службу RESTful WCF с использованием.Net 4.0. Я хочу следующие два URL:

/root/document/{ids}?fields={fields}
/root/externaldocument/{ids}?fields={fields}

для сопоставления с одним и тем же элементом интерфейса:

Documents GetDocuments(string ids, string fields)

Я попытался вставить шаблон в буквальный сегмент URL:

    [OperationContract]
    [WebGet(UriTemplate = "/root/*document/{ids}?fields={fields}")]
    Documents GetDocuments(string ids, string fields)

Однако это недопустимо, и я получаю следующее исключение:

The UriTemplate '/root/*document/{ids}?fields={fields}' is not valid; the 
wildcard ('*') cannot appear in a variable name or literal... Note that a 
wildcard segment, either a literal or a variable, is valid only as the last 
path segment in the template

Если я заверну сегмент шаблона в фигурную скобку:

    [OperationContract]
    [WebGet(UriTemplate = "/root/{*document}/{ids}?fields={fields}")]
    Documents GetDocuments(string ids, string fields)

Тогда я получаю исключение, потому что в аргументах метода нет такого входного параметра:

Operation 'GetDocuments' in contract 'IAPIv2' has a UriTemplate that expects a 
parameter named 'DOCUMENTS', but there is no input parameter with that name 
on the operation.

Мой обходной путь - это просто иметь две записи, указывающие на разные методы, а затем вызывать методы общей реализации:

    [OperationContract]
    [WebGet(UriTemplate = "/root/document/{ids}?fields={fields}")]
    Documents GetDocuments(string ids, string fields)

    [OperationContract]
    [WebGet(UriTemplate = "/root/externaldocument/{ids}?fields={fields}")]
     Documents GetExternalDocuments(string ids, string fields)

Но это выглядит некрасиво.

Я прочитал документацию и не могу найти этот адрес конкретно адрес. Есть ли способ, чтобы я мог иметь литеральный сегмент подстановочный знак в WCF? Или это не возможно в WCF?

1 ответ

Решение

Как оказалось, две точки входа должны были иметь несколько различную функциональность. Поэтому мне нужно было определить, какой URL был использован для ввода метода. В итоге я сделал следующее:

[OperationContract]
[WebGet(UriTemplate = "/root/{source}ocuments/{ids}?fields={fields}")]
DocumentCollection GetDocumentsById(string source, string ids, string fields);

Оба URL:

/root/document/{ids}?fields={fields}
/root/externaldocument/{ids}?fields={fields}

сопоставить с тем же шаблоном URL, и поэтому мне нужно было иметь только одну запись с одним UriTemplate в моем интерфейсе.

Входной параметр "source" фиксирует либо "d", если второй сегмент - "документы", либо "externald", если второй сегмент - "externaldocuments". Таким образом, проверяя этот входной параметр, метод может реагировать соответствующим образом, в зависимости от того, какой URL был использован. чтобы достичь метода.

Обратите внимание, что я не мог использовать следующее для UriTemplate:

[WebGet(UriTemplate = "/root/{source}documents/{ids}?fields={fields}")]

потому что в этом случае входящий URL

/root/document/{ids}?fields={fields}

не будет соответствовать шаблону, даже если шаблон соответствует, если для входного параметра источника используется пустая строка (""). По-видимому, алгоритм сопоставления UriTemplate требует, чтобы в группе захвата параметров был хотя бы один символ, чтобы было совпадение.

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