Параметры WCF REST не могут содержать периоды? - PullRequest
5 голосов
/ 04 февраля 2009

Итак, вот очень простой интерфейс для отдыха в WCF.

    [ServiceContract]
    public interface IRestTest
    {
        [OperationContract]
        [WebGet(UriTemplate="Operation/{value}")]
        System.IO.Stream Operation(string value);
    }

Это прекрасно работает, пока я не попытаюсь передать строку с точками, например, DNS-имя ... Я получаю 404 из asp.net.

Изменение UriTemplate для вставки параметров в строку запроса устраняет проблему. Кто-нибудь еще видит это или есть обходной путь?

Ответы [ 3 ]

3 голосов
/ 06 февраля 2009

Это правда, что часть пути не может содержать точку или много других специальных символов в этом отношении. Некоторое время назад я столкнулся с той же проблемой и получил ответ от команды TechNet, в котором говорилось, что строка запроса - это единственный вариант, который можно найти. К сожалению

http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/d03c8331-1e98-4d5d-82a7-390942a93012/

1 голос
/ 29 мая 2009

Вот пример HttpModule, который фиксирует «период», когда они встречаются в параметрах REST. Обратите внимание, что я видел это только на сервере разработки (он же Кассини), в IIS7 он, похоже, работает без этого «хака». Приведенный ниже пример также заменяет расширение файла «.svc», которое я адаптировал из этого ответа. Как удалить расширение «.svc» в службе RESTful WCF?

public class RestModule : IHttpModule
{
    public void Dispose()
    {
    }

    public void Init(HttpApplication context)
    {
        context.BeginRequest +=
            delegate
            {
                HttpContext ctx = HttpContext.Current;
                string path = ctx.Request.AppRelativeCurrentExecutionFilePath;

                int i = path.IndexOf('/', 2);
                if (i > 0)
                {
                    int j = path.IndexOf(".svc", 2);
                    if (j < 0)
                    {
                        RewritePath(ctx, path, i, ".svc");
                    }
                    else
                    {
                        RewritePath(ctx, path, j + 4, "");
                    }
                }
            };
    }

    private void RewritePath(HttpContext ctx, string path, int index, string suffix)
    {
        string svc = path.Substring(0, index) + suffix;
        string rest = path.Substring(index);
        if (!rest.EndsWith(ctx.Request.PathInfo))
        {
            rest += ctx.Request.PathInfo;
        }
        string qs = ctx.Request.QueryString.ToString();
        ctx.RewritePath(svc, rest, qs, false);
    }
}
1 голос
/ 06 февраля 2009

У меня есть сервис с почти точной подписью. Я могу передать значения, которые имеют "." во имя. Например, это будет работать на моем:

[OperationContract]
[WebGet(UriTemplate = "category/{id}")]
string category(string id);

с URL-адресом http://localhost/MyService.svc/category/test.category Я получаю значение `" test.category ", переданное как строковое значение.

Так что должна быть какая-то другая проблема. как вы получаете доступ к URL? просто прямо в браузере? Или через вызов JavaScript? Просто интересно, если это какая-то ошибка на стороне клиента. Сервер передает значение просто отлично. Я бы порекомендовал попытаться получить доступ к URL-адресу в вашем браузере, и, если он не работает, напишите точно, какой URL-адрес вы используете и какое сообщение об ошибке.

Кроме того, вы используете WCF 3.5 SP1 или просто WCF 3.5? В книге RESTFul .Net, которую я читаю, я вижу некоторые изменения в отношении UriTemplate.

И, наконец, я изменил простую Службу из книги RESTFul .Net, которая работает, и я получил правильный ответ.

class Program
{
    static void Main(string[] args)
    {
        var binding = new WebHttpBinding();
        var sh = new WebServiceHost(typeof(TestService));
        sh.AddServiceEndpoint(typeof(TestService),
            binding,
            "http://localhost:8889/TestHttp");
        sh.Open();
        Console.WriteLine("Simple HTTP Service Listening");
        Console.WriteLine("Press enter to stop service");
        Console.ReadLine();
    }
}

[ServiceContract]
public class TestService
{
    [OperationContract]
    [WebGet(UriTemplate = "category/{id}")]
    public string category(string id)
    {
        return "got '" + id + "'";
    }   
}
...