Using extension methods in web application - c#

Use extension methods and fetch the blob string length in web or mvc.
Sample code,tried using static customized methods but in vain.
sample code
public class Employee()
{
public string First_Name {get; set; }
public string Last_Name {get; set; }
}
public static string Full_Name(this Person source)
{
find length of full_name using extension methods
}
using extension methods

Code to fetch blobs from Azure
I have tried this from my end and able fetch the blobs and length of the blobs as per your requirement using extension methods.
string storageAccount_connectionString = "Connection String";
CloudStorageAccount storage_Account = CloudStorageAccount.Parse(storageAccount_connectionString);
CloudBlobClient blob_Client = storage_Account.CreateCloudBlobClient();
CloudBlobContainer _container = blob_Client.GetContainerReference(container_Name);
CloudBlockBlob cloudBlockBlob = _container.GetBlockBlobReference(filename);
You can pass the filename / blob to the below method.
The below is the sample code of extension method.
Public static int FindLength(this string blobstring)
{
return blobstring.Length;
//you can use char array or some other for fetching the length
}
Alternatively, you can use your custom methods for fetching the length in case of any future requirements
Generally blobs have name as one of the property, and is not split by first name / last name.
Extension method:
The extension methods allows you to add new methods in the existing class or in the structure without modifying the source code of the original type and you do not require any kind of special permission from the original type and there is no need to re-compile the original type.

Related

How can binding expressions/named parameters be used when following the multi-output pattern for dotnet-isolated Azure Functions?

In .net 3.x I have an azure function that generates thumbnails whenever a user uploads a new profile image. It uses a QueueTrigger, a Blob Input Binding (imageToProcess) and Blob Output Bindings for each thumbnail size. With .net 3.1 my azure function (which works great) is defined like this:
public async static Task RunAsync(
[QueueTrigger("%ProfileImageQueueName%", Connection = "ProfileImageQueueConnectionString")]ImageToProcess imageToProcess,
[Blob("profileimagestmp/{FullImagePath}", FileAccess.Read, Connection = "ProfileImageBlobConnectionString")] CloudBlockBlob originalImageTmp,
[Blob("profileimages/{RelativePath}profileImage-24.png", FileAccess.Write, Connection = "ProfileImageBlobConnectionString")] CloudBlockBlob image24),
[Blob("profileimages/{RelativePath}profileImage-40.png", FileAccess.Write, Connection = "ProfileImageBlobConnectionString")] CloudBlockBlob image40)
In the code above, "RelativePath" is a property on the queue message "ImageToProcess" that determines the path structure for the original blob. It also determines the path structure for the output blobs (through binding expressions).
With .net 5 (dotnet-isolated) I understand that having multiple outputs is done very differently.
I am attempting to follow the Multiple Output Bindings pattern when implementing a .net 5 (dotnet-isolated) Azure Function as shown in this document: https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide
With .net 5, my azure function is defined like this:
public async Task<FunctionOutput> Run(
[QueueTrigger("%ProfileImageQueueName%", Connection = "ProfileImageQueueConnectionString")] string imageToProcessString,
[BlobInput("profileimagestmp/{FullImagePath}", Connection = "ProfileImageBlobConnectionString")] byte[] originalImageTmp)
It returns the "MultiOutput" like this:
return new MultiOutput(imageToProcess.RelativePath)
{
Image24 = thumbnail24.
Image40 = thumbnail40
};
My "MultiOuput" class looks like this:
public class MultiOutput
{
public MultiOutput(string relativePath)
{
RelativePath = relativePath;
}
public string RelativePath { get; set; }
[BlobOutput("profileimages/{RelativePath}profileImage-original.png", Connection = "ProfileImageBlobConnectionString")]
public string OriginalImage { get; set; }
[BlobOutput("profileimages/{RelativePath}profileImage-24.png", Connection = "ProfileImageBlobConnectionString")]
public string Image24 { get; set; }
}
When I run the function I am getting the following exception: "Microsoft.Azure.WebJobs.Host: No value for named parameter 'RelativePath'."
To try and get around this issue I added a "RelativePath" property on my MultiOutput class that I set in it's constructor. The error persists.
My question is this, how do you use binding expressions in a Multiple Output scenario with .net 5 Azure Functions?

