Debug WCF service in IIS with object as input - visual-studio

I want to debug a WCF service locally in Visual Studio. The called function looks like this:
public void PerformAction(Directory[] dirs) {
....
}
Directory is a class with some properties. In the WCF test client I want to test the function but how can I set the input values for the Directory array?

Taking the default WCF template as an example, I made the following definition.
[OperationContract]
//[WebGet(RequestFormat =WebMessageFormat.Json,ResponseFormat =WebMessageFormat.Json)]
string GetData(CompositeType[] value);
public string GetData(CompositeType[] value)
{
return string.Format("You entered: {0},{1}", value[0].StringValue,value[1].StringValue);
}
First enter the length of the array, then select the array type, and finally enter the values of the individual elements one by one.
Wish it is useful to you, feel free to let me know if there is anything I can help with.

Related

How to pursuade the ApiExplorer to create documentation for ExpandoObject?

I've created a very neat way of implementing a PATCH method for my Web.API project by making use of an ExpandoObject as a parameter. As illustrated below:
[HttpPatch, Route("api/employee/{id:int}")]
public IHttpActionResult Update(int id, [FromBody] ExpandoObject employee)
{
var source = Repository.FindEmployeeById(id);
Patch(employee, source);
Repository.SaveEmployee(source);
return Ok(source);
}
However, when generating documentation ApiExplorer is at a loss as to what to do with the ExpandoObject, which is totally understandable. Would anyone have any ideas on how to manipulate the ApiExplorer to provide some sensible documentation?
My idea was to maybe introduce an new attribute which points to the actual Type that is expected:
public IHttpActionResult Update(int id, [FromBody, Mimics(typeof(Employee))] ExpandoObject employee)
{
...
}
But I have no idea where to start, any ideas or suggestions are welcome.
So this has been the source of some late evenings in order to get the Api Explorer to play along with our developed Http Patch mechanism. Truth be told, I'd probably should do a bit of a proper write up to full explain the mechanics behind the whole idea. But for those of you who landed on this page because you want the Api explorer to use a different type in the documentation, this is where you need to look:
Open HelpPageConfigurationExtensions.cs and locate the following method:
//File: Areas/HelpPage/HelpPageConfigurationExtensions.cs
private static void GenerateRequestModelDescription(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator, HelpPageSampleGenerator sampleGenerator)
{
....
}
this is the location where the parameter information is available to you and also provides you with the ability to replace/substitute parameter information with something else. I ended up doing the following to handle my ExpandoObject parameter issue:
if (apiParameter.Source == ApiParameterSource.FromBody)
{
Type parameterType = apiParameter.ParameterDescriptor.ParameterType;
// do something different when dealing with parameters
// of type ExpandObject.
if (parameterType == typeof(ExpandoObject))
{
// if a request-type-attribute is defined, assume the parameter
// is the supposed to mimic the type defined.
var requestTypeAttribute = apiParameter.ParameterDescriptor.GetCustomAttributes<RequestTypeAttribute>().FirstOrDefault();
if (requestTypeAttribute != null)
{
parameterType = requestTypeAttribute.RequestType;
}
}
}
Just, note that the RequestTypeAttribute is something I devised. My WebApi endpoint looks like this now:
public IHttpActionResult Update(int id,
[FromBody, RequestType(typeof(Employee))] ExpandoObject employee)
Thank you to everyone who took time to look into the problem.

How to send a List<object> to a Web Method?

