22.09.2017 WSDL генерит неправильный SoapAction
 
Всем привет!

Есть WSDL от стороннего сервиса
Содержит в себе такой раздел
<wsdl:operation name="SecurityAuthenticate">
<soap:operation soapAction="http://webservices.alienDomain.com/1ASIWVISVIP/VLSSLQ_06_1_1A" />
Этот Action является правильным

Но при этом в сгенеренном классе получается
[OperationContract(Action = "http://xml.alienDomain.com/AlienDomainWebServicesPT/SecurityAuthenticateRequest",

Свойство атрибута попадает в заголовок SoapAction и запрос не работает
Почему так происходит и как решить эту ситуацию?
Спасибо...

Подменять Action динамически не хочется, методов там много
Руками править сгенеренные классы тоже

22.09.2017 Свойства IEnumerable -- правильнее null или empty?
 
Емнип, есть правило что если метод возвращает пустой список -- то он должен быть не null а просто пустой.

Есть ли аналогичное правило для свойств?

18.09.2017 Кодогенерация в Visual Studio 2013
 
Добрый день.

Коллеги, подскажите удобное средство для кодогенерации совместимое с Visual Studio 2013.
В моём распоряжении последний ReSharper, сама студия, любое бесплатное ПО и прямые руки.

T4 не предлагать.

Необходимо прочитать текущую строчку, добавить в проект файл с новым типом и модифицировать 6 существующих.
Хочется иметь полный контроль над формированием текста.

18.09.2017 Чем подчеркнуть русские буквы в коде?
 
Иногда при переключении раскладки комп не успевает среагировать и вместо английской буквы c пишется русская c. Разницы между ними практически не видно на глаз.

Чем это подсветить? В решарпере есть такой функционал?

16.09.2017 Бывает ли.Net 4 без 2.0?
 
Будет ли работать прога, написанная на .Net 4.0 и использующая библиотеку .Net 2.0, если на компе установлена .Net 4.6 но нет 2.0? Или что лучше сделать, если нет исходников проги? Как то пересобрать IL под .Net 4? Или не нужно?

15.09.2017 IQuerable: на пороге велосипеда
 
Привет!
Вместо тысячи слов:

Есть локальная база, есть серверная.
Есть запрос FindEntryById, который может отправляться к любой из них.
В случае серверной базы, возвращаются только те записи, которые ассоциированы с пользователем, под которым осуществляется подключение к серверу. Перед возвратом модифицируются.
Все запросы к базе выполняются нативными SQL-квирями без ORM.

Запросов тысячи.
Пользователей тысячи.
Нужна обратная совместимость между версиями.

Я стою на пороге написания собственного IQuerable, который будет по разному транслировать запросы на стороне клиента и сервера, оттопыривая наружу единый API.
Меня беспокоит тот факт, что придется повторить путь Linq2Db с моделью CodeFirst, собрать все возможные грабли и реализовать не самый простой интерфейс с разбором экспрешшенов.
Есть ли пути проще?

Также буду рад если вы поделитесь чем-нибудь помимо примеров с MSDN касательно IQuerable и best practice по написанию подобных велосипедов.

14.09.2017 Как собрать приложение под .NET 4.5, чтобы оно работало на машине без .NET 4.6?
 
Доброго времени суток.

Есть (или была) в компиляторе неприятная проблема, связанная с тем, что в процессе оптимизации приложение, написанное под .NET 4.5 использует метод из .NET 4.6. Если он не установлен на целевой машине, это приводит к крашу.
https://stackoverflow.com/questions/31253747/method-not-found-0-system-array-empty-asapp-bundleconfig-registerbundl

Вопрос — актуальна ли эта проблема для MSBuild 15 (VS 2017), как её можно избежать, не удаляя с билдера .NET 4.6?
Есть ли другие аналогичные проблемы? Где с ними можно ознакомиться?

Пока самым надёжным вариантом кажется переход на .NET 4.6.

14.09.2017 Еще про CQRS
 
Смотрю, все больше говорят про CQRS. Уже хочется попробовать. Может будет подходящий проект и попробовать заюзать?

Хотя вот тут
Автор: AndrewVK
Дата: 13.09 23:32
чел критикует.

Что можете сказать? Это намного усложняет и лучше без надобности не соваться? Или же если проработать архитектуру то даже упростит?

13.09.2017 Как правильно вызвать последовательность задач?
 
Все привет!

При старте приложения надо запустить фоном выполнение нескольких тяжеловесных методов
Имеем:
var first = new Action(() => {});
var after1 = new Action(() => {});
var after2 = new Action(() => {});
...
var afterN = new Action(() => {});

Нужно дождаться выполнения метода first и запустить параллельно все остальные
Сейчас это работает так:
var _afters = 
{
   new Task(after1),
   new Task(after2),
   ...
   new Task(afterN),
}

var task = Task.Run(() => first).ContinueWith(t =>
                {
                    _afters.ForEach(a => a.Start());
                    Task.WaitAll(_afters);
                });

Можно ли написать как-то покрасивее?
Спасибо...

12.09.2017 В сотый раз про сущности EF и бизнес-объекты...
 
Много где обсуждалось. Но хотелось бы конкретики.

А именно. Чем плоха такая схема:

1. Для сервисов и их данных создаются контракты (interface). Интерфейсы принимают и отдают тоже интерфейсы или примитивные типы. Нужно для простой возоможности тестирования (подмена тех или иных сервисов на тестовую реализацию) и для возможности более простого распараллеливания работы.

2. Уже при реализации интерфейсов создаются классы бизнес-объектов (на основе соответствующих интерфейсов, просто нажимаешь правой кнопочкой implement).

Вопрос: чем плохо эти же классы бизнес-объектов наделить атрибутами разными, в том числе Key, Index, Required и пр. и позволить им сохраняться/восстанавливаться через EF? Какие конкретные минусы?

Стали бы вы делать специальные сущности для EF, которые на 90% совпадают с бизнес-объектами?

10.09.2017 Можно ли писать расширения для VS Code на .Net?
 
Можно ли писать расширения для VS Code на .Net?

Что-то сунулся, но там все на ТайпСкрипте. Есть ли возможность писать компилируемого языке?

Ну, или хотя бы связаться с сервером работающим на базе именованных каналов?

09.09.2017 Trailing Whitespace Visualizer
 
Хочу по рекламировать чужое студийное расширение Trailing Whitespace Visualizer

Оно подсвечивает и удаляет (при записи) пробелы и табы идущие в конце строк. Очень помогает держать код чистым, и подчищать за разными не следящими за "чистотой" товарищами.

https://raw.githubusercontent.com/madskristensen/TrailingWhitespace/master/artifacts/CSharp.png

07.09.2017 Фабрика классов работающая по атрибуту класса
 
Добрый день,

Озвучили мне идею — написать классам атрибут с характерным уникальным значением. А фабрика, чтобы получить входным параметром значение искала класс с соответствующим атрибутом и создавала экземпляр объекта.
Не могу найти решение как реализовать. Смотрел на Type.GetType, но там поиск по имени, а не по атрибуту. Циклически перебирать подходящие классы... наверное можно, но возможно существует лучшее решение?

07.09.2017 Функция для получения относительного пути
 
Вроде тривиальная задача. Вот есть у вас путь к файлу, типа:

D:/Temp/Resources/add.png


А так же есть путь к папке, типа:

D:/Temp/Templates/Resources


Как получить относительный путь для файла с точки зрения папки D:/Temp/Templates/Resources? Т.е. должно получиться:

../../Resources/add.png


На SOF предлагают юзать Uri MakeRelativeUri, но он не работает в Linux. А еще предлагают самописные фукнции разные. Проверил 2 штуки -- обе работали не во всех случаях. Нафарганил свою на скорую руку:

  Скрытый текст
        public static string MakeRelativePath(string absoluteFilePath, string baseDirectory)
        {
            if (null == absoluteFilePath)
                throw new ArgumentNullException(nameof(absoluteFilePath));

            if (null == baseDirectory)
                throw new ArgumentNullException(nameof(baseDirectory));

            //absoluteFilePath = Path.GetFullPath(absoluteFilePath);
            //baseDirectory = Path.GetFullPath(baseDirectory);

            var directorySeparator = Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture);
            var altDirectorySeparator = Path.AltDirectorySeparatorChar.ToString(CultureInfo.InvariantCulture);

            string[] separators =
            {
                directorySeparator,
                altDirectorySeparator
            };

            string[] absoluteFilePathParts = absoluteFilePath.Split(separators, StringSplitOptions.RemoveEmptyEntries);
            string[] baseDirectoryParts = baseDirectory.Split(separators, StringSplitOptions.RemoveEmptyEntries);

            int length = Math.Min(absoluteFilePathParts.Length, baseDirectoryParts.Length);

            int offset = 0;

            for (int i = 0; i < length; i++)
            {
                if (absoluteFilePathParts[i].Equals(baseDirectoryParts[i], StringComparison.Ordinal))
                    offset++;
                else break;
            }

            if (0 == offset)
            {
                if (!absoluteFilePath.StartsWith(directorySeparator)) // Linux
                    throw new ArgumentException("Paths do not have a common base!");
            }

            var relativePath = new StringBuilder();

            for (int i = 0; i < baseDirectoryParts.Length - offset; i++)
            {
                relativePath.Append("..");
                relativePath.Append(Path.DirectorySeparatorChar);
            }

            for (int i = offset; i < absoluteFilePathParts.Length - 1; i++)
            {
                relativePath.Append(absoluteFilePathParts[i]);
                relativePath.Append(Path.DirectorySeparatorChar);
            }

            relativePath.Append(absoluteFilePathParts[absoluteFilePathParts.Length - 1]);

            return relativePath.ToString();
        }


Кто может предложить вариант лучше или здесь увидит проблемы?

З.Ы.
Пока писал, уже увидел одну проблему -- сравнение папок идет с учетом регистра, что верно только для Linux, но не верно для Windows...

06.09.2017 посоветуйте либу 3d
 
2 основные задачи

1. протестировать intersection 2х bounding boxes, каждый задан двумя точками MinPoint и MaxPoint.
2. нормализовать координаты одного относительно другого

06.09.2017 Путь к файлу в конфиге: / или \
 
В Windows путь указывается через \. Хотя и / работает, это типа альтернативный сепаратор.

А в Linux только /

Получается с целью универсальности нужно забывать про \ как файловый разделить и использовать только /?

Могут ли с этим быть какие-либо проблемы?

03.09.2017 Попинайте метод локализации приложений
 
Вот к чему пришел:

1. Избавляемся от ключей. Вместо ключа (типа MainPageHeaderText1) юзать сам текст (ака "My Cool Service"). Ключи -- лишняя сущность. Они допустимы только когда текста реально много.

2. Одного текста не достаточно -- нужна еще и категория, иначе сложно переводить (не ясно к чему относится). Т.е. в итоге присвоение строке локализованного значения выглядит примерно так:

headerText = Translate(nameof(Page1), "My Cool Service");


При желании вместо "My Cool Service" можно указать и ключ, если текст очень длинный.

3. Список на локализацию должен формироваться автоматически. Т.е. открыли страницу а перевода для фразы "My Cool Service" еще нет. По умолчанию отдается то что в коде и сразу же создается запись в таблице переводов (с пустым переводом, конечно). Т.е. чтобы собрать полный список на перевод -- вам всего лишь нужно пройтись по всем возможным формам приложения (а без этого и не протестите).

Т.е. вручную не нужно вносить "My Cool Service" в базу -- оно там само появится, как только выполнится Translate(nameof(Page1), "My Cool Service"). А далее можете отдавать переводчику все что есть в базе. Если там появилось не все -- значит тестеры открыли не все страницы и/или протестировали не все возможные ситуации.

Критика?

31.08.2017 PerformanceCounter и права доступа в IIS
 
Есть простейшее приложение в виду WCF сервиса, которое должно прочитать несколько метрик (PerformanceCounter) и отдать их значения по запросу. Пока все в студии — работает. Как выкладывается сборка на IIS — ошибка "нет доступа к реестру Global". Понятно, что нужно задать права. Но я совершенно не разбираюсь в настройках IIS Где и какие именно права задать надо?
P.S. В коде PerformanceCounterPermission присутствует.

30.08.2017 WCF сервис под IIS. Проблемы производительности.
 
... уже всю голову сломал... Может у кого есть какие соображения?

Вообщем, имеется WCF сервис, который имеет ровно один метод,и этот метод делает Task.Delay(5000).Wait() — ждет пять секунд и возвращает результат.
Сервис хостится под честным IIS (window 10)

Есть клиент, который в 10 потоках, одновременно дергает этот метод.

Наблюдаю такую картину:
1. Запустилось десять потоков, случилось десять запросов к сервису
2. Через пять секунд только ТРИ(!) клиентских потока получили ответ.
3. Еще через пять секунд еще три клиентских потока получили ответ.
4. .. и так далее.

Как с этим бороться? Есть такое ощущение, что во всем виноват IIS, ибо:

1. Если запускать сервис как self-hosted — то все работает как надо — через пять секунд все 10 клиентский запросов получают ответ.
2. Если увеличить число рабочих потоков пула IIS например до 2, до через пять секунд ответ получают уже шесть клиентских запросов. Но webgarden не вариант.

Код примерно такой:

Сервис

    [ServiceContract]
    public interface IService1
    {

        [OperationContract]
        string GetData(string context, int value);
    }

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)]
    public class Service1 : IService1
    {
        private int instance;

        public string GetData(string context, int value)
        {
            Interlocked.Increment(ref instance);
            var debugOutput = string.Format("SERVICE. Context: '{0}' {1}, Thread: {2}, Instance: {3}, Time: {4}", context, value,
                Thread.CurrentThread.ManagedThreadId, instance, DateTime.Now.ToLongTimeString());
            Debug.WriteLine(debugOutput);
           
            Task.Delay(5000).Wait();

            return string.Format("response: {0}", value);
        }
    }