How to write unit test for this block of code

public static LoginResult CreateLoginSuccessResponse(this PortalIdentity user)
{
return new LoginResult(
true,
string.Empty,
user.Roles,
false
);
}
public class PortalIdentity : IdentityUser
{
public string Firstname { get; set; }
public string Lastname { get; set; }
}
This block of code is for creating a success response whenever a user logs in successfully. I am a QA and trying to learn how to write unit tests. I am not sure how to write unit test for "this" keyword
this (in the above context at least) just means it is an extension method.
To test it, new up a PortalIdentity, assign to a variable (bob) and call bob.CreateLoginSuccessResponse():
var bob = new PortalIdentity(you may need parameters here);
var result = bob.CreateLoginSuccessResponse();
If the call to bob.CreateLoginSuccessResponse() doesn't compile, then the extension method is likely in a different namespace. As per the docs, you need to:
In the calling code, add a using directive to specify the namespace
that contains the extension method class.

EF entity, local file as property

I have an entity that has both general properties that are stored in database table and a reference to a local file on system disk. I want the create/replace/delete methods for this file be encapsulated in the data access layer to let other parts of the application not care of how and where it should be stored, just send a bytes stream of perform "clear" operation. At the same time, I'd like the file directory to be defined in web.config like database access parameters are.
Im my web app I use EF 5 Code First and have defined the entity like an example below:
// EF entity
public class UserImage{
public string Description { get; set; }
[NotMapped]
public LocalFile File { get; set; }
}
// not EF entity
public class LocalFile{
public string Name { get; set; }
public string LocalPath { // should return full path as dir path + file name }
public string Url { // should return LocalPath mapped to Url }
public void Set(FileStream fs) { // saves file to disk }
public void Clear() { // deletes file }
}
In my approach I can account my DbContext is not only database context, but a context for both database and filesystem storage and I can provide it both with DB connection string and a local directory path on creation time. I think it should be a good practice, let me know if I'm wrong.
Now the problem: how I can know the local directory path from inside of the LocalFile or UserImage objects so they can implement LocalPath and Url properties? In other words, how some other part of the application can know what's the actual Path/Url of the LocalFile or UserImage instance? Or is there a way to provide these objects with LocalDir as they're being created inside DbContext? At last, what is the alternate way to incapsulate local storage operations within UserImage so any outed code never care how and where the file is stored?
You should create interface for your file operations that will have two methods: Stream GetFile(string fileName) and void PutFile(Stream fileStream, string fileName) and implement it with concrete class that will have constructor with parameter locationPath:
public interface IFileRepository
{
Stream GetFile(string fileName);
void PutFile(Stream fileStream, string fileName);
}
public class FileRepository
{
private readonly string localPath;
public FileRepository(string localPath)
{
_localPath = localPath;
}
public Stream GetFile(string fileName)
{
var file = //get filestram from harddrive using fileName and localPath
return file;
}
...
public void PutFile(Stream fileStream, string fileName)
{
//save input stream to disk file using fileName and localPath
}
}
In your DbContext class you should create private field of type IFileRepository and in constructor initialize it from parameter:
public class SomeDbContext:DbContext
{
private readonly IFileRepository _fileRepository;
public SomeDbContext(IFileRepository fileRepository)
{
_fileRepository = fileRepository;
}
...
}
And use this _fileRepository to put and get files in DbContext methods.
Concrete classes for interface type parameters should be passed by Inversion of Control container (or other implementations of Inversion of Control principle).
Update:
public class UserImage
{
public string Description { get; set; }
[NotMapped]
public LocalFile File { get; set; }
}
// not EF entity
public class LocalFile
{
private readonly string _filePath;
public LocalFile(string filePath)
{
_filePath=filePath;
}
public string Name { get; set; }
public string LocalPath { // aggregate Name and filePath }
public string Url { // should return LocalPath mapped to Url } If i where you, i would write helper for this
}
I think my mistake is that i'm trying to access context properties (i.e. directory path) from inside of the entity. EF database context architecture doesnt implement it and the entities don't have idea how they are stored. I wouldn't like to voilate this canon.
The directory for storing files can be considered either as context property (like connection string) and entity property (like path). To implement first case i can provide myDbContext with the Directory property and then resolve all paths via context instance by calling myContext.GetUrl(userImage.FileName). But myDbContext is not always directly accessible from presentation level and i'll be unable to extract userImage's Url to set it on web page until i propogate myDbContext to all upper layers.
If I consider Directory as LocalFile's property then i need somehow to inject its value, either in constructor:
public class LocalFile{
// Constructor
public LocalFile(string dir){ // set current dir }
private string _dir;
public GetUrl(){ // return _dir + filename }
}
// cons: parameterless constructor that will be called by DbContext on getting
// data from DB won't set `_dir` and GetUrl won't return correct result
or using static directory that is set up earlier (say in global.asax):
public class LocalFile{
// Constructor
public LocalFile(){ // empty }
public static Dir;
public GetUrl(){ // return Dir + filename }
}
or even directly accessing web.config to get paths:
public class LocalFile{
// Constructor
public LocalFileType(){ // empty }
public GetUrl(){ // read dir from web.config + filename }
}
// not good idea to access web-specific assemblies from EF data classes
or making extension methods at upper layers where web.config is accessible:
public static class MyExtensions
{
public static string GetUrl(LocalFile localFile)
{
// dir from web.config + localFile.Name
}
}
So, there are many possible solutions and each has its own disadvantages. My case is little bit more complicated as my dir path also depends on LocalFile's parent user's ID so i have dir template users/{0}/image.jpg in web.config instead of simple path.
What i've done to achieve my targets:
put url template of type users/{0}/{1} (0 - parent UserId, 1 -
fileName) to web.config
created class Settings nearby my EF entities
public static class Shared
{
public static Func<string, int, string> LocalFileUrlResolver;
}
populated its values on application start
protected void Application_Start()
{
Shared.LocalFileUrlResolver =
(fileName, userId) =>
String.Format(ConfigurationManager.AppSettings["LocalFileUrl"], userId, fileName);
}
made my User provide its own images with Url resolver at creation
time
public User()
{
// ...
Image = new LocalFile(
"userpic.css",
fileName => Shared.LocalFileUrlResolver(fileName, userId)
);
}
made my LocalFile constructor accept Func<string, string> param
that resolves full Url of given file name
public class LocalFile
{
public LocalFile(
string fileName,
Func<string, string> fnUrlResolver
)
{
FileName = fileName;
_fnUrlResolver = fnUrlResolver;
}
private readonly Func<string, string> _fnUrlResolver;
public string FileName { get; private set; }
public string Url { get { return _fnUrlResolver(FileName); } }
}
Yes, so many lines. I take dir template from web.config, inject it into static member of data access layer and make it more specific on User creation point for user's local images.
I am absolutely not sure does it worth the cost. Maybe in future i'll choose direct access to web.config :)

pass array of an object to webapi

I have a .net mvc 4 webapi project that I'm trying to pass an array of an object to a method on my controller.
I've found some examples here on SO that talk about needing to set my object's properties with: param1=whatever&param2=bling&param3=blah.
But I don't see how I can pass in a collection using that.
Here is my method signature. Notice I've decorated the argument with the [FromUri] attribute.
public List<PhoneResult> GetPhoneNumbersByNumbers([FromUri] PhoneRequest[] id)
{
List<PhoneResult> prs = new List<PhoneResult>();
foreach (PhoneRequest pr in id)
{
prs.Add(PhoneNumberBL.GetSinglePhoneResult(pr.PhoneNumber, pr.RfiDate, pr.FinDate, pr.State));
}
return prs;
}
here is my simple PhoneRequest object:
public class PhoneRequest
{
public string PhoneNumber { get; set; }
public string RfiDate { get; set; }
public string FinDate { get; set; }
public string State { get; set; }
}
and here's a sample of what I'm using to pass in:
http://localhost:3610/api/phonenumber/getphonenumbersbynumbers/
[{"PhoneNumber":"8016667777","RfiDate":"","FinDate":"2012-02-11","State":"UT"},
{"PhoneNumber":"8018889999","RfiDate":"2012-12-01","FinDate":"","State":"UT"}]
using this comes back with "bad request"
I also tried this
http://localhost:3610/api/phonenumber/getphonenumbersbynumbers?
id=[{"PhoneNumber":"8016667777","RfiDate":"","FinDate":"2012-02-11","State":"UT"},
{"PhoneNumber":"8018889999","RfiDate":"2012-12-01","FinDate":"","State":"UT"}]
which does reach the method, but the array is null.
how can I pass in an array of my PhoneRequest object to my Web API method?
Try passing the PhoneRequest[] from the uri in this format:
http://localhost:3610/api/phonenumber/getphonenumbersbynumbers?
id[0][PhoneNumber]=8016667777&id[0][FinDate]=2012-02-11&id[0][State]=UT&
id[1][PhoneNumber]=8018889999&id[1][RfiDate]=2012-12-01&id[1][State]=UT
I suggest you use POST for this.
As you query string grows, you will run into problems with the maximum length of the URL, which is browser dependent.
If you have a lot of parameters to pass, a POST is perfectly acceptable even if you are really only GETting data. What you will lose, however, is the ability for the user to bookmark a particular page with the query string.
I created a custom model binder, the FieldValueModelBinder class, which can effectively pass any object containing nested array or generic list types of data with query strings having field-name pairs without imbedding any JSON and XML structures. The model binder can resolve all issues discussed above. Since this question was extended by the question ID 19302078, you can see details of my answer in that thread.

Pass a list of objects to a web service

I have a DataObjects class that contains a UserEmail object that contains an int (EmailID) and a string (EmailAddress).
Within a C# .net application, if I want to display a list of email addresses - I create and populate a list of UserEmail objects.
List<DataObjects.UserEmails> myUserEmailsList = new List<DataObjects.UserEmails>();
And use it as a datasource for whatever control I happen to be using.
I need to pass that list to a web service. I can't see how to do this. If the other party writes a web service with a method that takes a list as a parameter - fine, I can call the web service and pass my list. But how will they be able to extract the data from the list - without having access to the classes that created the objects in the list?
Is there a way of looping through a list of objects without knowing what the data structure of the object is?
When you are consuming their web service, you have to conform to their data structures. You take your UserEmail object data, and would convert it to the object their service is expecting.
If you're using a service where it's just needing the data as get or post data, you'll have to use whatever keys they are requiring. So they might take the email address using a key of "email" instead of your property name of "EmailAddress"
here a sample to pass list object to your webservice
<%#WebService Language="c#" class="CustomObjectArrayWS"%>
using System;
using System.Collections;
using System.Web.Services;
using System.Xml.Serialization;
public class CustomObjectArrayWS
{
[WebMethodAttribute]
[XmlInclude(typeof(Address))]
public ArrayList GetAddresses ()
{
ArrayList al = new ArrayList();
Address addr1 = new Address("John Smith", "New York",12345);
Address addr2 = new Address("John Stalk", "San Fransisco", 12345);
al.Add(addr1);
al.Add(addr2);
return al;
}
}
// Custom class to be added to the collection to be passed in //and out of the service
public class Address
{
public string name;
public string city;
public int zip;
// Default ctor needed by XmlSerializer
public Address()
{
}
public Address(string _name, string _city, int _zip )
{
this.name = _name;
this.city = _city;
this.zip = _zip;
}
}
see http://www.programmersheaven.com/2/XML-Webservice-FAQ-Pass-Array-Of-Custom-Objects

Categories