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

среда, 29 июля 2009 г.

Странный баг в .Net Silverlight RIA Services

Портируя Silverlight приложение на .Net RIA Services столкнулся с неприятным багом, который сейчас и попробую описать.

Имеется некий метод TotalDueByRegionId который принимает в качестве параметра с именем inputName строку ( раньше принимал число, но баг повторяется независимо от этого ).
И вот необходимо вызвать его из XAML кода контрола, что я и делаю следующим образом, пытаясь передать ему параметр:











Запускаем код и отлавливаем в вызов TotalDueByRegionId в сгенерированом коде:



В этом месте инструкция по адресу 03Bh передает значение в переменную this._value



Следующая инструкция устанавливает эту же переменную в null:



Дизасемблер IL кажет нам следующие:


Что явно не вяжется с тем, что происходит в реальности. Я в тупике. Как жить дальше?

UPD: Запостил на официальный форум Silverlight: http://silverlight.net/forums/p/115386/260071.aspx#260071

UPD 2: Решение: Когда необходимо просто передать параметр в запрос - надо использовать тип parameter вместо controlparameter. Controlparameter позволяет забаиндиться к свойствам других контролов. (Надо меньше тупить... Надо меньше тупить... и чаще отдыхать)

суббота, 21 марта 2009 г.

URL rewritintg а точнее routing в ASP.Net 3.5

Все, что необходимо знать по этой теме прекрасно описано в статье ASP.Net routing... Goodby URL rewriting?  Криса Каванагса (Интересно правильно ли я транскрибировал его фамилию? :) 
И здесь я просто кратко повторю:

Первым делом надо добавить в проект ссылки на сборки System.Web.Routing и System.Web.Abstrations

public class WebFormRouteHandler : IRouteHandler where T : IHttpHandler, new()
{
public string VirtualPath { get; set; }

public WebFormRouteHandler(string virtualPath)
{
this.VirtualPath = virtualPath;
}

public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return (VirtualPath != null)
? (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(T))
: new T();
}
}

//Этот клас необходим для работы механизма роутинга в IIS 7
public class RoutingHandler : UrlRoutingHandler
{
protected override void VerifyAndProcessRequest(IHttpHandler httpHandler, HttpContextBase httpContext)
{
}
}
Чтобы роутинг заработал в IIS7 Необходимо выполнить ряд дополнительных действий

  • Вставить в web.config, в раздел system.webServer в теге modules следующую строчку:


  • В сам тег modules добавить атрибут


  • И последнее в том же разделе в тег handlers добавить:



Ну и теперь для счастливой жизни нам не хватает только следующего кода в файле Global.asax

protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
// Note: Change the URL to "{controller}.mvc/{action}/{id}" to enable
// automatic support on IIS6 and IIS7 classic mode

var routeHandler = new WebFormRouteHandler("~/MyPage.aspx");

routes.Add(new Route("{page}", routeHandler));
routes.Add(new Route("AccountServices/{page}", routeHandler));
routes.Add(new Route("Default.aspx", routeHandler));
}
Перед тем как использовать рекомендую так-же прочитать

Using routing with WEbforms
. Дабы спастись от злых хакеров

пятница, 20 марта 2009 г.

Получаем абсолютный путь к файлу в аттрибуте action тега form в ASP.Net

Так уж устроена работа программиста, что периодически приходиться спотыкаться на тривиальнейших вещах. И вот споткнувшись, обязательно во время выполнения черезвычайно срочного заказа, который надо было сдать позавчера, приходиться сидеть по многу часов подряд, и искать способ обойти какую-нибудь очередную хрень. За это время, заказчик успевает плюнуть на тебя и уходит на всегда. А ты продолжаешь сидеть и пытаешься понять, где же тебя...

Так и в этот раз. Оказалось, что атрибут action тега form возвращаемый aspx страницей содержит в содержит в себе исключительно относительный путь к странице. И что делать? Могли ведь предусмотреть в webconfig-е параметр, например, AbsoluteURLs = true, который бы заменял в случае необходимости относительные пути на абсолютные? И где он? Может я просто про него не знаю?

Ну а теперь собственно решение.
В папочке App_Browsers создаем файл Form.browser. В этот файл помещаем следующий код:










После этого мы созадем классы FormRewriterControlAdapter и RewriteFormHtmlTextWriter со следующим содержимым:


namespace WebApplication1
{
public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
base.Render(new RewriteFormHtmlTextWriter(writer));
}

public class RewriteFormHtmlTextWriter : HtmlTextWriter
{
public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
: base(writer)
{
this.InnerWriter = writer.InnerWriter;
}

public override void WriteAttribute(string name, string value, bool fEncode)
{
if (name == "action")
{
HttpContext Context = HttpContext.Current;

if (Context.Items["ActionAlreadyWritten"] == null)
{
Uri url = Context.Request.Url;

value = ((new StringBuilder()).AppendFormat("http://{0}:{1}{2}", url.Host, url.Port, Context.Request.RawUrl)).ToString();
Context.Items["ActionAlreadyWritten"] = true;
}
}
base.WriteAttribute(name, value, fEncode);
}
}
}
}


Вуаля. Сейчас если соберусь, выложу способ замены относительных путей на абсолютные в других частях aspx.

