亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在到達操作方法之前修剪 Request.Body,用于 XML 中的模型綁定

在到達操作方法之前修剪 Request.Body,用于 XML 中的模型綁定

C#
慕容708150 2022-06-12 10:18:04
我有一個以太網到 1-Wire 接口,它會定期發送帶有傳感器數據的 HTTP 帖子。數據主體采用 XML 格式,但不是完全有效的 XML。我無法更改 HTTP 正文,因為它位于嵌入式軟件中。完整的請求正文如下所示: ------------------------------3cbec9ce8f05 Content-Disposition: form-data; name="ServerData"; filename="details.xml" Content-Type: text/plain <?xml version="1.0" encoding="UTF-8"?> <Devices-Detail-Response xmlns="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <PollCount>2739</PollCount> <DevicesConnected>1</DevicesConnected> <LoopTime>1.022</LoopTime> <DevicesConnectedChannel1>0</DevicesConnectedChannel1> <DevicesConnectedChannel2>0</DevicesConnectedChannel2> <DevicesConnectedChannel3>1</DevicesConnectedChannel3> <DataErrorsChannel1>0</DataErrorsChannel1> <DataErrorsChannel2>0</DataErrorsChannel2> <DataErrorsChannel3>0</DataErrorsChannel3> <VoltageChannel1>4.91</VoltageChannel1> <VoltageChannel2>4.92</VoltageChannel2> <VoltageChannel3>4.92</VoltageChannel3> <VoltagePower>5.16</VoltagePower> <DeviceName>Unit 3 OW2</DeviceName> <HostName>EDSOWSERVER2</HostName> <MACAddress>00:00:00:00:00:00</MACAddress> <DateTime>2018-12-12 16:44:48</DateTime> <owd_DS18B20 Description="Programmable resolution thermometer"> <Name>DS18B20</Name> <Family>28</Family> <ROMId>F70000024D85E528</ROMId> <Health>7</Health> <Channel>3</Channel> <RawData>C6004B467FFF0A102A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</RawData> <PrimaryValue>12.3750 Deg C</PrimaryValue> <Temperature Units="Centigrade">12.3750</Temperature> <UserByte1 Writable="True">75</UserByte1> <UserByte2 Writable="True">70</UserByte2> <Resolution>12</Resolution> <PowerSource>0</PowerSource> </owd_DS18B20> </Devices-Detail-Response> ------------------------------3cbec9ce8f05--所以我試圖在它到達動作方法之前刪除'--------...'和Content-Type,以及最后的'--------..'。
查看完整描述

2 回答

?
慕的地6264312

TA貢獻1817條經驗 獲得超6個贊

請求正文表明嵌入式軟件正在發布多部分數據。以下content-disposition意味著它正在發送一個文件details.xml:


------------------------------3cbec9ce8f05

Content-Disposition: form-data; name="ServerData"; filename="details.xml"

Content-Type: text/plain

所以你不需要手動刪除 '-----------------------------3cbec9ce8f05' 和Content-Type=.... 只需使用Request.Form.Files.


此外,正如@ivan-valadares所建議的,您可以使用模型活頁夾來提升重物。但似乎他將所有請求正文視為字符串,然后構造一個XDocument. 一種更優雅的方式是用于XmlSerializer創建強類型對象。此外,IModelBinder 接口沒有public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext). 我們應該BindModelAsync(ModelBindingContext bindingContext)改用。


所以創建一個模型活頁夾如下:


public class EmbededServerDataBinder<T> : IModelBinder

{

    public Task BindModelAsync(ModelBindingContext bindingContext)

    {

        if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); }

        var modelName = bindingContext.BinderModelName ?? "ServerData";


        XmlSerializer serializer = new XmlSerializer(typeof(T));

        var data= bindingContext.HttpContext.Request.Form.Files[modelName];

        if(data == null){ 

            bindingContext.ModelState.AddModelError(modelName,"invalid error");

            return Task.CompletedTask;

        }

        using(var stream = data.OpenReadStream()){

            var o = serializer.Deserialize(stream);

            bindingContext.Result = ModelBindingResult.Success(o);

        }

        return Task.CompletedTask;

    }

}

現在您可以在 Action 方法中使用它:


    [HttpPost]

    public IActionResult Post([ModelBinder(typeof(EmbededServerDataBinder<Ow_ServerModel>))] Ow_ServerModel ServerData)

    {

        return Ok("Working");

    }

注意事項的名稱ServerData。模型綁定器將在 content-disposition 中查找此名稱。


我用你的有效載荷測試它,它按預期工作:

http://img1.sycdn.imooc.com//62a54d3c000179d407750238.jpg

查看完整回答
反對 回復 2022-06-12
?
qq_笑_17

TA貢獻1818條經驗 獲得超7個贊

您正在嘗試使用 ActionFilter 來做到這一點,我建議使用自定義 Binder 并使用正則表達式從請求中提取 de xml。


在 WebApiConfig.cs 中注冊新的自定義 xml 綁定器


public static void Register(HttpConfiguration config)

{

    config.Services.Insert(typeof(ModelBinderProvider), 0,

    new SimpleModelBinderProvider(typeof(XDocument), new XmlCustomBinder()));

}

創建一個自定義活頁夾,它將獲取內容主體并僅提取 xml


public class XmlCustomBinder : IModelBinder

{

    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)

    {

        try

        {

            var parsedXml = actionContext.Request.Content.ReadAsStringAsync().Result;

            Regex regex = new Regex(@"<\?xml.*>", RegexOptions.Singleline);

            Match match = regex.Match(parsedXml);

            if (!match.Success) return false;

            parsedXml = match.Groups[0].Value;

            TextReader textReader = new StringReader(parsedXml);

            XDocument xDocument = XDocument.Load(textReader);

            bindingContext.Model = xDocument;

            return true;

        }

        catch(Exception ex)

        {

            bindingContext.ModelState.AddModelError("XmlCustomBinder", ex);

            return false;

        }

    }

}

控制器代碼,獲取 XDocument (XML) 值


[HttpPost]

[OwServer]

public IActionResult Post([ModelBinder(typeof(XmlCustomBinder))] XDocument xDocument)

{

     return Ok("Working");

}

https://docs.microsoft.com/en-us/dotnet/api/system.xml.linq.xdocument?view=netframework-4.7.2


查看完整回答
反對 回復 2022-06-12
  • 2 回答
  • 0 關注
  • 146 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號