In WCF can I have a wildcard character in a literal segment of my UriTemplate?

孤人 提交于 2021-01-27 17:11:09

问题


I am authoring a RESTful WCF service using .Net 4.0. I want the following two URLS:

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

to map to the same interface member:

Documents GetDocuments(string ids, string fields)

I have tried putting a wildcard into a literal URL segment:

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

However, this is not valid and I get the following exception:

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

If I wrap the wildcard segment in a template brace:

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

Then I get an exception because there is no such input parameter in the method arguments:

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.

My workaround is simply to have two entries, pointing to different methods, and then have the methods call a common implementation:

    [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)

But this seems kind of ugly.

I have read the documentation and cannot find this point specifically address. Is there any way I can have a wildcard literal segment in WCF? Or is this not possible in WCF?


回答1:


As it turned out, the two entry points needed to have slightly different functionality. So I needed to capture which URL was used to enter the method. What I ended up doing was the following:

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

Both URLs:

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

map to the same URL template, and thus I needed to have only a single entry with a single UriTemplate in my interface.

The "source" input parameter captures either "d" if the second segment is "documents or "externald" if the second segment is "externaldocuments". Thus by inspecting this input parameter, the method can react appropriately, depending upon which URL was used to reach the method.

Note that I could not use the following for the UriTemplate:

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

because in this case, the incoming URL

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

would not match the template, even though the template matches if an empty string ("") is used for the source input parameter. Apparently the UriTemplate matching algorithm requires there to be at least one character in a parameter capturing group for there to be a match.



来源:https://stackoverflow.com/questions/13956889/in-wcf-can-i-have-a-wildcard-character-in-a-literal-segment-of-my-uritemplate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!