Use SQL Server view in NEW Azure App Service - node.js

I am new to Azure App Service.
I've created a view in Azure database to get data across several tables. Now I want to use the data from this view in my Cordova App using the Azure Mobile Service (MobileService.GetTable...). I found several articles in the web that describe how to do that in Classic Azure Portal. But I need a solution for the NEW Azure App Service with Node.js Backend.
What is the syntax to return data from a view as an Azure table?
var table = module.exports = require('azure-mobile-apps').table();
table.read(function (context) {
// *** Need code to return data from sql view ***
//return context.execute();
});
And it would be great to use a parameter to filter data in the view before returning.
Thanks,
Uwe

You are pretty much right there. You need to just create a table controller to access the view. Ensure you have the system columns defined (version, updatedAt, createdAt, deleted and id). Also, ensure the right thing happens when you update the view (e.g. with an INSERT, UPDATE, DELETE) as that will tell you what needs to be done with the controller (for example, if you can't insert/update/delete, then make it read-only).
Reference blog post for you: https://shellmonger.com/2016/04/15/30-days-of-zumo-v2-azure-mobile-apps-day-8-table-controller-basics/

Things can be so easy sometimes ;-)
All I need to do is to write the following lines to my table controller:
var table = require('azure-mobile-apps').table();
table.databaseTableName = 'ViewName';
module.exports = table;
Thanks for your help!

Had a similar issue but fixed it now, am using a .Net backend thou.
1. Log into azure portal and select the database you want to create the view in Then select the query Editor in the left pane.
2. Use the sql to create the query.
3.Create a table in the asp.net backend that matches your fields in your view.
4.Go to your asp.net backend and create a custom Api and write the following codes:
public class HelloCustomController : ApiController
{
MobileServiceContext context;
public HelloCustomController()
{
context = new MobileServiceContext();
}
[HttpGet]
public async Task<List<vwUser>> Get()
{
try
{
var users = context.Database.SqlQuery<vwUser>("Select * from
dbo.vwUser);
return await users.ToListAsync();
}
catch(Exception ex)
{
return new List<vwUser>()
{
new vwUser
{
UserName=ex.Message
}
};
}
}
4.You edit my codes to select from your view.
5. Create a similar class in your mobile app that matches what u created in your backend.
5. You can then access your view by calling it in your mobile app with the following codes:
var users= await client.InvokeApiAsync<vwUser>("HelloCustom",HttpMethod.Get,null);
Thanks Guys. This is my fisrt answer to this beautiful community that carried me from day 1 of programming till now that am a bit conversant.

Related

azure mobile apps: tables are only created when there isnt a single one existing

it took me days to figure this out:
I am using azure mobile apps as my backend.
I created a middleware that connects to my sql db. this is appdbcontext.cs:
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public DbSet<TodoItem> TodoItems => Set<TodoItem>();
public DbSet<UserItem> UserItems => Set<UserItem>();
public async Task InitializeDatabaseAsync()
{
await this.Database.EnsureCreatedAsync().ConfigureAwait(false);
}
}
When I deploy this script to azure and check my tables inside SSMS both tables are created. (Todo and UserItems)
I can read and write to them, so my controllers and models are all fine!
HOWEVER:
If I now create a third table eg:
public DbSet<ThirdItem> ThirdItem => Set<ThirdItem>();
And then check the DB in SSMS I still just see the two tables from above.
If i now however delete alle the existing tables (todo and user), so that there are NO MORE TABLES on my db and THEN deploy my script to azure again...
ALL THREE TABLES ARE THERE NOW?!?
So meaning I must do something wrong in the app context file, as it somehow checks:
"Do we already HAVE a db with tables? No, then create the following. YES? then do nothing and create nothing new".
How can I alter my script to check if a table exists IRREGARDLESS of whether any tables exists, and then add it to the db?
ALSO:
When I add a new field to my model I have to delete all tables so that my tables now have the new fields...

Syncing Azure Easy Table with WHERE clause

I'm developing a Xamarin.Forms app which uses an Azure app service with SQL database linked through EasyTables. I've run the samples and successfully tested querying tables etc on the server and enabled offline sync so as a localdb is created.
I've created the store, defined the table & sync'd it, however I want to be able to query it somehow with a where clause - is that possible? Can I add a where clause to the client.GetSyncTable line?
var store = new MobileServiceSQLiteStore("localstore.db");
store.DefineTable<Journey_Stages>();
client.SyncContext.InitializeAsync(store);
tbl_Stages = client.GetSyncTable<Journey_Stages>();
Some of the tables I'm pulling down will grow over time & are linked to individual user profiles, so I only want data which belongs to that user and I don't want to be bringing down masses of data each time, preferably let the server handle that and only bring down what I need on a user by user basis.
Thanks,
Steve
You should add this filtering logic on the server side, so that each user's data isn't exposed to all your other users. See for example this sample if you are using the Node.js backend -- line 17 adds a WHERE clause for the table read query. If you have the .Net backend, similar logic would go in your table controller.
// Configure specific code when the client does a request
// READ - only return records belonging to the authenticated user
table.read(function (context) {
context.query.where({ userId: context.user.id });
return context.execute();
});

setting must be in the form "name=value" in vs 2017

I have been learning the bot framework from microsoft and have been following a tutorial on pluralsight. I have made the changes to my Global.asax.cs and for some reason I keep on getting the error setting must be in the form name=value. I have no idea what to do and how to get rid of these errors. Any help would be highly appreciated.
Global.asax.cs
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// This code chunk below will allow us to use table bot data store instead of
// in memory data store
Conversation.UpdateContainer(
builder =>
{
builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));
// here we grab the storage container string from our web config and connecting
var store = new TableBotDataStore(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);
builder.Register(c => store).
Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore).
AsSelf().
SingleInstance();
});
GlobalConfiguration.Configure(WebApiConfig.Register);
TableBotDataStore is for Azure Table Storage, and it seems you are using some sql connectionstring. You would usually have that connection string in the AppSettings section, not the ConnectionStrings section (yes, the names are a bit misguiding here).