пятница, 13 марта 2009 г.

Загрузка XAML во время выполнения

Загружаем элементы Silverlight из стороннего XAML файла.

private Canvas GetControlFromFile()
{
Uri uri = new Uri("Hands.xaml", UriKind.Relative);

System.Windows.Resources.StreamResourceInfo streamInfo = Application.GetResourceStream(uri);
if ((streamInfo != null) && (streamInfo.Stream != null))
{
using (System.IO.StreamReader reader = new StreamReader(streamInfo.Stream))
{
return XamlReader.Load(reader.ReadToEnd()) as Canvas;
}
}
return null;
}


Полученный элемент добавляем к другому элементу

LayoutRoot.Children.Add(GetControlFromFile);

понедельник, 9 февраля 2009 г.

Атрибут xmlns

При попытке выполнить следующий код:

XmlWriter output;
output.WriteStartElement("sparql");
output.WriteAttributeString("xmlns", "http://www.w3.org/2005/sparql-results#");

получаем исключение:

System.Xml.XmlException: Префикс "" не может быть переопределен с "" на "http://www.w3.org/2005/sparql-results#" внутри того же начального тега элемента.

Это все потому, что правильно делать вот так:

XmlWriter output;
output.WriteStartElement("sparql", "http://www.w3.org/2005/sparql-results#");

Ошибка была обнаружена в библиотеке SemWeb. Теперь в репозитории лежит уже исправленная версия.

воскресенье, 1 февраля 2009 г.

Вывод результата запроса в SemWeb

Для того чтобы сериализовать результаты выполнения запроса к RDF хранилищу в нужный нам формат в пространстве имен SemWeb.Query библиотеки SemWeb предусмотрен абстрактный класс QueryResultSync, а так же реализованы несколько его наследников:

  1. SparqlXmlQuerySynk, возвращающий результат запроса в виде XML документа содержащего исходный запрос и результат.
  2. HTMLQuerySink, - возвращает результат в виде таблицы HTML
  3. CSVQuerySynk - как нетрудно догадаться возвращает результат в строку разделенную запятыми
  4. QueryResultBuffer - класс который сохраняет результаты в три коллекции Variables, Bindings, и Coments

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


public abstract class QueryResultSink
{
public virtual void Init(Variable[] variables){}
public abstract bool Add(VariableBindings result);
public virtual void Finished() {}
public virtual void AddComments(string comments) {}
}


Примеры реализации лучше всего смотреть в коде самой библиотеки.

Cинглтон и многопоточность

Допустим у нас есть некий синглтон, который сохраняет свои состояния и работает как конечный автомат. И состояний этих у него много. Но допустим нам хотелось бы воспроизвести результаты его поведения в начальном состоянии. А как его в это состояние вернуть непонятно.
В этом случае иногда может выручить многопоточность.

public delegate string GetXmlFromTestedDelegate(Person[] persons);
private string GetXmlFromTested(Params[] params)
{
Singletone.Instance.Import(params);
return Singletone.GetAllInXml();
}

public void GetResultInXml()
{
GetXmlFromTestedDelegate asyncDelegate = GetXmlFromTested;
IAsyncResult result = asyncDelegate.BeginInvoke(Params, null, null);
while (!result.IsCompleted)
{
Thread.Sleep(50);
}
string xml = asyncDelegate.EndInvoke(result);

Assert.That(xml,Is.EqualTo(GetEtalonXML()));
}


А может и не выручить... Это я к чему собственно?? А к тому, что не всякая реализация синглтона действительно синглтон.

пятница, 30 января 2009 г.

Как узнать полный путь к файлу в приложении на ASP.Net?

Исчерпывающее руководство по этому вопросу можно найти здесь.

Основное же – это использование метода MapPath(), который прячется в таких классах как Control, Page, Server.

четверг, 29 января 2009 г.

Перебираем все свойства класса

Иногда возникает задача перебрать все свойства некоторого класса. Задача очень просто решается при помощи рефлексии: person.GetType().GetProperties();

Этот код возвращает коллекцию PropertyInfo, из которой мы можем достать все необходимое.

А вот пример кода возвращающего значение свойства объекта по имени свойства: person.GetType().GetProperty(property.Name).GetValue(person, null)

Вывод XML в виде форматированного текста

Иногда возникает задача вывести некий Xml документ в строку, а иногда даже в виде текста на HTML страничке. Я нашел два похожих варианта решения.

Вариант с использованием XmlTextWriter

StringBuilder builder = new StringBuilder();
XmlTextWriter wr = new XmlTextWriter(new StringWriter(builder));
wr.Indentation = 2;
wr.IndentChar = '\t';
wr.Formatting = Formatting.Indented;

//Этот запрос заполняет строку builder xml данными форматированными символами "/t и /n"
ExecuteQuery(query, new SparqlXmlQuerySink(wr));


string s = builder.ToString();
//А это нам понадобилось чтобы получить возможность вставить строку в HTML
s.Replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("\n", "br")


Вариант с использованием XmlWriter

StringBuilder builder = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = ("\t");

XmlWriter xmlWriter = XmlWriter.Create(builder, settings);

//Заполняем builder XML кодом и опять получаем строку форматированную символами "/t и /n"
manager.Write(xmlWriter);