I am developing a web application using MVC 3 and ASMX Web Services.
I am trying to send a List< object > to a Web Method, but I get the following error:
" cannot convert from 'System.Collections.Generic.List' to 'WebServiceClass.ArrayOfAnyType' "
This is my Web Service definition:
public class WebServiceClass : System.Web.Services.WebService
{
[WebMethod]
public bool MyWebMethod(List<object> ParameterValues)
{
//do stuff..
}
}
And this is the block of code where I call the Web Method:
List<object> ParameterValues = new List<object>();
WebServiceClass.WebServiceClassSoapClient MyWebService = new WebServiceClass.WebServiceClassSoapClient();
//I use actual objects here, this is just for an example
ParameterValues.Add(new DateTime(2012,5,2));
ParameterValues.Add(23);
ParameterValues.Add("some string");
MyWebService.MyWebMethod(ParameterValues);
My idea was to save time and pass Lists of objects to all Web Methods instead of defining WebMethod(DateTime date, int someint, string somestring).
Is there a solution for this?
Best regards.
If your method expects 3 parameters of type DateTime, int, and string than define a method with this arguments. Otherwise you will have to case down and your solution is not type-safe.
Are all your methods in code taking a list of objects as a parameter? Probably not. And the same should apply to web methods.

Duplicate the behaviour of a data driven test

Right now, if you have a test that looks like this:
[TestMethod]
[DeploymentItem("DataSource.csv")]
[DataSource(
Microsoft.VisualStudio.TestTools.DataSource.CSV,
"DataSource.csv",
"DataSource#csv",
DataAccessMethod.Sequential)]
public void TestSomething()
{
string data = TestContext.DataRow["ColumnHeader"].ToString();
/*
do something with the data
*/
}
You'll get as many tests runs as you have data values when you execute this test.
What I'd like to do is duplicate this kind of behaviour in code while still having a datasource. For instance: let's say that I want to run this test against multiple deployed versions of a web service (this is a functional test, so nothing is being mocked - ie. it could very well be a codedui test against a web site deployed to multiple hosts).
[TestMethod]
[DeploymentItem("DataSource.csv")]
[DataSource(
Microsoft.VisualStudio.TestTools.DataSource.CSV,
"DataSource.csv",
"DataSource#csv",
DataAccessMethod.Sequential)]
public void TestSomething()
{
var svc = helper.GetService(/* external file - NOT a datasource */);
string data = TestContext.DataRow["ColumnHeader"].ToString();
/*
do something with the data
*/
}
Now, if I have 2 deployment locations listed in the external file, and 2 values in the datasource for the testmethod, I should get 4 tests.
You might be asking why I don't just add the values to the datasource. The data in the external file will be pulled in via the deployment items in the .testsettings for the test run, because they can and will be defined differently for each person running the tests and I don't want to force a rebuild of the test code in order to run the tests, or explode the number of data files for tests. Each test might/should be able to specify which locations it would like to test against (the types are known at compile-time, not the physical locations).
Likewise, creating a test for each deployment location isn't possible because the deployment locations can and will be dynamic in location, and in quantity.
Can anyone point me to some info that might help me solve this problem of mine?
UPDATE! This works for Visual Studio 2010 but does not seem to work on 2012 and 2013.
I had a similar problem where I had a bunch of files I wanted to use as test data in a data driven test. I solved it by generating a CSV file before executing the data driven test. The generation occurs in a static method decorated with the ClassInitialize attribute.
I guess you could basically do something similar and merge your current data source with your "external file" and output a new CSV data source that your data driven test use.
public TestContext TestContext { get; set; }
const string NameColumn = "NAME";
const string BaseResourceName = "MyAssembly.UnitTests.Regression.Source";
[ClassInitialize()]
public static void Initialize(TestContext context)
{
var path = Path.Combine(context.TestDeploymentDir, "TestCases.csv");
using (var writer = new StreamWriter(path, false))
{
// Write column headers
writer.WriteLine(NameColumn);
string[] resourceNames = typeof(RegressionTests).Assembly.GetManifestResourceNames();
foreach (string resourceName in resourceNames)
{
if (resourceName.StartsWith(BaseResourceName))
{
writer.WriteLine(resourceName);
}
}
}
}
[TestMethod]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\TestCases.csv", "TestCases#csv", DataAccessMethod.Random)]
public void RegressionTest()
{
var resourceName = TestContext.DataRow[NameColumn].ToString();
// Get testdata from resource and perform test.
}

