Веб-задание Azure по запросу не получает правильно отформатированную сериализованную строку json

У меня есть веб-задание по запросу с сайтом asp.net mvc, развернутым в Azure. Веб-задание пытается отправить электронную почту с помощью sendgrid.

Пользователи моего сайта заполняют форму, при желании прикрепляют файл и нажимают отправить. На стороне сервера я собираю все данные, сериализую их в json, используя Newtonsoft.Json. И мое веб-приложение, и веб-задание используют одну и ту же версию Newtonsoft.Json.

<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net47" />

Затем я отправляю сериализованные данные в свою веб-работу, используя аргументы

  private static void TrySendEmail(Customer customer)
    {
        using (WebClient client = new WebClient())
        {
            string responsebody = Encoding.UTF8.GetString(client.UploadValues(ConfigurationManagerExtension.WebJobUrl,
                "POST",
                new System.Collections.Specialized.NameValueCollection
                {
                    {"email",JsonConvert.SerializeObject(CreateCustomerEmail(customer)) }
                }));
        }
    }

Сериализованные данные получаются моим веб-заданием, которое пытается десериализовать их с помощью Newtonsoft.Json и отправить электронное письмо с помощью sendgrid.

При запуске веб-задания в Azure я получаю сообщение об ошибке Необработанное исключение: System.AggregateException: произошла одна или несколько ошибок. ---> Newtonsoft.Json.JsonReaderException: Недопустимый символ идентификатора свойства JavaScript: }. Путь '', строка 1, позиция 6. в ABCD.Background.Program.d__4.MoveNext() в C:\Projects\ABCD\ABCD.Background\Program.cs:строка 25

Строка 25

  DeserializedCustomer customer = JsonConvert.DeserializeObject<DeserializedCustomer>(email);

Теперь я тщетно пытался подключить отладчик к этому веб-заданию, поскольку он по требованию

Затем я просто скопировал функцию веб-задания в частную функцию в моем контроллере, чтобы проверить, работает ли десериализация в моем веб-приложении. Я запустил свое веб-приложение локально и, к удивлению, оно работает!!!.

В чем может быть проблема, Newtonsoft.Json работает в приложении asp.net mvc, но не в веб-задании по запросу, развернутом в Azure?

Помощь

Обновлять

Добавлено ведение журнала для веб-задания с использованием

  Console.WriteLine($"SerializedEmail - {serializedEmail}");

Результирующая трассировка


[08/28/2017 11:39:44 > 1a8d37: SYS INFO] Status changed to Initializing
[08/28/2017 11:39:44 > 1a8d37: SYS INFO] Job directory change detected: Job file 'ABCD.Backgr.exe' timestamp differs between source and working directories.
[08/28/2017 11:39:45 > 1a8d37: SYS INFO] Run script 'ABCD.Backgr.exe' with script host - 'WindowsScriptHost'
[08/28/2017 11:39:45 > 1a8d37: SYS INFO] Status changed to Running
[08/28/2017 11:39:45 > 1a8d37: INFO] SerializedEmail - {email}
[08/28/2017 11:39:45 > 1a8d37: ERR ] 
[08/28/2017 11:39:45 > 1a8d37: ERR ] Unhandled Exception: System.AggregateException: One or more errors occurred. ---> Newtonsoft.Json.JsonReaderException: Invalid JavaScript property identifier character: }. Path '', line 1, position 6.
[08/28/2017 11:39:45 > 1a8d37: ERR ]    at Newtonsoft.Json.JsonTextReader.ReadUnquotedPropertyReportIfDone(Char currentChar, Int32 initialPosition)
[08/28/2017 11:39:45 > 1a8d37: ERR ]    at Newtonsoft.Json.JsonTextReader.ParseUnquotedProperty()

Обновлять

Почему сообщение не принимается должным образом лазурным веб-заданием по запросу?

Обновлять

