authentication to embed powerbi into aspnetcore 2 mvc - asp.net-core-mvc

there is an excellent example for how to embed powerbi App Owns Data here:
https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-embed-sample-app-owns-data/
however this example is for running on the .net platform
and some of the routines used in the example dont exist for aspnetcore
there is another excellent post about someone attempting to do the same thing:
Embed Power BI Report In ASP.Net Core Website
as well as this one:
https://community.powerbi.com/t5/Developer/Embed-Power-BI-dashboard-in-ASP-Net-core/td-p/273279
however im having trouble even getting the stuff to authenticate
here is how my current code stands:
private static readonly string AuthorityUrl = "https://login.windows.net/common/oauth2/authorize/";
private static readonly string ResourceUrl = "https://analysis.windows.net/powerbi/api";
private static readonly string ApiUrl = "https://api.powerbi.com/";
private static readonly string EmbedUrl = "https://app.powerbi.com/";
private static readonly string ClientId = "xxxxclientid";
private static readonly string Username = "xxxxusername";
private static readonly string Password = "xxxxpass";
private static readonly string GroupId = "xxxxgroup";
private static readonly string ReportId = "xxxxreportid";
public async Task<ActionResult> embed(string username, string roles)
{
var result = new EmbedConfig();
try
{
result = new EmbedConfig { Username = username, Roles = roles };
var error = GetWebConfigErrors();
if (error != null)
{
result.ErrorMessage = error;
return View(result);
}
var authenticationResult = await AuthenticateAsync();
if (authenticationResult == null)
{
result.ErrorMessage = "Authentication Failed.";
return View(result);
}
var tokenCredentials = new TokenCredentials(authenticationResult.AccessToken, "Bearer");
... [the rest is post-authentication stuff, ie powerbi]
}
private static async Task<OAuthResult> AuthenticateAsync()
{
Uri oauthEndpoint = new Uri(AuthorityUrl);
using (HttpClient client = new HttpClient()) {
HttpResponseMessage result = await client.PostAsync(oauthEndpoint, new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("resource", ResourceUrl),
new KeyValuePair<string, string>("client_id", ClientId),
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", Username),
new KeyValuePair<string, string>("password", Password),
new KeyValuePair<string, string>("scope", "openid"),
}));
string content = await result.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<OAuthResult>(content);
}
}
where oAuthResult class is
public class OAuthResult
{
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("scope")]
public string Scope { get; set; }
[JsonProperty("experies_in")]
public int ExpiresIn { get; set; }
[JsonProperty("ext_experies_in")]
public int ExtExpiresIn { get; set; }
[JsonProperty("experies_on")]
public int ExpiresOn { get; set; }
[JsonProperty("not_before")]
public int NotBefore { get; set; }
[JsonProperty("resource")]
public Uri Resource { get; set; }
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
}
i know my credentials work
because i built the original solution in classic .net with them
and they worked swimmingly
now however in this version im receiving this response in AuthenticateAsync (only a portion):
"\r\n\r\n\r\n\r\n\r\n Sign in to your account\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n https://login.windows.net/common/jsdisabled\" />\r\n \r\n https://secure.aadcdn.microsoftonline-p.com/ests/2.1.7382.8/content/images/favicon_a.ico\" />\r\n \r\n "
which is obviously not a JSON response but rather the html for the ms login box
and indeed i managed to render the output and it looks like this
can anyone point me in the proper direction so that
it authenticates properly and sends me a token instead of a login box?
thank you
UPDATE:
ive tried logging in directly through browser url
here is the url im using:
https://login.windows.net/common/oauth2/authorize/?client_id=myid&grant_type=password&username=myun&password=mypw&scope=openid
does the url at least look correct for the non-sensitive info?
still getting the sign in box

You should use: AuthorityUrl = "https://login.windows.net/common/oauth2/token/"
Please see - Embed Power BI Report In ASP.Net Core Website

Related

How to get Auth code in api call post on ruby on rails app from wix api website?

