How to send a List<object> to a Web Method? - asp.net-mvc-3

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.

Related

Want to Send the Object type data from one VSTO addin Project to Another VSTO addin project

I am working on a Outlook addin in which I want to send the data from one outlook addin project to another outlook project. But when I try call the function of another project with the object type data in the arguments it will throw "Unable to cast object of type 'System.Runtime.Remoting.Proxies.__TransparentProxy' to type at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)" error.
Here is the code for your reference.
public IProfileAttribute[] profileAttributes= null;
Outlook.Application outlookApp = new Outlook.Application();
this.profileAttributes = new FilingNotifiableIpmlementation().FilingNotification(); // to fill the object
object destAddinName = "Tikit.CarpeDiem.AddIn.Outlook";
Office.COMAddIn destAddIn = outlookApp.COMAddIns.Item(ref destAddinName)
destAddIn.Object.FilingNotification(this.profileAttributes);
FilingNotification() is the method which we want to call of Tikit.CarpeDiem.AddIn.Outlook this project and this.profileAttributes is the object array.
The flow is going perfectly to the Outlook project if the parameter type is either string or int but it is throwing error if the parameter is object type.
Implementation of FilingNotification() method in Tikit.CarpeDiem.AddIn.Outlook project.
public void FilingNotification(IProfileAttribute[] profileAttributesList)
{
if (profileAttributesList != null)
{
var x = profileAttributesList;
}
else
{
string y = "Try again";
}
}
Can someone help me in this one. I am stuck in this for 2 days. It will be really helpful. Thanks in advance.
Instead of passing a .Net object, make it implement a COM interface and pass it as an interface:
var obj = new MyBlah();
destAddIn.Object.FilingNotification(obj as IBlah);
...
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IBlah
{
void DoBlah();
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class MyBlah: StandardOleMarshalObject, IBlah
{
public void DoBlah()
{
//todo
};
}
You may pass scalar data types following that way. You need to implement an interface known on both sides if you want to pass objects between two entities. Read more about that in the Walkthrough: Call code in a VSTO Add-in from VBA article. For example:
[ComVisible(true)]
public interface IAddInUtilities
{
void ImportData();
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class AddInUtilities : IAddInUtilities
{
// This method tries to write a string to cell A1 in the active worksheet.
public void ImportData()
{
// implementation
}
}
Also you may consider using any standard mechanisms available for .net based applications such Remoting or WCF, see Basic WCF programming for more information.

Mutiny Uni Convert to Primitive Type

Up until now I have done very basic things with smallrye Mutiny in Quarkus. Basically, I have one or two very small web services which only interact with a web application. These services return a Uni<Response>.
Now I'm writing a logging service I want my others to pass information to. In this logging service, I need to return a value to calling services. The logging service will return this value as a Uni<Integer>. What I'm struggling with is how to extract the return value in the calling service as an int.
Here is the function in the logging service
#GET
#Path("/requestid")
#Produces(MediaType.TEXT_PLAIN)
public Uni<Integer> getMaxRequestId(){
return service.getMaxRequestId();
}
public Uni<Integer> getMaxRequestId() {
Integer result = Integer.valueOf(em.createQuery("select MAX(request_id) from service_requests").getFirstResult());
if(result == null) {
result = 0;
}
return Uni.createFrom().item(result += 1);
}
And here is the client side code in the calling service
#Path("/requests")
public class RequestIdResource {
#RestClient
RequestIdServices service;
#GET
#Path("/requestid")
#Produces(MediaType.TEXT_PLAIN)
public Uni<Integer> getMaxRequestId(){
return service.getMaxRequestId();
}
}
public void filter(ContainerRequestContext requestContext) throws IOException {
int requestid = client.getMaxRequestId();
rm.name = ConfigProvider.getConfig().getValue("quarkus.application.name", String.class);
rm.server = requestContext.getUriInfo().getBaseUri().getHost();
rm.text = requestContext.getUriInfo().getPath(true);
rm.requestid = requestid;
}
Basically everything I have tried creates another Uni. Maybe I am simply using the concept all wrong. But how do I get the Integer out of the Uni so I can get the intValue?
You need to invoke a terminal operation, or use the value and continue the chain.
If you want to invoke a terminal operator you can invoke the await operation to make your code blocking and wait for the response.
If you want to merge this reactive invocation with another that is present in your client code, you can join or combine your actual Mutiny stream with the on coming from the response by using the combine method.
If you just want to use the value and do not retrieve it, you can suscribe and get the result.
If you have a multi you can call directly the method toList
Assuming that you want to have some timeouts involved and you want to get the actual Integer, you can go with the await method and a timeout.

using signalR .net core client

I have set up a signalR website .net core. My function in my hub is:
public async Task Notify(int id) {
await Clients.All.InvokeAsync("Notified", id);
}
I have also tested this with the following js:
let connection = new signalR.HubConnection(myURL);
connection.on('Notified', data => {
console.log(4, data);
});
connection.start();
The js code seems to work fine and I see the log when I try connection.Invoke('Notify').
Now I have a console app that can needs to make the invoke. I am trying this in two ways and don't mind either solution:
1. A mvc controller within the signalR website that can take the id and invoke 'Notified'.
2. Use the client library Microsoft.AspNetCore.SignalR.Client in the console app.
The way 1 I have only done in classic asp.net like this:
GlobalHost.ConnectionManager.GetHubContext(hubName)
But couldn't find a way to do this in .net core.
Way 2 I have used the library and tried this so far:
var con = new HubConnectionBuilder();
con.WithUrl(myURL);
var connection = con.Build();
connection.InvokeAsync("Notify",args[0]).Wait();
This is the closest I have come to create a connection in the same way as the js code. However this code throws a null pointer when calling connection.InvokeAsync. The connection object is not null. It seems to be an internal object that is null. According to the stack trace the exception is thrown when a MoveNext() function is internally called.
Well looks like both are not currently possible. As of now I just used a forced way which is hopefully temporary.
I have created and used the following base class for hubs:
public abstract class MyHub : Hub
{
private static Dictionary<string, IHubClients> _clients = new Dictionary<string, IHubClients>();
public override Task OnConnectedAsync()
{
var c = base.OnConnectedAsync();
_clients.Remove(Name);
_clients.Add(Name, Clients);
return c;
}
public static IHubClients GetClients(string Name) {
return _clients.GetValueOrDefault(Name);
}
}
GlobalHost is gone. You need to inject IHubContext<THub> like in this sample.
This can be a bug in SignalR alpha1. Can you file an issue on https://github.com/aspnet/signalr and include a simplified repro?

CreateResponse method in asp.net Web API

calling this method:
public HttpResponseMessage PostProduct(Product item)
{
item = repository.Add(item);
var response = this.Request.CreateResponse<Product>CreateResponse(HttpStatusCode.Created, item);
string uri = Url.RouteUrl("DefaultApi", new { id = item.Id });
response.Headers.Location = new Uri(uri);
return response;
}
Is causing a compile-time error:
'System.Web.HttpRequestBase' does not contain a definition for 'CreateResponse' and the
best extension method overload 'System.Net.Http.HttpRequestMessageExtensions.CreateResponse<T>
(System.Net.Http.HttpRequestMessage, System.Net.HttpStatusCode, T)' has some invalid arguments.
What am I missing here?
The runtime type of item is probably not an instance of Product. You should be able to do this:
var response = Request.CreateResponse(HttpStatusCode.Created, item);
Even if item was an instance of Product, the generic <Product> argument is redundant and not necessary. If you used ReSharper, it would tell you that the "(Generic) Type argument specification is redundant".
Update
Does your class extend from Controller or ApiController? The error should be 'System.Net.Http.HttpRequestMessage' does not contain a definition for..., not 'System.Web.HttpRequestBase' does not contain a definition for....
WebApi controllers should extend from ApiController, not Controller. In an MVC controller, this.Request points to an instance of System.Web.HttpRequestBase. In a WebAPI controller, this.Request points to an instance of System.Net.Http.HttpRequestMessage.
CreateResponse is an extension method defined in System.Net.Http namespace.
Make sure to add a reference to System.Net.Http and System.Net.Http.Formatting in your project and add a correct using directive:
C#:
using System.Net.Http;
VB:
Import System.Net.Http

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

Resources