I inherited the following code:
using (var dataAccessConnection = da.GetConnection()) //no opening curly brace here
using (var command = new SqlCommand(sql, dataAccessConnection.Connection))
{
command.CommandType = CommandType.Text;
using (var sqlDataReader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (sqlDataReader.Read())
{
rueckgabe.Add(new Myclass
{
Uid = Guid.NewGuid(),
ImportVersionUid = versionUid,
MyProperty = Convert.ToInt32(sqlDataReader["MyProperty"])
});
}
}
command.Connection.Close();
dataAccessConnection.Connection.Close();
}
Looking at the code I expexted an opening curly brace after the using clause.
The code compiles and does what it is expected to do. The application behaves unpredictable. At some time it cant access the Database server.
Does this code make sense? Does dataAccessConnection have the rigth scope?
Beginning with C# 8.0, the using keyword can be used as an attribute in the variable declarations of disposable objects (Reference). The semantics is as you would expect -- the objects are auto-disposed at the end of the scope.
public class Disposable : IDisposable
{
string name;
public Disposable(string name)
{
this.name = name;
}
public void Dispose()
{
Console.WriteLine(name + " disposed");
}
public void Identify()
{
Console.WriteLine(name);
}
static void Main(string[] args)
{
using Disposable d1 = new Disposable("Using 1");
Disposable d2 = new Disposable("No Using 2");
using Disposable d3 = new Disposable("Using 3");
Disposable d4 = new Disposable("No Using 4");
d1.Identify();
d2.Identify();
d3.Identify();
d4.Identify();
}
}
Output
Using 1
No Using 2
Using 3
No Using 4
Using 3 disposed
Using 1 disposed
using statements without explicit curly braces apply only to the following statement.
using (Idisp1)
// use it
// it's disposed
Thus, when chained, they work the same way. The second using here acts as a single statement.
using (Idisp1)
using (Idisp2)
{
}
Commenter stakx suggested that formatting to make it clear how the compiler reads the using blocks. In reality, these would usually be formatted as the OP encountered:
using (Idisp1)
using (Idisp2)
{
}
That is equivalent to this:
using (Idisp1)
{
using (Idisp2)
{
}
}
Notice that the first at the top is always the last to dispose. Thus, in all previous examples, Idisp2.Dispose() is called before Idisp1.Dispose(). That isn't relevant in many cases where you would do something like this, but I believe you should always be aware of what your code will do and make the informed decision not to care.
An example of this is when reading a web page:
HttpWebRequest req = ...;
using (var resp = req.GetResponse())
using (var stream = resp.GetResponseStream())
using (var reader = new StreamReader(stream))
{
TextBox1.Text = reader.ReadToEnd(); // or whatever
}
We get the response, get the stream, get the reader, read the stream, dispose the reader, dispose the stream, and finally, dispose the response.
Note, as commenter Nikhil Agrawal pointed out, that this is a language feature regarding blocks that is not specific to the using keyword. For example, the same applies to if blocks:
if (condition)
// may or may not execute
// definitely will execute
Versus
if (condition1)
if (condition2)
// will execute if both are true
// definitely will execute
Although you should never, of course, use if statements this way as it's dreadful to read, but I thought it'd help you understand the using case. I'm personally very okay with chaining using blocks.
The C# language specification (Version 5) describes a using statement as:
using-statement:
using ( resource-acquisition ) embedded-statement
That is:
The using statement obtains one or more resources, executes a statement, and then disposes of the resource.
(My emphasis)
So, how then do we end up using it with curly braces? Because the definition of embedded-statement is:
embedded-statement:
block
empty-statement
expression-statement
selection-statement
iteration-statement
jump-statement
try-statement
checked-statement
unchecked-statement
lock-statement
using-statement
yield-statement
And:
The embedded-statement nonterminal is used for statements that appear within other statements
And finally, we discover that block is defined as:
A block permits multiple statements to be written in contexts where a single statement is allowed.
block:
{ statement-listopt }
So basically, curly braces can always be used to take a situation where a single statement is accepted and to instead have multiple statements.
It just so happens that, almost always, we do want to make use of more than one statement, and so the curly-braces tend to be seen as part of if, using, etc statements. Whereas, in fact, they're a separate part of the language.
Related
Since the .NET version has been updated, there is no need to write entire C# code just to print 'Hello World!'. Just Console.WriteLine(); is enough. But what I could not understand, is how to define a new function outside Main()?
If I want to develop a separate function outside Main(), do I need to write entire code including using System; and namespaces and Main() function? I am talking about updated version which is C# v10.
Please, do enlighten me!
I hope this question is not much lengthy and you got idea regarding the problem.
Here is the code for your reference:
class Program
{
public static void Main(string[] args)
{
string? theWord;
System.Console.WriteLine("Enter the word");
theWord = Console.ReadLine();
System.Console.WriteLine("original string: " + theWord);
System.Console.WriteLine("middle character of " + theWord + " is " + test(theWord));
}
public static string test(string theWord)
{
int i = 1 - theWord.Length % 2;
return theWord.Substring(theWord.Length / 2-i, 1+i);
}
}
There are two important things to understand here:
Firstly, top-level statements and implicit using directives are entirely different features. So you can declare a class as normal, but still omit the using directives. Likewise if you don't want to declare a namespace, you don't have to - although these days you could just use a file-scoped namespace declaration, e.g. namespace MyNamespace; without indenting everything.
Secondly, even with top-level statements, you can write methods... but they're effectively local methods within the Main method, and come with all the restrictions that imposes (e.g. no overloading). Note that even with top-level statements for your entry point, you can still declare other classes elsewhere - it would be entirely reasonable to have a brief Program.cs using top-level statements just to get everything going, but use "regular" C# elsewhere in the project. Indeed, that's how the ASP.NET Core templates work these days.
As an example, given the sample code, you could write (slightly amended for naming and to avoid warnings):
System.Console.WriteLine("Enter the word");
string? input = Console.ReadLine();
if (input is null)
{
Console.WriteLine("No input");
return;
}
System.Console.WriteLine($"Original string: {input}");
System.Console.WriteLine($"Middle character of {input} is {GetMiddle(input)}");
string GetMiddle(string input)
{
int i = 1 - input.Length % 2;
return input.Substring(input.Length / 2 - i, i + 1);
}
In this particular case you don't actually need the parameter for the method - input would be captured anyway, because GetMiddle is a local method.
You can write that like a normal method.
using System;
Console.WriteLine("Hello World");
display();
static void display()
{
Console.WriteLine("from display");
}
I need to do serialization and deserialization using below code. But always i am getting "Dynamic type is not a contract-type" error while serializing. I am stuck with this. I need to achieve this someway Can somebody help me on this?
using ProtoBuf;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
namespace ProtoSerialization
{
class Program
{
static void Main(string[] args)
{
try
{
byte[] arr;
ClassA obj = new ClassA();
obj.ColumnList = new List<int> {1 };
using (var stream = new MemoryStream())
{
ProtoBuf.Serializer.Serialize(stream, obj);
arr = stream.ToArray();
}
using(var stream=new MemoryStream(arr))
{
var result = Serializer.Deserialize(typeof(ClassA), stream);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadKey();
}
}
}
[ProtoContract]
public class ClassA
{
[ProtoMember(1,DynamicType =true)]
public IList ColumnList;
}
}
I strongly advise against using the dynamic feature, here or elsewhere. It is deprecated in V3, probably permanently. It looks like what you really want here is something like a Value from struct.proto. This doesn't have inbuilt support in protobuf-net currently, but I'll probably add it soon. As for now: I'd probably advise using an array of a type that has those things as fields. If you make the layout look like Value does, in terms of the field numbers, it should be directly swappable later.
Mostly copied from question about protobuf dynamic array.
The documentation for dynamic arrays state:
DynamicType - stores additional Type information with the type (by default it includes the AssemblyQualifiedName, although this can be controlled by the user). This makes it possible to serialize weak models, i.e. where object is used for property members, however currently this is limited to contract types (not primitives), and does not work for types with inheritance (these limitations may be removed at a later time). Like with AsReference, this uses a very different layout format
You have a primitive, therefore you can not use DynamicType. As explained in the error message you got.
A workaround could be to wrap the primitives you want to store in another type with a defined contract.
Thanks for your observations, i did applied them with the following code but after testing api returns no data. I have even used my connection string instead of dbcontext still nothing! I get this error Invalid attempt to call FieldCount when reader is closed and my reader is open. i am in this situation for a week now any help. The FromSql query just returns entities of a single table. my Store procedure takes a parameter and has joins with 4 tables. i have tried with "ExecuteSqlCommand" query as results is a -1 i get.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using ActivaMobileAgent.Persistence;
using Microsoft.EntityFrameworkCore;
using ActivaMobileAgent.Model;
using System.Linq;
using System.Collections.Generic;
using System.Data.SqlClient;
using System;
using Dapper;
using System.Data;
using System.Data.Common;
namespace ActivaMobileAgent.Controllers
{
[Route("/api/Policy")]
public class PolicyController : Controller
{
private readonly ActivaMobileAgentDbContext context;
public PolicyController(ActivaMobileAgentDbContext context) => this.context = context;
public readonly string connectionString = "Data Source=Localhost;Initial Catalog=HELLOxx;User=sa; Password=Helloxx";
[HttpGet("{id}")]
public async Task<IActionResult> GetPolicy(string id)
{
using (var connection = new SqlConnection("Data Source=Localhost;Initial Catalog=Helios;User=sa; Password=P#ssw0rd"))
{
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText ="dbo.sproc_Contract_Get";
command.Parameters.Add(new SqlParameter("#ContractNumber", SqlDbType.VarChar) { Value = id });
connection.Open();
using (var result = await command.ExecuteReaderAsync())
{
return Json(result);
}
}
}
}
}
Your web-method doesn't return any data.
Instead of having a method that returns nothing, modify the method signature to
public async Task<IActionResult> GetPolicy( int id )
Once you've done that, the compiler will expect that this method returns some data.
I suppose that the stored proc returns some data, so you'll have to put it somewhere. Afterwards you can return the values using
return Ok(thedata);
Check the Ok method for instance.
If something went wrong, you shouldn't return Ok offcourse, but another Http status code that indicates what went wrong.
This leads me to saying that the functions in a REST service should always return the correct HTTP status code. Therefore, all your REST methods should return IActionResult or Task, and not only the data that is retrieved
Edit after the Question has been edited
The ExecuteReader() method returns a class that implements IDataReader. It's obviously not correct to return the datareader to the consumer of your webservice.
Instead, you'll have to use the IDataReader to read the data and use that data to populate some kind of model that you can use to return to the consumer of your service.
List<SomeClass> result = new List<SomeClass>();
using (var reader = await command.ExecuteReaderAsync())
{
while( reader.Read() )
{
result.Add(new SomeClass(dr.GetInt32(0), dr.GetString(1));
}
}
return Ok(result);
Next to that, I advise you to not format the data yourself to json or xml or whatever. Let ASP.NET handle that for you. ASP.NET will serialize the results to the appropriate format based on the value accept-header of the request that it has received.
ExecuteReaderAsync returns Task<SqlDataReader>. This is probably not a useful type to serialize as a JSON result. It represents a cursor over a dataset, not the data itself; the data hasn't actually been brought back from the database yet. As this blog article explains, there isn't a built-in way to turn a SqlDataReader into JSON. There are a couple of ways mentioned there, but the take-away is that you will have to write code that iterates the SqlDataReader and constructs results from it.
Typically to make this job easier you'd use an Object-Relational Mapper to do this work for you, an example is Dapper which has support for stored procedures (disclaimer: I#ve never used Dapper). Entity Framework is the usual for .net applications as it's built by Microsoft, but it's quite heavy and can be complex to use.
edit: Oh - I didn't spot that you had an Entity Framework DbContext already. That should allow you to execute the stored procedure and map it to a result natively.
I am using the following code under ASP.NET 4.0 framework to obtain the version of MSI file from a web app:
string strVersion = "";
try
{
Type InstallerType;
WindowsInstaller.Installer installer;
InstallerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
installer = (WindowsInstaller.Installer)Activator.CreateInstance(InstallerType);
WindowsInstaller.Database db = installer.OpenDatabase(strMSIFilePath, 0);
WindowsInstaller.View dv = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'");
WindowsInstaller.Record record = null;
dv.Execute(record);
record = dv.Fetch();
strVersion = record.get_StringData(1).ToString();
dv.Close();
//db.Commit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(dv);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(db);
}
catch
{
//Failed
strVersion = "";
}
It works fine except that when the code finishes running it holds an internal MSI file handle so when I try to move or rename the MSI file I get the error that the file is still in use. This continues until I actually navigate away from the ASPX page that calls the method above.
My question is, I obviously didn't close some handle or object in the code above. But what could that be?
PS. I'm testing it in a development IDE from VS2010.
EDIT: Edited the code like it should be after Adriano's suggestion. Thanks!
The COM object has not been released (it should be auto-released when it goes out of scope but in .NET this doesn't work really well). Because it does not implement the IDisposable interface you can't call its Dispose() method and you can't use it inside an using statement. You have to explicitly call Marshal.FinalReleaseComObject. For example:
try
{
// Your stuffs
}
finally
{
dv.Close();
Marshal.FinalReleaseComObject(dv);
Marshal.FinalReleaseComObject(db);
}
Moreover note that you do not really need a call to the Commit() method because you didn't make any change but just a query.
FWIW, you should be using Windows Installer XML (WiX) Deployment Tools Foundation (DTF). It's an FOSS project from Microsoft that can be found on CodePlex. It has MSI interop libraries with classes that are very similar to the COM classes but implement IDisosable and use P/Invoke instead of COM behind the scenes. There is even support for Linq to MSI if you want. And the full source code is available.
DTF is the gold standard for MSI interop in a .NET world. Here are two examples:
using System;
using System.Linq;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Deployment.WindowsInstaller.Linq;
namespace ConsoleApplication3
{
class Program
{
const string DATABASE_PATH = #"C:\FOO..MSI";
const string SQL_SELECT_PRODUCTVERSION = "SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'";
static void Main(string[] args)
{
using (Database database = new Database(DATABASE_PATH, DatabaseOpenMode.ReadOnly))
{
Console.WriteLine(database.ExecuteScalar(SQL_SELECT_PRODUCTVERSION).ToString());
}
using (QDatabase database = new QDatabase(DATABASE_PATH, DatabaseOpenMode.ReadOnly))
{
var results = from property in database.Properties where property.Property == "ProductVersion" select property.Value;
Console.WriteLine(results.AsEnumerable<string>().First());
}
}
}
}
try to Dispose the Objects.
dv.Dispose();
db.Dispose();
I see this:
using (StreamWriter sw = new StreamWriter("file.txt"))
{
// d0 w0rk s0n
}
Everything I try to find info on is does not explain what this doing, and instead gives me stuff about namespaces.
You want to check out documentation for the using statement (instead of the using directive which is about namespaces).
Basically it means that the block is transformed into a try/finally block, and sw.Dispose() gets called in the finally block (with a suitable nullity check).
You can use a using statement wherever you deal with a type implementing IDisposable - and usually you should use it for any disposable object you take responsibility for.
A few interesting bits about the syntax:
You can acquire multiple resources in one statement:
using (Stream input = File.OpenRead("input.txt"),
output = File.OpenWrite("output.txt"))
{
// Stuff
}
You don't have to assign to a variable:
// For some suitable type returning a lock token etc
using (padlock.Acquire())
{
// Stuff
}
You can nest them without braces; handy for avoiding indentation
using (TextReader reader = File.OpenText("input.txt"))
using (TextWriter writer = File.CreateText("output.txt"))
{
// Stuff
}
The using construct is essentially a syntactic wrapper around automatically calling dispose on the object within the using. For example your above code roughly translates into the following
StreamWriter sw = new StreamWriter("file.text");
try {
// do work
} finally {
if ( sw != null ) {
sw.Dispose();
}
}
Your question is answered by section 8.13 of the specification.
Here you go: http://msdn.microsoft.com/en-us/library/yh598w02.aspx
Basically, it automatically calls the Dispose member of an IDisposable interface at the end of the using scope.
check this Using statement