I'm trying to developing a dashboard website for a wix application and I need to connect the website to the wix application.
I have a problem with an api (post) call. I have to fill in several information including the auth code that I don't know where to find.
Here is an image to illustrate the process :
I don't really know what is the wix app marker install, but for the authorization request I did this
$url_oauth = "https://www.wix.com/oauth/access"
response = RestClient::Request.execute(url: $url_oauth, method: :post, body:{grant_type: "authorization_code",client_id:"APP_ID", client_secret:"Secret_key", code:"{Can not find what is this value}"})
#data = JSON.parse(response)
render json: response
Here is the documentation :
Could you help how and where to find this Auth code ?
You will need to make an intermediate web service that will accept webhooks from WIX.
I'll show you the example of C# ASP.Net Core.
STEP 1:
We are waiting for a token from WIX and if it is received, we make a redirect.
private const string AppID = "";
private const string ApiKey = "";
private const string UrlAccess = "https://www.wix.com/oauth/access";
HttpGet("WaitToken")]
public ActionResult GetToken([FromQuery] string token = "")
{
try
{
if (string.IsNullOrWhiteSpace(token))
{
string message = "Your message";
ModelState.AddModelError("TokenNotCorrect", message);
return BadRequest(ModelState);
}
string paramUrl = #"https://your web service/OAuth/api/check/WaitAuthCode";
string urlRedirect = $#"https://www.wix.com/installer/install?token={token}&appId={AppID}&redirectUrl={paramUrl}";
return RedirectPermanent(urlRedirect);
}
catch (WebException ex)
{
ModelState.AddModelError("GetTokenException", ex.Message);
return BadRequest(ModelState);
}
}
STEP 2:
We are waiting for the Auth Code to be received, provided that the user has confirmed the installation of the application.
[HttpGet("WaitAuthCode")]
public async Task<ActionResult> GetAuthCodeAsync([FromQuery] string code = "", string state = "", string instanceId = "")
{
try
{
if (string.IsNullOrWhiteSpace(code))
{
string message = "your message";
ModelState.AddModelError("AuthCodeNotCorrect", message);
return BadRequest(ModelState);
}
var token = new Token(code);
if (!GetAccessToken(ref token))
return BadRequest("your message RefreshToken");
var tokenBase = new TokenBase
{
AppID = instanceId,
Token = token.RefreshToken
};
db.Tokens.Add(tokenBase);
if(await db.SaveChangesAsync() == 0)
return BadRequest("your message");
string urlRedirect = $"https://www.wix.com/installer/token-received?access_token={token.AccessToken}";
return RedirectPermanent(urlRedirect);
}
catch (WebException ex)
{
ModelState.AddModelError("GetAuthCodeException", ex.Message);
return BadRequest(ModelState);
}
}
The AuthCode is valid for 10 minutes, we send a request to receive a Refresh Token. This token must be kept at home, as it will be required in the future to obtain an Access Token.
private bool GetAccessToken(ref Token token)
{
try
{
string json = JsonConvert.SerializeObject(token, Formatting.Indented);
var client = new RestClient(UrlAccess);
var request = new RestRequest();
request.Method = Method.POST;
request.AddHeader("Content-Type", "application/json");
request.AddParameter(string.Empty, json, "application/json", ParameterType.RequestBody);
var response = client.Post(request);
if (response == null)
return false;
token = JsonConvert.DeserializeObject<Token>(response.Content);
if (string.IsNullOrWhiteSpace(token.RefreshToken))
return false;
return !string.IsNullOrWhiteSpace(token.AccessToken);
}
catch (Exception ex)
{
return false;
}
}
Getting an Access Token from a client application:
[HttpGet("WaitAccessToken")]
public async Task<ActionResult<string>> GetAccessToken([FromQuery] string instance = "", string apiKey = "")
{
string message;
var tokenBase = await db.Tokens.FirstOrDefaultAsync(x => x.AppID == instance);
if (tokenBase == null)
{
message = "Your message";
ModelState.AddModelError("AppIdNotFound", message);
return NotFound(ModelState);
}
var token = new Token
{
GrantType = "refresh_token",
RefreshToken = tokenBase.Token
};
if (!GetAccessToken(ref token))
{
message = $"Your message";
ModelState.AddModelError("NotCorrectAccessToken", message);
return BadRequest(ModelState);
}
return new ObjectResult(token.AccessToken);
}
Model Token:
public class Token
{
public Token() { }
public Token(string code) { Code = code; }
[JsonProperty("grant_type")]
public string GrantType { get; set; } = "authorization_code";
[JsonProperty("client_id")]
public string ClientID { get; set; } = "";
[JsonProperty("client_secret")]
public string ClientSecret { get; set; } = "";
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("refresh_token", NullValueHandling = NullValueHandling.Ignore)]
public string RefreshToken { get; set; }
[JsonProperty("access_token", NullValueHandling = NullValueHandling.Ignore)]
public string AccessToken { get; set; }
}
Model Instance:
public class Instance
{
[JsonProperty("instanceId")]
public string InstanceId { get; set; }
[JsonProperty("appDefId")]
public string AppDefId { get; set; }
[JsonProperty("signDate")]
public DateTime SignDate { get; set; }
[JsonProperty("uid")]
public string Uid { get; set; }
[JsonProperty("permissions")]
public string Permissions { get; set; }
[JsonProperty("demoMode")]
public bool DemoMode { get; set; }
[JsonProperty("siteOwnerId")]
public string SiteOwnerId { get; set; }
[JsonProperty("siteMemberId")]
public string SiteMemberId { get; set; }
[JsonProperty("expirationDate")]
public DateTime ExpirationDate { get; set; }
[JsonProperty("loginAccountId")]
public string LoginAccountId { get; set; }
}
Don't forget that to get an Access Token, you will need the application ID on the site where it is installed.
[HttpGet("WixInfo")]
public ActionResult GetWixInfo([FromQuery] string instance = "")
{
try
{
string message;
var base64 = instance.Split(".");
if (base64.Length != 2)
{
message = "Your message";
ModelState.AddModelError("InstanceNotCorrect", message);
return BadRequest(ModelState);
}
var base64EncodedBytes = Convert.FromBase64String(base64[1]);
string json = Encoding.Default.GetString(base64EncodedBytes);
var info = JsonConvert.DeserializeObject<Instance>(json);
message = $"Your message.AppID: {info.InstanceId}";
return Ok(message);
}
catch (Exception ex)
{
ModelState.AddModelError("GetWixInfoException", ex.Message);
return BadRequest(ModelState);
}
}
When a WIX application is launched by a user, you can get the ID of the running application.