What's the easiest way to write a unit test that sends Request.Form data to my controller?

Basically I want to set 20 or so Request.Form values, send a POST to my controller, and then check the result.
I found a couple articles such as this one which describe how you can do this with a combination of NUnit, MVCContrib, and Rhino Mocks. But I don't know if this is truly necessary.
It would seem that Visual Studio 2010 and ASP.NET MVC 2 should be able to do this natively and display the results in the little "Test Results" window. In fact, when I create a new unit test with the wizard, it comes up with this...
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("G:\\Webs\\MyWebsite.com\\MyWebsite", "/")]
[UrlToTest("http://localhost:43383/")]
public void PaypalIPNTest()
{
BuyController target = new BuyController(); // TODO: Initialize to an appropriate value
ActionResult expected = new EmptyResult(); // TODO: Initialize to an appropriate value
ActionResult actual;
actual = target.PaypalIPN();
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
Is it possible to feed target.PaypalIPN() my Request.Form variables based on the above code? Or do I need to rely on 3rd party libraries to get this done?
In fact, when I create a new unit test with the wizard, it comes up with this
Yes, and all that you can keep from this is the method signature. The method body is useless.
So let's start by looking at this:
Is it possible to feed target.PaypalIPN() my Request.Form variables
By reading this sentence I assume that your controller action looks something like this:
[HttpPost]
public ActionResult PaypalIPN()
{
string foo = Request["foo"];
string bar = Request["bar"];
... do something with foo and bar
}
So the first is to improve this code by introducing view models:
public class MyViewModel
{
public string Foo { get; set; }
public string Bar { get; set; }
}
and then modify your method signature to:
[HttpPost]
public ActionResult PaypalIPN(MyViewModel model)
{
... do something with model.Foo and model.Bar
}
Now your controller is abstracted from any HttpContext infrastructure code (which really should be left to the framework, it is not your controller actions responsibility to read request parameters => that's plumbing code) and unit testing it is really a simple matter:
[TestMethod()]
public void PaypalIPNTest()
{
// arrange
var sut = new BuyController();
var model = new MyViewModel
{
Foo = "some foo",
Bar = "some bar",
};
// act
var actual = sut.PaypalIPN(model);
// assert
// TODO:
}
OK, this being said, here we dealt with some really simple controller action. For more advanced scenarios you really should consider using a mocking framework. Personally I use MvcContrib.TestHelper with Rhino Mocks to unit test my ASP.NET MVC applications.
I have another approach to test my MVC application, first I used Dev Magic Fake to fake any underline layer under the controller until the application is running and the business is approved and then I replace the fake code with TDD approach based on approved requirements
See Dev Magic Fake on CodePlex:
http://devmagicfake.codeplex.com/
Thanks
M.Radwan

Can Resharper (or Visual Studio) collapse a method call (replace the call with the contents of that method/constant)?

I've inherited a web application written in ASP.NET that has an incomplete implementation of a localization scheme (not using resource files). Here's a micro version:
public class Useful
{
public void DoSomething()
{
return Localizations.Do_Something_Message_vx7Hds8i;
}
}
public class Localizations
{
public const string Do_Something_Message_vx7Hds8i = "Some text!";
}
In almost all cases, these localized strings aren't even used in more than one place. I'd like to factor out this annoying localization layer before properly localizing the app.
The end result I want is just:
public class Useful
{
public void DoSomething()
{
return "Some text!";
}
}
This is proving tediously slow and I have over 1000 in this app.
What would be awesome would be a one-click way of selecting the reference and have it automatically suck in the string contents. I'm using Visual Studio 2008 and ReSharper 5.1.
Does anyone know if there's a way to accomplish this? It seems like there should be a proper name for what I'm trying to do (anti-modularization?) but I'm a little stumped where to start.
The default key command in Resharper is Ctrl+Alt+N for inline refactoring.

Resources