Обработка недействительного тела при получении почтового запроса в Web Api - PullRequest
1 голос
/ 12 марта 2019

У меня есть третья сторона, которая будет отправлять запросы Post на службу Web Api, которую я создаю.

У меня есть такая функция, как

public returnObject PostFromThirdPartyObject(ThirdPartyObject JSONobj)
{
    // Process Object
    return returnObject;
}

Это нормально работает, когда я отправляю правильный объект.

Проблема в том, что при отправке недействительного объекта ThirdPartyObject заполняется нулями.

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

Как я могу обработать тело сообщения, которое не соответствует ожидаемому типу?


Редактировать: Код, используемый для проверки в случае необходимости изменения

string body = JsonConvert.SerializeObject(ThirdPartyObject);
var cfReq = (HttpWebRequest)WebRequest.Create(url);
cfReq.ContentType = "application/json";
cfReq.Method = "Post";
cfReq.ContentLength = body.Length;
var byteArray = Encoding.UTF8.GetBytes(body);
var stream = cfReq.GetRequestStream();
stream.Write(byteArray, 0, body.Length);

var httpResponse = (HttpWebResponse)cfReq.GetResponse();
var stringResponse = string.Empty;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
    stringResponse = streamReader.ReadToEnd();
}

РЕДАКТИРОВАТЬ 2: действительно плохой обходной путь с использованием объекта, надеюсь, кто-то может опубликовать более правильный путь

public Status PostFromThirdPartyObject([FromBody] object sObject)
{
    ThirdPartyObject obj = null;
    string sRequest = null;
    try
    {
        sRequest = JsonConvert.SerializeObject(sObject);
        LogRequest(sRequest);
        var setting = new JsonSerializerSettings();
        setting.MissingMemberHandling = MissingMemberHandling.Error;
        obj = JsonConvert.DeserializeObject<ThirdPartyObject>(sRequest, setting);
    }
    catch
    {
        if (sObject != null)
        {
            return Error
        }
        else
        {
            return NullError
        }
    }
    return processThirdPartyObject(obj);
}

Ответы [ 3 ]

0 голосов
/ 12 марта 2019

Будут некоторые хорошие варианты, но сейчас вы можете ожидать поток в качестве входных данных и читать его в виде строки. у вас есть именно то, что ваш клиент разместил в этой строке. Вы можете затем десериализовать эту строку в ThirdPartyObject, используя Newtonsoft.Json.JsonConvert, например JsonConvert.DeserializeObject<ThirdPartyObject>(inpString)

Ваша функция может быть такой:

public returnObject PostFromThirdPartyObject(Stream jsonStream)
{
        string sRequest = String.Empty;
        StreamReader stmRequest = new StreamReader(input, System.Text.Encoding.UTF8);
        sRequest = stmRequest.ReadToEnd();
        ThirdPartyObject obj = null;

        try{
            obj = JsonConvert.DeserializeObject<ThirdPartyObject>(sRequest)
           }
        catch
        {
           //you have the object posted by your client in sRequest
           //do whatever you want
        }

    // obj is your object to process
    // Process Object
    return returnObject;
}

вашему клиенту не нужно ничего менять в конце.

0 голосов
/ 12 марта 2019

Попробуйте с ModelState.IsValid ():

public returnObject PostFromThirdPartyObject([FromBody] ThirdPartyObject JSONobj)
{
    if(!ModelState.IsValid()) {
        // Do someting
    }
    // Process Object
    return returnObject;
}
0 голосов
/ 12 марта 2019

Чтобы расширить ответ Шауката Сарвара, вы можете получить доступ к телу из HttpContext.

public returnObject PostFromThirdPartyObject(ThirdPartyObject JSONobj)
{
    var content = new System.IO.StreamReader(HttpContext.Current.Request.InputStream /*, Encoding here if necessary */)
                    .ReadToEnd();

    // Process Object
    return returnObject;
}

Не забудьте использовать соответствующую кодировку в StreamReader (UTF8, скорее всего).

Возможно, вы также захотите взглянуть на ModelState.IsValid, как сказал другой ответ. Просто пометьте все необходимые свойства в вашей модели как [Required] (в противном случае ModelState.IsValid всегда будет истинным) и получите необработанное содержимое недопустимого запроса для его сохранения.

public returnObject PostFromThirdPartyObject(ThirdPartyObject JSONobj)
{
    if (!ModelState.IsValid)
    {
        var content = new StreamReader(HttpContext.Current.Request.InputStream /*, Encoding here if necessary */)
                .ReadToEnd();

        // Do something with the raw content here

        return BadRequest(ModelState);
    }

    // Process Object
    return returnObject;
}

См. Также: Проверка модели в ASP.NET Web API

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...