How to get result value from WebAPI in Xamarin

public async Task<Customer> GetCustomersAsync(string id)
{
var prod = new Customer();
HttpClient client = new HttpClient();
string url = "https://xxxxxx.com/api/Customers/" + id;
client.BaseAddress = new Uri(url);
HttpResponseMessage response = await client.GetAsync("");
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
prod = JsonConvert.DeserializeObject<Customer>(content);
}
return await Task.FromResult(prod);
}
Class Customer(Models)
public class Customer
{
public string CodeRandom { get; set; }
public string NameUs { get; set; }
}
I do make a call to the API to get the results. However I can't get the return result when .Result
This is how I do it:
var infocustomer = customerRepository.GetCustomersAsync(userrating);
string nameus = infocustomer.Result.NameUs;
When I debug, nameus exits by itself. Please give me any solution. Thank you
instead of this
string content = response.Content.ReadAsStringAsync().Result;
do this
string content = await response.Content.ReadAsStringAsync();
and then just
return prod;

EF Core Decryption of SQL Column Level Encryption

My team and I are attempting to decrypt values from a db (Azure SQL) that has column level encryption turned on; with certs stored in key vault.
Expected Result:
var someLinqQuery = _contex.Users.First();
someLinqQuery.SSN = "000-00-0000";
Actual Result:
var someLinqQuery = _context.Users.First();
someLinqQuery.SSN = "the var binary (encrypted) version of the ssn";
FWIW, this works fine w/ raw sql. But we would like the option of not doing it this way, and encrypting more data.
Also we have the azure keyvault code here:
//Key Vault Code Below
private static ClientCredential _clientCredential;
public static void InitializeAzureKeyVaultProvider()
{
if (!isActivated)
{
_clientCredential = new ClientCredential(_applicationId, _clientKey);
SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers = new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>
{
{ SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider }
};
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
isActivated = true;
}
}
public static async Task<string> GetToken(string authority, string resource, string scope)
{
var authContext = new AuthenticationContext(authority);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, _clientCredential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the access token");
}
AccessToken = result.AccessToken;
return result.AccessToken;
}
This is loaded in the startup class. I've also moved the code to other places in the app w/ the same results.
My question is this, on .net core 2.1.x and EF core 2.1.x is this possible using LINQ? Do I need to upgrade?
According to my research, if we want to use Always Encryption( Column Encryption), we need to use the Microsoft.Data.SqlClient. For more details, please refer to the document. Besides, Microsoft.EntityFrameworkCore.SqlServer 3.x depends on Microsoft.Data.SqlClient, so I suggest you use EF core 3.x
For example. I do a test in the console application.
Configure database
Application
a. Install SDK
<PackageReference Include="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" Version="1.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="5.2.7" />
b. data model
class Patient
{
public int PatientId { get; set; }
public string SSN { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
}
c. database context
private static Boolean isInitialized;
public TestContext(DbContextOptions<TestContext> options) : base(options) {
if(! isInitialized) { InitializeAzureKeyVaultProvider(); isInitialized = true; }
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// your sql server connnection string
var constr = "Server=<>;Initial Catalog=<>;User ID=<>;Password=<>;Column Encryption Setting=enabled";
SqlConnection connection = new SqlConnection(constr);
optionsBuilder.UseSqlServer(connection);
}
public DbSet<Patient> Patients { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Patient>().ToTable("Patients");
}
private static string clientId = "";
private static string clientSecret = "";
private static ClientCredential _clientCredential;
private static void InitializeAzureKeyVaultProvider()
{
_clientCredential = new ClientCredential(clientId, clientSecret);
SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider =
new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();
providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
}
private static async Task<string> GetToken(string authority, string resource, string scope)
{
var authContext = new AuthenticationContext(authority);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, _clientCredential);
if (result == null)
throw new InvalidOperationException("Failed to obtain the access token");
return result.AccessToken;
}
d. test
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
DbContextOptions<TestContext> options = new DbContextOptions<TestContext>();
var db =new TestContext(options);
var results =db.Patients.ToListAsync().Result;
foreach (var r in results) {
Console.WriteLine(r.SSN);
}
Console.ReadLine();
}