Клиент
    class Program
    {
        static void Main(string[] args)
        {
            ThreadCall(10, 1);
        }

        private static void ThreadCall(int threadCount, int callsPerThread)
        {
            var tasks = new List<Func<Task>>();
            for (var i = 0; i < threadCount; i++)
            {
                var context = "thread_" + i;
                tasks.Add(() => Task.Factory.StartNew(() => SequentalCall(context, callsPerThread)));
            }
            Task.WaitAll(tasks.Select(x => x()).ToArray());
        }

        static void SequentalCall(string context, int count)
        {
            for (var i = 0; i < count; i++)
            {
                using (var client = new TestServiceReference.Service1Client())
                {
                    Console.WriteLine("thread: {0}", Task.CurrentId);
                    var sw = Stopwatch.StartNew();
                    var r = client.GetData(context, i);
                    WriteResult(sw.ElapsedMilliseconds, context, i, r);
                }
            }
        }

        private static void WriteResult(long elapsedMs, string context, int value, string result)
        {
            Console.WriteLine("[{0}: {1} ms] call ({2}) = '{3}'", context, elapsedMs, value, result);
        }
    }



конфиги стандартные.
добавлял в behavior

<serviceThrottling maxConcurrentCalls="100" maxConcurrentInstances="100" maxConcurrentSessions="100"/>


не помогло

29.08.2017 Как получить все символы, которые можно ввести с клавиатуры?
 
Всем привет!

Subj, собственно
Нужен простой способ получить массив всех символов (не управляющих кодов и прочих Del, Home et cetera), которые можно ввести с клавиатуры на русском
И такой же на английском

Спасибо