Base solution for your next web application
Open Closed

Content Type other than JSON #4713


User avatar
0
fguo created

I am using Core+Angular version 5.1.0. Usually, I build APIs by adding a Service class inheritance from AppServiceBase. APIs built in this way only handle JSON content type, I guess. Now, I need to provide a POST API for 3rd party. It must accept input and return object with content-type other than JSON, such as "application/x-www-form-urlencoded". Can you advise how to specify other content type in service class, or any other approach with ASP.NET Zero?

Thanks,


6 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    @fguo you can create a Controller in your Web project. It will be served as API as well.

  • User Avatar
    0
    fguo created

    I tried that. I created an Controller in Web.Core/Controllers, but I have to inherit ControllerBase, otherwise it cannot be routed, and popup error while the swagger opens. If I inherit ControllerBase, the input header as "--header 'Content-Type: application/json-patch+json'", no mater how I manually set the content-type. Here is my test code:

    using Microsoft.AspNetCore.Mvc;
    using Twilio.AspNet.Mvc;
    using Twilio.Rest.Api.V2010.Account;
    using Twilio.TwiML;
    using Twilio.TwiML.Messaging;
    
    namespace SNet.Web.Controllers
    {
        [Route("api/[controller]/[action]")]
        public class SmsController : SNetControllerBase
        {
            private TwilioController m_del;
    
          public static implicit operator TwilioController(SmsController type)
            {
                return (type.m_del);
            }
    
            [HttpPost]
            [Produces("text/xml")]
            public TwiMLResult ReceiveSms([FromBody] MessageResource request)
            {
                HttpContext.Response.Headers["Content-Type"] = "text/xml";
                HttpContext.Request.Headers["Content-Type"] = "text/xml";
                
                var messagingResponse = new MessagingResponse();
                messagingResponse.Message("The Robots are coming! Head for the hills!");
    
                return new TwilioController().TwiML(messagingResponse); //m_del.TwiML(messagingResponse);//m_del always null
            }
        }
    }
    

    I just tried to build an .NET app from scratch. The similar Controller works:

    using System.Web.Mvc;
    using Twilio.AspNet.Mvc;
    using Twilio.TwiML;
    namespace TwilioReceiver.Controllers
    {
    	public class SmsController : TwilioController
    	{
    		[HttpPost]
    		public TwiMLResult Index()
    		{
    			var messagingResponse = new MessagingResponse();
    			messagingResponse.Message("Testing...");
    
    			return TwiML(messagingResponse);
    		}
    	}
    }
    

    This API is for 3rd party Twilio to callback. I have to follow Twilio's requirement on input and return type. I wonder how to merge this controller into ASPNETZero package. Can you advise me some thing more?

    Thanks,

  • User Avatar
    0
    alper created
    Support Team

    hi,

    you have two options

    1- The Xml formatters are not added by default. You need to include the package Microsoft.AspNetCore.Mvc.Formatters.Xml which has XmlSerializerInputFormatter, XmlSerializerOutputFormatter, XmlDataContractSerializerInputFormatterand XmlDataContractSerializerOutputFormatter

    2- Set return type of your method to ActionResultand serialize the TwiMLResultclass to string. so when you return this string it must definitely work.

  • User Avatar
    0
    bbakermmc created

    We use actionresult with twilio and have no issues.

  • User Avatar
    0
    bbakermmc created

    I think they finally released a helper nuget that works with .netcore 2.0 But we just created a DTO

    [DontWrapResult]
            [RequiresFeature(AppFeatures.Twilio)]
            public async Task<IActionResult> InboundRequestWithAccountSId(TwilioRequestDTO input)
            {
                if (!CheckFeatureValue(input.AccountSid, AppFeatures.Twilio_AccountSId))
                {
                    Logger.Error(string.Format("{0} accountsid provided, expected {1}",
                        input.AccountSid, FeatureChecker.GetValue(AppFeatures.Twilio_AccountSId)));
    
                    throw new UserFriendlyException("Key not valid.");
                }
    
                if (input.NumMedia.HasValue && input.NumMedia > 0)
                    AddAttachments(input);
    
                await Create(input, Direction.Inbound, Method.Twilio);
    
                return EmptyResponse();
            }
    
  • User Avatar
    0
    fguo created

    Thank you! I just tried installing Twilio.AspNet.Core. It works! Here is my test controller code:

    using Microsoft.AspNetCore.Mvc;
    using Twilio.AspNet.Common;
    using Twilio.AspNet.Core;
    using Twilio.TwiML;
    
    namespace Project.Web.Controllers
    {
        [Route("api/[controller]/[action]")]
        public class SmsController : ProjectControllerBase
        {
            [HttpPost]
            public TwiMLResult ReceiveSms(SmsRequest request)
            {
                var messagingResponse = new MessagingResponse();
                messagingResponse.Message("The Robots: " + request.Body);
    
                return new TwiMLResult(messagingResponse);
            }
        }
    }
    

    It's nice to use Twilio.AspNet.Common.SmsRequest. I can get all info from Twilio by this type.

    I also tried to merge the above "ReceiveSms" method into /api/services which is ultimately derived from "AbpServiceBase". It does NOT work there. I cannot use "SmsRequest" as input type. The workaround is using string type of input, such as:

    public TwiMLResult ReceiveSms(string from, string body){}
    

    Do you have any idea how to use Twilio type "SmsRequest" as input here?

    At least, I got a workaround. Thank you very much!!