Показаны сообщения с ярлыком Web Client. Показать все сообщения
Показаны сообщения с ярлыком Web Client. Показать все сообщения

Сервис изображений

суббота, 25 апреля 2009 г.,

Например, необходимо на сайт добавить сервис, который будет динамически создавать изображения (.gif-формат) в ответ на запрос: "/image/logo,hello,RedOnMaroon", где logo - это тип изображения, hello - текст на изображении, Red - цвет текста, Maroon - цвет фона.
Ниже приводится метод, который необходимо добавить в сервис:
[OperationContract]
[WebGet(UriTemplate = "/image/{id},{text},{color}On{bgcolor}")]
public Stream GetImage(string id, string color, string bgcolor, string text)
{
    var format = ImageFormat.Gif;

    // создать
    Bitmap img = new Bitmap(100, 100);
    using (Graphics g = Graphics.FromImage(img))
    {
        g.Clear(Color.FromName(bgcolor));
        g.DrawString(
            text,
            new Font("verdana", 14),
            new SolidBrush(Color.FromName(color)),
            new RectangleF(0, 0, img.Width, img.Height));
    }

    // сохранить
    var ret = new MemoryStream();
    img.Save(ret, format);
    ret.Position = 0;

    WebOperationContext.Current.OutgoingResponse.ContentType = ("image/" + format).ToLower();
    return ret;
}

Пример вызова метода из html:
<img src="/DataProvider.svc/image/logo,hello,WhiteOnRed" />
<img src="/DataProvider.svc/image/logo,привет,WhiteOnNavy" />

Если указать не все параметры, то клиент получит сообщение: Endpoint not found.

Если при отладке в методе GetImage вызвать img.Save("image." + format, format);, то файл будет создан в папке C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE

В сервисе HttpContext.Current == null, но если: 1) добавить в web.config в configuration следующий тег:
<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
2) у класса сервиса определить атрибут AspNetCompatibilityRequirementsMode:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceContract]
public class DataProvider
{
    ...
3) в методе GetImage можно вызвать:
var dir = HttpContext.Current.Server.MapPath("~");

Особенность CookieContainer'а

воскресенье, 19 апреля 2009 г.,

При первом обращении к веб-сайту, например, test.ru был получен ответ:
HTTP/1.1 200 OK
Date: Thu, 16 Apr 2009 08:39:02 GMT
Set-Cookie: PathDotTest=value; expires=Tue, 13-Apr-2010 23:43:04 GMT; path=/; domain=.test.ru
Set-Cookie: PathTest=value; expires=Tue, 13-Apr-2010 23:43:04 GMT; path=/; domain=test.ru
Set-Cookie: DotTest=value; expires=Tue, 13-Apr-2010 23:43:04 GMT; domain=.test.ru
Set-Cookie: WwwDotTest=value; expires=Tue, 13-Apr-2010 23:43:04 GMT; domain=www.test.ru
Set-Cookie: Test=value; expires=Tue, 13-Apr-2010 23:43:04 GMT; domain=test.ru
Set-Cookie: Path=value; expires=Tue, 13-Apr-2010 23:43:04 GMT; path=/;
Set-Cookie: Null=value; expires=Tue, 13-Apr-2010 23:43:04 GMT;
Set-Cookie: External=value; expires=Tue, 13-Apr-2010 23:43:04 GMT; domain=external.ru
Location: /homepage
Content-Length: 0



В HttpWebResponse.Cookies, а соответственно и в HttpWebRequest.CookieContainer окажется меньше cookie, чем указано в http-заголовках:
PathDotTest=value; expires=14.04.2010 3:43:04; path=/; domain=.test.ru
PathTest=value; expires=14.04.2010 3:43:04; path=/; domain=test.ru
DotTest=value; expires=14.04.2010 3:43:04; path=/; domain=.test.ru
Test=value; expires=14.04.2010 3:43:04; path=/; domain=test.ru
Path=value; expires=14.04.2010 3:43:04; path=/; domain=test.ru
Null=value; expires=14.04.2010 3:43:04; path=/; domain=test.ru
Два cookie: WwwDotTest и External - "пропали", т.е. не попали в контейнер. С External - понятно, это сторонний домен. А при повторном обращении к сайту:
  • адрес: http://test.ru; отправлены cookie: Path и Null.
  • адрес: http://www.test.ru; отправлены cookie: PathDotTest, PathTest, DotTest, Test
Вот такая особенность есть у CookieContainer'а, которая противоречит правилам сайтов:
  • если в cookie указан domain=test.ru, то верни cookie при запросе http://test.ru;
  • если в cookie указан domain=mail.test.ru, то верни cookie при запросе http://mail.test.ru;
  • если в cookie указан domain=.test.ru, то верни cookie при запросе http://test.ru и любого поддомена, например, http://www.test.ru или http://mail.test.ru;
  • если domain не указан, то это эквивалентно http://test.ru;

Т.е. иногда лучше самому обрабатывать http-заголовки.