Отправлен простой объект с веб-клиентом на лазурную веб-работу

  new System.Collections.Specialized.NameValueCollection
                {
                    {"email",JsonConvert.SerializeObject(new {Email = "[email protected]"}) }
                }));

Лог показывает то же самое

    [08/28/2017 11:39:45 > 1a8d37: INFO] SerializedEmail - {email}

Это веб-клиент или kudu scm?

Обновлять

Чтобы получить параметр email, я делаю это, но ничего не получаю в своем веб-задании

string serializedEmail = Environment.GetEnvironmentVariable("WEBJOBS_COMMAND_ARGUMENTS");
        if (string.IsNullOrWhiteSpace(serializedEmail))
        {
            serializedEmail = args[0];
        }

Тем не менее я не получаю сериализованное электронное письмо, отправленное asp.net mvc.


person Hamza Ahmed Zia    schedule 28.08.2017    source источник
comment
Сократите это до минимально воспроизводимого примера. Учитывая, что DeserializeObject терпит неудачу, весь последующий код не имеет значения. Весьма вероятно, что ваш JSON на самом деле не извлекается должным образом - вы должны зарегистрировать значение email в своем методе перед его десериализацией. Я подозреваю, что это не то, что вы ожидаете.   -  person Jon Skeet    schedule 28.08.2017
comment
@JonSkeet Зарегистрированное значение электронной почты в веб-задание, и это не то, что я ожидаю. Проблема в том, как Куду получает сообщение от веб-клиента?   -  person Hamza Ahmed Zia    schedule 28.08.2017
comment
Понятия не имею, но теперь вы можете сузить свой вопрос до этого аспекта, а не до десериализации JSON.   -  person Jon Skeet    schedule 28.08.2017
comment
@JonSkeet Конечно, я обновлю вопрос. Спасибо   -  person Hamza Ahmed Zia    schedule 28.08.2017


Ответы (1)


Насколько я знаю, если вы хотите передать параметры запускаемым веб-заданиям. Вы должны следовать приведенным ниже типам.

https://{yourwebsitename}.scm.azurewebsites.net/api/triggeredwebjobs/{webjobsname}/run?arguments=yourarugment

Кроме того, если вы используете консольное приложение в качестве веб-задания. Консольное приложение, получившее аргументы, удалит кавычки внутри JSON.

Как это. Если вы отправите этот json в файл webjobs args.

{"Name":"[email protected]"}

Полученная строка:

SerializedEmail - {Name:[email protected]}

Поэтому вы должны изменить преобразованную строку, используя приведенные ниже коды.

  string para = JsonConvert.SerializeObject(new Customer { Name = "[email protected]" });

    string escapedString = para.Replace("\"", "\\\"");
    string url = @"https://{yourwebappname}.scm.azurewebsites.net/api/triggeredwebjobs/{webjobsname}/run?arguments=" + escapedString;
    var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
    httpWebRequest.Method = "POST";
    httpWebRequest.ContentLength = 0;
    //you could find the user name and password in the webjobs property
    string logininforation = "${username}:{password}";
    byte[] byt = System.Text.Encoding.UTF8.GetBytes(logininforation);
    string encode = System.Convert.ToBase64String(byt);

    httpWebRequest.Headers.Add(HttpRequestHeader.Authorization, "Basic " + encode);


   HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse() ;

Результат:

введите здесь описание изображения

person Brando Zhang    schedule 29.08.2017
comment
Большое спасибо за то, что указали мне правильное направление. Ваш код работал почти безупречно (единственное изменение в том, что мне не нужно было экранировать сериализованную строку. Одна вещь, которую я должен отметить для других, заключается в том, что при создании объекта электронной почты я возвращал объект, поскольку параметр JsonConvert.SerializeObject был объектом. Когда я обновил метод, чтобы вернуть конкретный тип, ваш код начал работать без нареканий Большое спасибо. - person Hamza Ahmed Zia; 07.09.2017