Not able to access Request.Headers in BeginExecuteCore() method of Basecontroller MVC4

Can any one please help me? I am trying to implement localization in my mvc 4 WebApi application. I want to show the culture specific pages to the user on the basis of
"User-Locale" passed in the Request headers.
What I have done is, I am having a LinkedAccountModel class as shown below -
public class LinkedAccountModel
{
public string Id { get; set; }
[Required(ErrorMessageResourceType = typeof(LanguageResources.Resource), ErrorMessageResourceName = "DomainNameRequired")]
[DataType(DataType.Password)]
[Display(Name = "DomainName", ResourceType = typeof(LanguageResources.Resource))]
public string DomainName { get; set; }
[Required(ErrorMessageResourceType = typeof(LanguageResources.Resource), ErrorMessageResourceName = "UserNameRequired")]
[Display(Name = "UserName", ResourceType = typeof(LanguageResources.Resource))]
public string UserName { get; set; }
[Required(ErrorMessageResourceType = typeof(LanguageResources.Resource), ErrorMessageResourceName = "PasswordRequired")]
[DataType(DataType.Password)]
[Display(Name = "Password", ResourceType = typeof(LanguageResources.Resource))]
public string Password { get; set; }
[Required(ErrorMessageResourceType = typeof(LanguageResources.Resource), ErrorMessageResourceName = "ServerNameRequired")]
[Display(Name = "ServerName", ResourceType = typeof(LanguageResources.Resource))]
public string ServerName { get; set; }
[Required]
public long UserId { get; set; }
}
========================================================================
With this, I am having an ExchangeAccountSetupController which uses this model. This controller is implemented by the BaseController. My ExchangeAccountSetupController looks like as follows-
public class ExchangeAccountSetupController : BaseController
{
private PersistenceManagerAsync _persistenceManager;
public async Task<ActionResult> New(string sessionToken)
{
if (string.IsNullOrEmpty(sessionToken))
{
ViewBag.Title = LanguageResources.Resource.AccountConfigurationFailed;
ViewBag.ErrorMessage = LanguageResources.Resource.UnableToProcessRequest;
return View("Message");
}
_persistenceManager = new PersistenceManagerAsync(null);
var token = await _persistenceManager.RetrieveAsync<SessionToken>(string.Format("{0}|{1}", sessionToken.Substring(0, 10), sessionToken));
if (token == null)
{
ViewBag.Title = LanguageResources.Resource.AccountConfigurationFailed;
ViewBag.ErrorMessage = LanguageResources.Resource.UnableToProcessRequest;
return View("Message");
}
_persistenceManager = new PersistenceManagerAsync(token);
var user = new User { UserId = token.UserId };
var linkedAccount = await LinkedAccountManager.RetrieveLinkedAccount(_persistenceManager, user, "Exchange");
var linkedAccountModel = new LinkedAccountModel { UserId = token.UserId };
var existingUser = await _persistenceManager.RetrieveAsync<User>(user.PartitionKey, user.RowKey);
if (linkedAccount != null)
{
ViewBag.Title = LanguageResources.Resource.ChangePassword;
linkedAccountModel.DomainName = linkedAccount.DomainName;
linkedAccountModel.UserName = linkedAccount.UserName;
if (!string.IsNullOrEmpty(linkedAccount.Url))
linkedAccountModel.ServerName = new Uri(linkedAccount.Url).Host;
return View("New", linkedAccountModel);
}
ViewBag.Title = LanguageResources.Resource.ConfigureNewExchangeAccount; //default title.
return View("New", linkedAccountModel);
}
========================================================================
My BaseController looks like as follows -
public class BaseController : Controller
{
protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
string currentLocale = string.Empty;
if (Request.Headers["User-Locale"] == null || string.IsNullOrEmpty(Request.Headers["User-Locale"]))
currentLocale = "en-US";
else
currentLocale = Request.Headers["User-Locale"];
// Modify current thread's cultures
string[] localeKeys = currentLocale.Split('-');
if (localeKeys[0].Equals("en"))
currentLocale = "en-US";
else if (localeKeys[0].Equals("nl"))
currentLocale = "nl-NL";
else
currentLocale = "en-US";
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(currentLocale);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
return base.BeginExecuteCore(callback, state);
}
}
========================================================================
My client application is in Dotnet only. I am sending a request to the "ExchangeAccountSetupController" controller's New() Action.
Here is the client application code where I am adding headers in my HttpClient Request-
var client = new HttpClient();
client.Timeout = new TimeSpan(1, 1, 1);
client.DefaultRequestHeaders.Add("User-Locale", "nl-NL");
var webResponse = httpClient.GetAsync(RestServiceUrl.GetLinkedAccountProviderUrl(accountProviderName)).Result;
if (webResponse.StatusCode != HttpStatusCode.OK)
return null;
var url = JsonConvert.DeserializeObject<string>(webResponse.Content.ReadAsStringAsync().Result);
return url;
My problem is that whenever I send a request from my client, the request reached to BaseController successfully.But I cannot access that "User-Locale" in the current Request object under BeginExecuteCore() method. I cannot access the "User-Locale" header from the Request object. I did not get any thing in Request.Headers["User-Locale"].It give me null.
Please tell me if I am doing anything wrong.Even I am not sure whether I can access that header under BeginExecuteCore() method or not .Any suggestions are highly appreciated.
There is no User-Locale header defined in HTTP. You are probably looking for the Accept-Language header.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
From MVC Web API you can get a hold of it with
Request.Headers.AcceptLanguage.
You can also get a parsed list of languages with this property
HttpContext.Current.Request.UserLanguages
Please note that the list is NOT sorted, contrary to what the documentation says.
http://msdn.microsoft.com/en-us/library/system.web.httprequest.userlanguages(v=vs.110).aspx