Windows Azure Table Storage Webrole.cs vs. global.asax.cs

I have read that the easiest way for setting up a connection and creating a table is putting the following line of codes in the webrole.cs onStart() method.
but for some reason I have got errors and when I put the same code in global.asax.cs Application_start() method. it works fine?
what is the difference
here is the code I am talking about : I am using tablestorage bytheway
...
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) =>
{
var connectionString = RoleEnvironment.GetConfigurationSettingValue(configName);
configSettingPublisher(connectionString);
}
);
var account =
CloudStorageAccount.FromConfigurationSetting(
Constants.KEY_STORAGE);
//create table
var client = account.CreateCloudTableClient();
client.CreateTableIfNotExist(Constants.EMAILMERGE_TABLE);
/////////////////////////////////
and the Error I am getting is-----------------------------
SetConfigurationSettingPublisher needs to be called before FromConfigurationSetting can be used
Tnx for the tips!!
cheeers
For a worker role, we only need to put the code in OnStart. But for a web role, we need to put the code in two places. If you want to access storage in OnStart, please put the code in OnStart. If you want to access storage in your web application, please put the code in Global.asax’s Application_Start. If you need both, please put the code in both places.
Best Regards,
Ming Xu.

Upload a file to SharePoint through the built-in web services

What is the best way to upload a file to a Document Library on a SharePoint server through the built-in web services that version WSS 3.0 exposes?
Following the two initial answers...
We definitely need to use the Web Service layer as we will be making these calls from remote client applications.
The WebDAV method would work for us, but we would prefer to be consistent with the web service integration method.
There is additionally a web service to upload files, painful but works all the time.
Are you referring to the “Copy” service?
We have been successful with this service’s CopyIntoItems method. Would this be the recommended way to upload a file to Document Libraries using only the WSS web service API?
I have posted our code as a suggested answer.
Example of using the WSS "Copy" Web service to upload a document to a library...
public static void UploadFile2007(string destinationUrl, byte[] fileData)
{
// List of desination Urls, Just one in this example.
string[] destinationUrls = { Uri.EscapeUriString(destinationUrl) };
// Empty Field Information. This can be populated but not for this example.
SharePoint2007CopyService.FieldInformation information = new
SharePoint2007CopyService.FieldInformation();
SharePoint2007CopyService.FieldInformation[] info = { information };
// To receive the result Xml.
SharePoint2007CopyService.CopyResult[] result;
// Create the Copy web service instance configured from the web.config file.
SharePoint2007CopyService.CopySoapClient
CopyService2007 = new CopySoapClient("CopySoap");
CopyService2007.ClientCredentials.Windows.ClientCredential =
CredentialCache.DefaultNetworkCredentials;
CopyService2007.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Delegation;
CopyService2007.CopyIntoItems(destinationUrl, destinationUrls, info, fileData, out result);
if (result[0].ErrorCode != SharePoint2007CopyService.CopyErrorCode.Success)
{
// ...
}
}
Another option is to use plain ol' HTTP PUT:
WebClient webclient = new WebClient();
webclient.Credentials = new NetworkCredential(_userName, _password, _domain);
webclient.UploadFile(remoteFileURL, "PUT", FilePath);
webclient.Dispose();
Where remoteFileURL points to your SharePoint document library...
There are a couple of things to consider:
Copy.CopyIntoItems needs the document to be already present at some server. The document is passed as a parameter of the webservice call, which will limit how large the document can be. (See http://social.msdn.microsoft.com/Forums/en-AU/sharepointdevelopment/thread/e4e00092-b312-4d4c-a0d2-1cfc2beb9a6c)
the 'http put' method (ie webdav...) will only put the document in the library, but not set field values
to update field values you can call Lists.UpdateListItem after the 'http put'
document libraries can have directories, you can make them with 'http mkcol'
you may want to check in files with Lists.CheckInFile
you can also create a custom webservice that uses the SPxxx .Net API, but that new webservice will have to be installed on the server. It could save trips to the server.
public static void UploadFile(byte[] fileData) {
var copy = new Copy {
Url = "http://servername/sitename/_vti_bin/copy.asmx",
UseDefaultCredentials = true
};
string destinationUrl = "http://servername/sitename/doclibrary/filename";
string[] destinationUrls = {destinationUrl};
var info1 = new FieldInformation
{
DisplayName = "Title",
InternalName = "Title",
Type = FieldType.Text,
Value = "New Title"
};
FieldInformation[] info = {info1};
var copyResult = new CopyResult();
CopyResult[] copyResults = {copyResult};
copy.CopyIntoItems(
destinationUrl, destinationUrls, info, fileData, out copyResults);
}
NOTE: Changing the 1st parameter of CopyIntoItems to the file name, Path.GetFileName(destinationUrl), makes the unlink message disappear.
I've had good luck using the DocLibHelper wrapper class described here: http://geek.hubkey.com/2007/10/upload-file-to-sharepoint-document.html
From a colleage at work:
Lazy way: your Windows WebDAV filesystem interface. It is bad as a programmatic solution because it relies on the WindowsClient service running on your OS, and also only works on websites running on port 80. Map a drive to the document library and get with the file copying.
There is additionally a web service to upload files, painful but works all the time.
I believe you are able to upload files via the FrontPage API but I don’t know of anyone who actually uses it.
Not sure on exactly which web service to use, but if you are in a position where you can use the SharePoint .NET API Dlls, then using the SPList and SPLibrary.Items.Add is really easy.

Resources