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