How to post image data from j2me to ASP.net MVC 3?

I'm making a j2me mobile application which can post images (as byte[]) and other simple data (strings, ints, floats, etc) on a ASP.net MVC 3 website. Currently the application and website are nearly done, except the part where the app can post the image data on the website.
Here is the datamodel I'd like to post to the website (j2me):
public class DataModel {
private String description = null;
private float latitude = 0;
private float longitude = 0;
private long timestamp = 0;
private String userName = null;
private byte[] imageData = null;
private String contentType = null;
// getters and setters...
}
This is the model my website expects (ASP.net MVC3 C#):
public class Model
{
public string Description { get; set; }
public float Latitude { get; set; }
public float Longitude { get; set; }
public long Timestamp { get; set; }
public string UserName { get; set; }
public byte[] Image { get; set; }
}
This is the (simplified) code I use to send the data (j2me):
InputStream in = null;
OutputStream out = null;
// url contains all the simple data
String encodedUrl = UrlEncoder.encodeUrl(url);
this.connection = (HttpConnection)Connector.open(encodedUrl);
byte[] imageData = DataModel.getImageData();
this.connection.setRequestMethod(HttpConnection.POST);
this.connection.setRequestProperty("Content-Length", imageData.length + "");
out = this.connection.openOutputStream();
out.write(imageData);
int responseCode = this.connection.getResponseCode();
if(responseCode != HttpConnection.HTTP_OK) {
throw new IOException("Transmission failed as server responded with response code: " + responseCode);
}
// process response here...
I've found some sollutions online for handling a post request from a j2me application which doens't do what I want and it's in VB. But maybe there's some useful code in there, which should be placed in the page-load event:
' the stream will be ASCII encoded'
Dim ascii As ASCIIEncoding = New ASCIIEncoding
'Get ASCII into reg. string here'
strmContent = ascii.GetString(strArr)
Label1.Text = strArr.ToString()
'write the received data to a text file'
Dim FILE_NAME As String = "C:\\NP\\received.txt"
Dim objWriter As New System.IO.StreamWriter(FILE_NAME, True)
objWriter.WriteLine(strmContent)
objWriter.WriteLine()
objWriter.Close()
I have no clue how I can receive the image data on my website. What code do I need to put in my Controller Action to be able to receive all the data? Do I need to change anything in my application code?
I'm splitting up the simple data from the image data. Is that even the right way to work here?
Thanks alot!
I am not an expert of j2me but you could simply make a multipart/form-data request as shown in this article which allows you to send files in addition to simple values in an HTTP request. So your code will look something along the lines of:
byte[] fileBytes = DataModel.getImageData();
Hashtable params = new Hashtable();
params.put("Description", "some description");
params.put("Latitude", "5");
params.put("Longitude", "6");
params.put("Timestamp", "123");
params.put("UserName", "john smith");
HttpMultipartRequest req = new HttpMultipartRequest(
"http://example.com/home/upload",
params,
"Image", "original_filename.png", "image/png", fileBytes
);
byte[] response = req.send();
Then on your ASP.NET MVC side your view model will simply look like this:
public class MyViewModel
{
public string Description { get; set; }
public float Latitude { get; set; }
public float Longitude { get; set; }
public long Timestamp { get; set; }
public string UserName { get; set; }
public HttpPostedFileBase Image { get; set; }
}
and your controller action:
[HttpPost]
public ActionResult Upload(MyViewModel model)
{
...
}
And here's the HttpMultipartRequest code (in case Nokia's site goes down):
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
public class HttpMultipartRequest
{
static final String BOUNDARY = "----------V2ymHFg03ehbqgZCaKO6jy";
byte[] postBytes = null;
String url = null;
public HttpMultipartRequest(String url, Hashtable params, String fileField, String fileName, String fileType, byte[] fileBytes) throws Exception
{
this.url = url;
String boundary = getBoundaryString();
String boundaryMessage = getBoundaryMessage(boundary, params, fileField, fileName, fileType);
String endBoundary = "\r\n--" + boundary + "--\r\n";
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(boundaryMessage.getBytes());
bos.write(fileBytes);
bos.write(endBoundary.getBytes());
this.postBytes = bos.toByteArray();
bos.close();
}
String getBoundaryString()
{
return BOUNDARY;
}
String getBoundaryMessage(String boundary, Hashtable params, String fileField, String fileName, String fileType)
{
StringBuffer res = new StringBuffer("--").append(boundary).append("\r\n");
Enumeration keys = params.keys();
while(keys.hasMoreElements())
{
String key = (String)keys.nextElement();
String value = (String)params.get(key);
res.append("Content-Disposition: form-data; name=\"").append(key).append("\"\r\n")
.append("\r\n").append(value).append("\r\n")
.append("--").append(boundary).append("\r\n");
}
res.append("Content-Disposition: form-data; name=\"").append(fileField).append("\"; filename=\"").append(fileName).append("\"\r\n")
.append("Content-Type: ").append(fileType).append("\r\n\r\n");
return res.toString();
}
public byte[] send() throws Exception
{
HttpConnection hc = null;
InputStream is = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] res = null;
try
{
hc = (HttpConnection) Connector.open(url);
hc.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + getBoundaryString());
hc.setRequestMethod(HttpConnection.POST);
OutputStream dout = hc.openOutputStream();
dout.write(postBytes);
dout.close();
int ch;
is = hc.openInputStream();
while ((ch = is.read()) != -1)
{
bos.write(ch);
}
res = bos.toByteArray();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if(bos != null)
bos.close();
if(is != null)
is.close();
if(hc != null)
hc.close();
}
catch(Exception e2)
{
e2.printStackTrace();
}
}
return res;
}
}

Resources