Ksoap2 forming SoapObject - ksoap2

I need to generate a SoapObject. here is my code --
SoapObject request = new SoapObject(namespace, method);
SoapObject r = new SoapObject(namespace, "request");
r.addProperty("email", email);
request.addSoapObject(r);
my code generates the following
<Info xmlns=NAMESPACE >
<request>
<email>id#gmail.com</email>
</request>
</Info>
but the request body needs to be like this
<con:Info>
<!--Optional:-->
<con:request>
<typ:email>id#gmail.com</typ:email>
</con:request>
</con:Info>
what should i do to include that typ:'s equivalent in my code?

The code you want to generate lacks namespace declarations, they are probably somewhere up in the tree.
The namespace for email seems to be different than the namespace for the rest. Your code needs to reflect that to generate equivalent XML.
p.s. You could try something like
PropertyInfo emailType = new PropertyInfo();
emailType.name = "email";
emailType.namespace = emailNamespace;
emailType.type = String.class;
r.addProperty(emailType, email);
kSOAP was written for J2ME, which does not support reflection, and it has some complexities to work around this. I don' think I can really recommend it on Android:
For simple cases, one could just use the DOM
For complex cases, a serialization library similar to GSON might make more sense (not sure if something similar to GSON exists for SOAP object serialization).

Related

Retrieve file attachment from MMS via ASP.NET MVC controller

I'm trying out the Twilio service to interact with individuals via SMS/MMS. I've sorta figured out how to send MMS messages to initiate the "conversation" and that seems to be working well. However, now I'm trying to build a system to respond to the incoming messages on my SMS/MMS-enabled test number. I'm working from one of the examples I found on the Twilio documentation site to build an ASP.NET MVC web service to handle the conversation (VB.NET):
Imports System.Web.Mvc
Imports Twilio.AspNet.Common
Imports Twilio.AspNet.Mvc
Imports Twilio.TwiML
Namespace Controllers
Public Class SMSController
Inherits TwilioController
' GET: SMS
Function Index(ByVal IncomingSMS As SmsRequest) As TwiMLResult
Dim SMSResponse As New MessagingResponse
Dim SMSMessage As String = IncomingSMS.Body
Dim JediCode As String = "There is no emotion, there is peace."
Dim SithCode As String = "Peace is a lie. There is only Passion."
JediCode += vbCrLf & "There is no ignorance, there is knowledge."
JediCode += vbCrLf & "There is no passion, there is serenity."
JediCode += vbCrLf & "There is no chaos, there is harmony."
JediCode += vbCrLf & "There is no death, there is the Force."
SithCode += vbCrLf & "Through Passion, I gain Strength."
SithCode += vbCrLf & "Through Strength, I gain Power."
SithCode += vbCrLf & "Through Power, I gain Victory."
SithCode += vbCrLf & "Through Victory my chains are Broken."
SithCode += vbCrLf & "The Force shall free me."
If SMSMessage IsNot Nothing Then
If SMSMessage.ToUpper.Trim = "JEDI" Then
SMSResponse.Message(JediCode)
ElseIf SMSMessage.ToUpper.Trim = "SITH" Then
SMSResponse.Message(SithCode)
Else
SMSResponse.Message("Ahsoka? Is that you?")
End If
Else
SMSResponse.Message("What did you want to know?")
End If
Return TwiML(SMSResponse)
End Function
End Class
End Namespace
Yes, this is all just "play" stuff that I'm using for testing and will eventually be replaced with something more appropriate to the purpose, but I want to try and figure it all out before I get too deep into the reality of things.
I've set up the site on my IIS server, registered the DNS, and even gotten my SSL certificate set up. Everything seems to be working great with my simple testing so far, but there are a couple of things that I still haven't been able to figure out so far and I'm hoping someone here can point me in the right direction.
I'll ask each as a separate question, but here's the first: how do I retrieve the attachment from an MMS message?
I'd like to be able to receive PDFs (and possibly other file types) and pass them along via email to an appropriate individual or department. I know how to do the emailing, but I haven't been able to find appropriate documentation for how to retrieve the attachment(s) in the MMS message to actually include it in that email process.
When I try to access the properties of the IncomingSMS (SmsRequest) object, I don't find any reference to Media in any of them - no NumMedia, no MediaUri, nothing. There doesn't appear to be an MmsRequest object type (that I've found yet, anyway).
What am I overlooking here to be able to retrieve the PDF I sent to my test number for further processing? Should I change the method's definition to accept the object as a MessageResource or something?
EDIT: I forgot to mention that I checked the Twilio console and see that the message was apparently received successfully with the attachment, so I know that at least that part is working properly.
I've asked a second, related question that goes along with this one to help "finalize" some things for our goals.
The SmsRequest class that you're using comes from the Twilio helper library for ASP.NET which aims to make it easier to integrate Twilio into ASP.NET. However, the SmsRequest and other classes do not cover all possible webhook parameters. If there's parameters missing from the class, you can still retrieve the parameters manually instead of relying on MVC Model Binding.
Based on this C# sample, I created a VB.NET sample to show how to receive and save incoming MMS files:
Imports System.IO
Imports System.Net.Http
Imports System.Threading.Tasks
Imports MimeTypes
Imports Twilio.AspNet.Mvc
Imports Twilio.TwiML
Imports Twilio.TwiML.Messaging
Public Class HomeController
Inherits TwilioController
Shared httpClient As HttpClient = New HttpClient
Async Function Index() As Task(Of TwiMLResult)
Dim response As New MessagingResponse
Dim message As New Message
Dim numMedia = Short.Parse(If(Request.Form.Get("NumMedia"), 0))
If numMedia = 0 Then
response.Message("No file received.")
Return TwiML(response)
End If
For mediaIndex As Integer = 0 To numMedia - 1
Dim mediaUrl = Request.Form.Get($"MediaUrl{mediaIndex}")
Dim contentType = Request.Form.Get($"MediaContentType{mediaIndex}")
Dim saveFilePath = Server.MapPath(String.Format(
"~/App_Data/{0}{1}",
Path.GetFileName(mediaUrl),
MimeTypeMap.GetExtension(ContentType)
))
Await DownloadUrlToFileAsync(mediaUrl, saveFilePath)
Next
response.Message("File received.")
Return TwiML(response)
End Function
Private Async Function DownloadUrlToFileAsync(mediaUrl As String, saveFilePath As String) As Task
Dim Response = Await httpClient.GetAsync(mediaUrl)
Dim httpStream = Await Response.Content.ReadAsStreamAsync()
Using fileStream As Stream = IO.File.Create(saveFilePath)
Await httpStream.CopyToAsync(fileStream)
Await fileStream.FlushAsync()
End Using
End Function
End Class
You can probably simplify the code a little by assuming there's only one file going to be sent over MMS, but it's a good idea to handle other cases too.
To get the correct file extension, I'm using this
MimeTypeMap library, but you can roll your own solution.
By default the files from the incoming MMS are publicly available via the MediaUrl{mediaIndex} URL, but it's a good idea to turn on Basic Auth for these media files.
If you're turning on Basic Auth for media files, you'll need to add the authentication header to the HTTP requests, like this:
Imports System.IO
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Threading.Tasks
Imports MimeTypes
Imports Twilio.AspNet.Mvc
Imports Twilio.TwiML
Imports Twilio.TwiML.Messaging
Public Class HomeController
Inherits TwilioController
Shared httpClient As HttpClient = CreateHttpClient()
Private Shared Function CreateHttpClient() As HttpClient
Dim client As New HttpClient
Dim appSettings As NameValueCollection = ConfigurationManager.AppSettings
If Boolean.Parse(If(appSettings.Get("TwilioUseBasicAuthForMedia"), False)) Then
Dim authString = $"{appSettings.Get("TwilioAccountSid")}:{appSettings.Get("TwilioAuthToken")}"
authString = Convert.ToBase64String(Encoding.ASCII.GetBytes(authString))
client.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Basic", authString)
End If
Return client
End Function
...
End Class
I'm retrieving the TwilioUseBasicAuthForMedia, TwilioAccountSid, and TwilioAuthToken from the Web.config appSettings.
(Make sure you don't check those secrets into source control, and use UserSecretsConfigBuilder instead, to securely set the secrets).
Here's the source code on GitHub.
You're welcome to submit a GitHub issue and/or a PR to add support for these missing parameters to the SmsRequest. Tho, it wouldn't be as easy as normal model binding because the number of parameters increases as more files are sent over MMS.

What is the alternative for jsonp format in MVC core?

I need to return result in jsonp format while I'm using asp.net MVC Core.
In asp.net MVC we can use MVC.jsonp dll an it's work fine but what is the alternative in MVC Core because I can't find any.
public JsonpResult FunctionalitesTblList()
{
var settings = new JsonSerializerSettings();
return Jsonp(Rows, settings);
}
There was no built in ability to handle JSONP with MVC, so you were always using a third-party addition. Apparently, that library is incompatible with .NET Core. Therefore, your option is to find a similar library that is compatible or choose some other approach.
#CuongLe is correct that CORS is a better approach overall, so you should definitely investigate that. However, if you insist on JSONP, it's so simple to implement manually, you don't really need a library.
Simply, all JSONP is a is JSON passed into a "callback" function, specified by the client. In other words, if the callack was specified as "mycallback", the response should just look like:
mycallback({ "foo": "bar" });
As a result, your code simply becomes:
string json = null;
using (var ms = new MemoryStream())
{
var serializer = new DataContractJsonSerializer(typeof(Foo));
serializer.WriteObject(ms, foo);
json = Encoding.UTF8.GetString(ms.ToArray());
}
var jsonp = String.Format("{0}({1});", callback, json);
Response.ContentType = "application/javascript";
return Content(jsonp);

grails xml unmarshalling

Since Grails 1.1.x, they have supported XML and JSON unmarshalling for REST requests. I can't seem to get this working in version 2.1.0. Here is the relevant files from the example project I am using to test the functionality:
UrlMappings.groovy
static mappings = {
"/$action/$id?"(controller:'verification',parseRequest:true)
"/"(view:"/index")
"500"(view:'/error')
}
Tester.groovy
class Tester {
String name
String vendor
String toString() {
return "$name $vendor"
}
}
VerificationController.groovy
class VerificationController {
def save() {
Tester tester = new Tester(params.tester)
log.error "Tester = ${tester}"
log.error "Request XML = ${request.XML}"
}
}
XML send with REST call
<?xml version="1.0" encoding="utf-8"?>
<tester>
<name>Windows</name>
<vendor>Microsoft</vendor>
</tester>
When I pass the XML in, the controller log statements output this:
Tester = null null
Request XML = WindowsMicrosoft
My bewilderment would be in why it recognizes it as XML (by putting it in the XML field of the request) but won't parse it and put it in params as defined here
After trying for a few hours with the same problem I found a solution for me.
My problem was that I didn't had a content-type defined in my REST call.
So if you add content-type: application/xml to your rest call it should work.
I had the same problem, with almost exactly the same setup. I believe your problem could lie within the UrlMapping configuration. Initially I had the following.
"/rest/airport/$iata?"(controller: "airport", action: "restHandler", parseRequest: "true")
When I PUT/POST XML to that URI, it would show up correctly in request.XML, but it would never show up in the params object. I then realized I had the parseRequest boolean in quotes. Removing that fixed the issue.
"/rest/airport/$iata?"(controller: "airport", action: "restHandler", parseRequest: true)
Now, if your code is truly the same as what you have above, your problem may not be exactly the same. However, what might help is making some kind of change to your UrlMappings to see if you could get it working a different way.
At first I thought it might have been the single quotes you had, but that seemed to work fine either way I tried it. So, I would suggest just changing your URI mapping to something else and be very picky about the formatting. In the end it was just a minor formatting issue in the UrlMappings.groovy file that fixed my problem.

Using the Json.NET serializer in an MVC4 project

I'm starting to learn Json.NET, but I'm having trouble using its serializer. I have a new MVC4 project with a Web.API service:
public class PTE_TestsController : ApiController {
PTE_TestsRepository _repository = new PTE_TestsRepository();
// GET /api/PTE_Tests/5
public HttpResponseMessage<string> Get(int id) {
try {
PTE_Test test = _repository.GetTest(id);
return new HttpResponseMessage<string>(JsonConvert.SerializeObject(test));
} catch {
return new HttpResponseMessage<string>(HttpStatusCode.NotFound);
}
}
}
JsonConvert.SerializeObject() works as expected and returns a string. My Web.API controller returns that as part of an HttpResponseMessage. The end result, when viewed in Fiddler, is not JSON data, but JSON data being serialized again (I think):
"{\"ID\":1,\"Name\":\"Talar Tilt\",\"TagID\":1,\"PracticeID\":1,
\"SpecificAreaID\":1,\"TypeID\":1,\"VideoID\":1,\"PicID\":1}"
Does someone know how to turn off the default serializer so I can use Json.NET directly? By the way, I'm not using the default serializer because I can't figure out how to make it work with complex objects (PTE_Test will eventually contain members of type List).
Alternately, it will also solve my problem if someone can explain how to use the default serializer with complex objects. MSDN's explanation didn't help me.
Rick Strahl has a blog on that here with a code that works.
As others have pointed out, you need to create a formatter and replace the DataContractSerializer with the JSON.NET serializer. Although, if you're not in a rush for JSON.NET specifically, rumor has it that next beta/rc is going to have support for JSON.NET built in.
Conceptually, however, you're missing part of the magic of WebAPI. With WebAPI you return your object in it's native state (or IQueryable if you want OData support). After your function call finishes the Formatter's take over and convert it into the proper shape based on the client request.
So in your original code, you converted PTE_Test into a JSON string and returned it, at which point the JSON Formatter kicked in and serialized the string. I modified your code as follows:
public class PTE_TestsController : ApiController {
PTE_TestsRepository _repository = new PTE_TestsRepository();
public HttpResponseMessage<PTE_Test> Get(int id) {
try {
PTE_Test test = _repository.GetTest(id);
return new HttpResponseMessage(test);
} catch {
return new HttpResponseMessage<string>(HttpStatusCode.NotFound);
}
}
}
Notice how your function returns PTE_Test instead of string. Assuming the request came in with a request header of Accept = application/json then the JSON formatter will be invoked. If the request had a header of : Accept = text/xml the XML formatter is invoked.
There's a decent article on the topic here. If you're a visual learner, Scott Gu shows some examples using fiddler in this video, starting around 37 minutes. Pedro Reys digs a little deeper into content negotiation here.
The way to do this is to use formatters.
Check out: https://github.com/WebApiContrib/WebAPIContrib/tree/master/src/WebApiContrib.Formatting.JsonNet.
Json.NET support will be in the RC release of Web API.

Best way to structure the code for an ASP.NET MVC REST API that is decoupled from the data formats?

I am creating a REST API in ASP.NET MVC. I want the format of the request and response to be JSON or XML, however I also want to make it easy to add another data format and easy to create just XML first and add JSON later.
Basically I want to specify all of the inner workings of my API GET/POST/PUT/DELETE requests without having to think about what format the data came in as or what it will leave as and I could easily specify the format later or change it per client. So one guy could use JSON, one guy could use XML, one guy could use XHTML. Then later I could add another format too without having to rewrite a ton of code.
I do NOT want to have to add a bunch of if/then statements to the end of all my Actions and have that determine the data format, I'm guessing there is some way I can do this using interfaces or inheritance or the like, just not sure the best approach.
Serialization
The ASP.NET pipeline is designed for this. Your controller actions don't return the result to the client, but rather a result object (ActionResult) which is then processed in further steps in the ASP.NET pipeline. You can override the ActionResult class. Note that FileResult, JsonResult, ContentResult and FileContentResult are built-in as of MVC3.
In your case, it's probably best to return something like a RestResult object. That object is now responsible to format the data according to the user request (or whatever additional rules you may have):
public class RestResult<T> : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
string resultString = string.Empty;
string resultContentType = string.Empty;
var acceptTypes = context.RequestContext.HttpContext.Request.AcceptTypes;
if (acceptTypes == null)
{
resultString = SerializeToJsonFormatted();
resultContentType = "application/json";
}
else if (acceptTypes.Contains("application/xml") || acceptTypes.Contains("text/xml"))
{
resultString = SerializeToXml();
resultContentType = "text/xml";
}
context.RequestContext.HttpContext.Response.Write(resultString);
context.RequestContext.HttpContext.Response.ContentType = resultContentType;
}
}
Deserialization
This is a bit more tricky. We're using a Deserialize<T> method on the base controller class. Please note that this code is not production ready, because reading the entire response can overflow your server:
protected T Deserialize<T>()
{
Request.InputStream.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(Request.InputStream);
var rawData = sr.ReadToEnd(); // DON'T DO THIS IN PROD!
string contentType = Request.ContentType;
// Content-Type can have the format: application/json; charset=utf-8
// Hence, we need to do some substringing:
int index = contentType.IndexOf(';');
if(index > 0)
contentType = contentType.Substring(0, index);
contentType = contentType.Trim();
// Now you can call your custom deserializers.
if (contentType == "application/json")
{
T result = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(rawData);
return result;
}
else if (contentType == "text/xml" || contentType == "application/xml")
{
throw new HttpException(501, "XML is not yet implemented!");
}
}
Just wanted to put this on here for the sake of reference, but I have discovered that using ASP.NET MVC may not be the best way to do this:
Windows Communication Foundation (WCF)
provides a unified programming model
for rapidly building service-oriented
applications that communicate across
the web and the enterprise
Web application developers today are
facing new challenges around how to
expose data and services. The cloud,
move to devices, and shift toward
browser-based frameworks such as
jQuery are all placing increasing
demands on surfacing such
functionality in a web-friendly way.
WCF's Web API offering is focused on
providing developers the tools to
compose simple yet powerful
applications that play in this new
world. For developers that want to go
further than just exposing over HTTP,
our API will allow you to access all
the richness of HTTP and to apply
RESTful constraints in your
application development. This work is
an evolution of the HTTP/ASP.NET AJAX
features already shipped in .Net 4.0.
http://wcf.codeplex.com/
However I will not select this as the answer because it doesn't actually answer the question despite the fact that this is the route I am going to take. I just wanted to put it here to be helpful for future researchers.

Resources